Thread (30 messages) flat view 30 messages, 6 authors, 2015-10-08

Re: [PATCH net-next 1/2] bpf: enable non-root eBPF programs

From: Ingo Molnar <mingo@kernel.org>
Date: 2015-10-06 08:20:55
Also in: lkml, netdev

* Daniel Borkmann [off-list ref] wrote:
On 10/06/2015 09:13 AM, Ingo Molnar wrote:
quoted
* Alexei Starovoitov [off-list ref] wrote:
quoted
On 10/5/15 3:14 PM, Daniel Borkmann wrote:
quoted
One scenario that comes to mind ... what happens when there are kernel
pointers stored in skb->cb[] (either from the current layer or an old
one from a different layer that the skb went through previously, but
which did not get overwritten)?

Socket filters could read a portion of skb->cb[] also when unprived and
leak that out through maps. I think the verifier doesn't catch that,
right?
grrr. indeed. previous layer before sk_filter() can leave junk in there.
Could this be solved by activating zeroing/sanitizing of this data if there's an
active BPF function around that can access that socket?
I think this check could only be done in sk_filter() for testing these
conditions (unprivileged user + access to cb area), so it would need to
happen from outside a native eBPF program. :/
Yes, the kernel (with code running outside of any eBPF program) would guarantee 
that those data fields are zeroed/sanitized, if there's an eBPF program that is 
attached to that socket.
[...] Also classic BPF would then need to test for it, since a socket filter 
doesn't really know whether native eBPF is loaded there or a classic-to-eBPF 
transformed one, and classic never makes use of this. Anyway, it could be done 
by adding a bit flag cb_access:1 to the bpf_prog, set it during eBPF 
verification phase, and test it inside sk_filter() if I see it correctly.
That could also be done in an unlikely() branch, to keep the cost to the non-eBPF 
case near zero.
The reason is that this sanitizing must only be done in the 'top-level' program 
that is run from sk_filter() _directly_, because a user at any time could decide 
to put an already loaded eBPF fd into a tail call map. And cb[] is then used to 
pass args/state around between two programs, thus it cannot be unconditionally 
cleared from within the program. The association to a socket filter 
(SO_ATTACH_BPF) happens at a later time after a native eBPF program has already 
been loaded via bpf(2).
So zeroing tends to be very cheap and it could also be beneficial to performance 
in terms of bringing the cacheline into the CPU cache. But I really don't know the 
filter code so I'm just handwaving.

Thanks,

	Ingo
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help