Hacker News new | ask | show | jobs
by Ericson2314 2052 days ago
The future ought to be capabilities. All this policy scripting stuff is just drudgery make-work that gets us nowhere.
2 comments

Can you provide more context on why you feel that's true (or even possible)?

For the last few years, I managed the Container Runtime group at Facebook. My experience has been:

1. `if (has_capability(..., X)) { ... }` gets put into code pretty haphazardly in a way that's not necessarily super well structured. Once it's there, it's ABI, and you're screwed if you want to iterate on it. That's why cap_sys_admin is /almost/ root.

2. If you wanted to do the right thing from the jump (e.g. for bpf itself), you'd have to add a new capability. This is a heavy lift for something that might not actually get any traction. It requires changing a bunch of common tools, and you likely end up breaking a bunch of applications.

3. Debugging capability failures is a pain in the ass. We ended up building and deploying capability tracing infrastructure just to figure out what people are actually using.

4. For gradual roll outs of enforcement/changes, you need the flexibility to warn first, enforce second. We did large scale monitoring of all such changes to make sure we didn't break the workloads.

5. Even if you nail all of the above, the ability to make finer-than-capability-grained decisions (i.e. binding to port 20 or 80 is okay but not port 22) is really valuable.

I'm all for kernel abstractions that just work and solve all problems for all people, but I think the overwhelming trend has been towards kernel interfaces that provide a lot of flexibility and then more opinionated libraries/tools that kind of let us have our cake and eat it to (io_uring => liburing, bpf => libbpf, btrfs => btrfstools).

Are we talking about POSIX capabilities or object capabilities?
What POSIX and the linux kernel calls "capabilities" unfortunately result in quite a bit of confusion, which I believe is the cause of your post. POSIX capabilities bear little resemblance to actual capability based security (where a capability is a send/recv-able token that references an object and a set of rights for interacting with that object).
I was not aware of object capabilities -- TIL.

That said, looking at the (apparently) leading implementation, capsicum

> Capsicum also introduces capability mode, which disables (with ECAPMODE) all syscalls that access any kind of global namespace; this is mostly (but not completely) implemented in userspace as a seccomp-bpf filter.

So I do feel that bpf ultimately enables building the kinds of abstractions that people want.

BPF wasn't originally conceived of as a reference monitor or ACL system; in fact, originally, it was believed that operating systems would use BPF-style packet filters to do pretty much all their demuxing.
That's all true. I'm worried about what people will do with this stuff in practice (more rope to hang themselves) not eBPF fundamentally is.
Are you referring to STREAMS? https://en.m.wikipedia.org/wiki/STREAMS
Not really, though BPF was sort of a design alternative to Solaris/SVR4 STREAMS. If you follow the cites, BPF is really an evolution of CSPF, the CMU-Stanford Packet Filter. (As I understand it! McCanne could show up at any moment and correct me.)
AFAIK BPF wasn’t conceived as anything security-related, it was just an optimization.
From the article:

Buggy kernel code will crash your machine. The kernel is not protected from a buggy kernel module. I think people assumed that this is just how things are; that's the price to do kernel programming. eBPF changed this dogma. It brought safety to kernel programming.

"It brought safety to kernel programming" , if you use eBPF and don't expose bugs in the parser, or checking or validation systems. (These have already happened).

Extending a bit on what Alexei is talking about (Full eBPF summit talk: https://youtu.be/jw8tEPP6jwQ?t=639)

Many people seem to make an assumption that kernel code is perfect and that when code is merged into the Linux kernel, it is automatically secure. That is definitely not the case. Kernel developers make mistakes as well and they have devastating consequences.

Right now, the security of the Linux kernel code depends on a combination of code review, fuzzing, controlling the pace of code changes, and running LTS releases to increase the chance others found the bugs already.

eBPF further increases the security model of kernel development by adding a verification step to the model. It means that there is an additional layer of protection in case of code imperfections.

The focus on eBPF safety is awesome. eBPF is software, software will have bugs, eBPF is no exception. The best way to improve the security of software is to question it. Given the wide spread use of eBPF in highly critical and exposed scenarios, the pressure on making it as bug-free as possible is very high so it's probably fair to assume that the scrutiny put in place, will lead to a high quality implementation of the verifier.

BPF has always been statically verified, back to 1991 or whenever.

If anything, eBPF is less sound than classic BPF, because the verifier is dramatically more complicated, as is the execution environment.

He means security in the sense of adding new security controls to Linux. Yes, the core idea of BPF (e- or otherwise) is that the code can be verified not to harm the kernel.
It was, but it was an optimization over earlier VM-based packet filters, which were definitely not optimizations; they were pursued as elegant system design, not high-performance networking.