Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Kernel Pwning with eBPF: A Love Story (graplsecurity.com)
136 points by arkadiyt on Aug 8, 2021 | hide | past | favorite | 18 comments



It's a truly excellent bug, a gnarly logic problem (it superficially looks like a 32/64 problem, but it's really just a logic bug that follows those same contours) that kind of betrays how brittle the eBPF verifier is. I look at this bug and what it shows about the assumptions baked into eBPF verification and conclude that it is not safe for unprivileged programs to use.

What's nice is, this bug says nothing about the verifier's ability to protect kernel stability from stupid, rather than malicious, code. Which, for 99% of eBPF applications, is all you care about! It's still a great way to let systems programmers extend the kernel.


> I look at this bug and what it shows about the assumptions baked into eBPF verification and conclude that it is not safe for unprivileged programs to use.

This is actually something we took away from this (I work at Grapl) as well.

We consider the Linux kernel to be unsuitable for isolation in some of our services, and it at least requires hardening (such as limiting unprivileged ebpf) in others.


> An LPE exploit writeup by Qualys published in July 2021 uses a memory corruption vulnerability to overwrite an eBPF program buffer, which contains the eBPF bytecode for a loaded program. Instead of fooling the verifier, the program is valid and passes verification. The buffer is overwritten after verification but before JIT compilation to achieve OOB read/write capabilities

Lovely.


How does eBPF compare to WebAsm? I'm a bit more familiar with the latter (thanks to some great articles) and I know that they use the same general approach of safety via linear-time verification and translation to machine code+buffer overflow checks, but I'm curious about the differences.


BPF has a much more limited execution model (in general, eBPF programs aren't even allowed to loop, though the verifier may allow some loops that it can prove are bounded), but freer access to the underlying machine (by design, your programs are usually handling live kernel memory directly).


In more general terms, the eBPF VM goes out of it's way to not be Turing complete in order to solve it's version of the halting problem. Instruction stream graphs must be able to be translated to a acyclic graph by the verifier.


Interesting, that makes me wonder if a similar restricted "acyclic control flow" mode could be built into WA; I bet that would be pretty useful.


It is extremely limiting and makes programming very difficult.


Yes, clearly. But it could be used in places where you want performance guarantees. Like, a client sends a custom sort function to a server to build responses, wide-open WA would not be appropriate for this but maybe a guaranteed acyclic control flow could work. Etc.


Sort is interesting because it's difficult to make a sort algorithm without unbounded loops. Although I guess a comparison function is probably easier, and leave the sort itself in the trusted computing base.


Basically only now the security community is starting to validate the security claims from WebAssembly, while founding there is room for improvement.

"Everything Old is New Again: Binary Security of WebAssembly"

https://www.usenix.org/conference/usenixsecurity20/presentat...

I expect more papers to start showing up.


That paper has been discussed on HN a few times ( https://news.ycombinator.com/item?id=26994741 ; https://news.ycombinator.com/item?id=24216764 ). The conclusion I came to in the comments on those threads is the authors of this paper discuss webasm program correctness ('insecure C is still insecure, whaddyaknow'), but they don't even attempt to break the host barrier (aka the whole point of the spec) so this doesn't really say much about the WebAssembly spec from a host security perspective.

I am also interested in new papers that directly discuss webasm host security.


> so this doesn't really say much about the WebAssembly spec from a host security perspective

To be clear, it does. WebAssembly does attempt to ensure that it compiles and executes programs in such a way that they are resistant to memory unsafety.

From webassembly.org, section "Memory Safety":

https://webassembly.org/docs/security/

Webassembly advertises itself as more or less solving the "insecure C is still insecure" problem. In reality it's missing a lot of memory safety mitigations you'd find in a C program compiled with a modern compiler.


From that section that you linked:

> Nevertheless, other classes of bugs are not obviated by the semantics of WebAssembly. Although attackers cannot perform direct code injection attacks, it is possible to hijack the control flow of a module using code reuse attacks against indirect calls. However, conventional return-oriented programming (ROP) attacks using short sequences of instructions (“gadgets”) are not possible in WebAssembly, because control-flow integrity ensures that call targets are valid functions declared at load time. ...

The paper is just a long-winded restatement of this paragraph.

And to be clear it doesn't. I said:

> ... Notably, they don't appear to even try to break the WA-host memory barrier ...

To which the paper's author themselves directly replied:

> ... I do agree with you, however, that our findings do not invalidate the overall design of WebAssembly. ... I also think "host security" (which we are not really looking into) is solid, with two qualifications: ...


It doesn't matter if the host remains untouched, when its behaviour depends on outputs from WASM functions.

So you can get upgraded security credentials, while the host remains 100% safe, as a possible attack scenario.

Security is only effective as the weakest link.


WA's goal posts are "protect the host from the program, not the program from itself"; the program is assumed to be malicious in this context. If you want to turn around and eval the output of a potentially malicious program in the context of the host, that's on you. You haven't 'broken' the WA memory barrier and blaming WA is an attempt to move the goal posts. WA adds a specific (hitherto unbroken) security layer; intentionally poking a hole in it and prancing about like you've found something is just crying wolf.

Edit to add that I agree that whole-program security is obviously still important when a WA-sandbox is part of the whole program, but WA is not advertised to be a solution to the halting problem, it's still just a tool. Be aware of the capabilities of the tools you use, wishing that your tools are made of magic does not make them more capable than what they were designed for.


Ergo, the same security capabilities of an OS process regarding the host OS.

I am fully aware of WebAssembly capabilities, its advocates should be as well, instead of shouting security left and right.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: