[PATCH bpf-next v4 3/8] bpf: lsm: provide attachment points for BPF LSM programs
Casey Schaufler
casey at schaufler-ca.com
Mon Feb 24 18:45:27 UTC 2020
On 2/24/2020 9:13 AM, KP Singh wrote:
> On 24-Feb 08:32, Casey Schaufler wrote:
>> On 2/23/2020 2:08 PM, Alexei Starovoitov wrote:
>>> On Fri, Feb 21, 2020 at 08:22:59PM -0800, Kees Cook wrote:
>>>> If I'm understanding this correctly, there are two issues:
>>>>
>>>> 1- BPF needs to be run last due to fexit trampolines (?)
>>> no.
>>> The placement of nop call can be anywhere.
>>> BPF trampoline is automagically converting nop call into a sequence
>>> of directly invoked BPF programs.
>>> No link list traversals and no indirect calls in run-time.
>> Then why the insistence that it be last?
> I think this came out of the discussion about not being able to
> override the other LSMs and introduce a new attack vector with some
> arguments discussed at:
>
> https://lore.kernel.org/bpf/20200109194302.GA85350@google.com/
>
> Let's say we have SELinux + BPF runnng on the system. BPF should still
> respect any decisions made by SELinux. This hasn't got anything to
> do with the usage of fexit trampolines.
The discussion sited is more about GPL than anything else.
The LSM rule is that any security module must be able to
accept the decisions of others. SELinux has to accept decisions
made ahead of it. It always has, as LSM checks occur after
"traditional" checks, which may fail. The only reason that you
need to be last in this implementation appears to be that you
refuse to use the general mechanisms. You can't blame SELinux
for that.
>>>> 2- BPF hooks don't know what may be attached at any given time, so
>>>> ALL LSM hooks need to be universally hooked. THIS turns out to create
>>>> a measurable performance problem in that the cost of the indirect call
>>>> on the (mostly/usually) empty BPF policy is too high.
>>> also no.
>> Um, then why not use the infrastructure as is?
> I think what Kees meant is that BPF allows hooking to all the LSM
> hooks and providing static LSM hook callbacks like traditional LSMs
> has a measurable performance overhead and this is indeed correct. This
> is why we want provide with the following characteristics:
I was responding to the "also no", which denies both what Kees said
and what you're saying here.
> - Without introducing a new attack surface, this was the reason for
> creating a mutable security_hook_heads in v1 which ran the hook
> after v1.
Yeah,
> This approach still had the issues of an indirect call and an
> extra check when not used. So this was not truly zero overhead even
> after special casing BPF.
The LSM mechanism is not zero overhead. It never has been. That's why
you can compile it out. You get added value at a price. You get the
ability to use SELinux and KRSI together at a price. If that's unacceptable
you can go the route of seccomp, which doesn't use LSM for many of the
same reasons you're on about.
When LSM was introduced it was expected to be used by the lunatic fringe
people with government mandated security requirements. Today it has a
much greater general application. That's why I'm in the process of
bringing it up to modern use case requirements. Performance is much
more important now than it was before the use of LSM became popular.
> - Having a truly zero performance overhead on the system. There are
> other tracing / attachment mechnaisms in the kernel which provide
> similar guarrantees (using static keys and direct calls) and it
> seems regressive for KRSI to not leverage these known patterns and
> sacrifice performance espeically in hotpaths. This provides users
> to use KRSI alongside other LSMs without paying extra cost for all
> the possible hooks.
This is in direct conflict with the aforementioned "also no".
>>>> So, trying to avoid the indirect calls is, as you say, an optimization,
>>>> but it might be a needed one due to the other limitations.
>>> I'm convinced that avoiding the cost of retpoline in critical path is a
>>> requirement for any new infrastructure in the kernel.
>> Sorry, I haven't gotten that memo.
>>
>>> Not only for security, but for any new infra.
>> The LSM infrastructure ain't new.
> But the ability to attach BPF programs to LSM hooks is new.
Stop right there. No, I mean it. Really, stop right there.
I don't give a flying fig (he said, using the polite expression
rather than the vulgar) about what you want to do within a
security module. Attach a BPF program, randomize arbitrary
memory locations, do traditional Bell & LaPadula, it's all the
same to the LSM infrastructure. If you want to do something
that has to work outside that, the way audit and seccomp do,
you need to take that out of the LSM infrastructure. If you
want the convenience of the LSM infrastructure you don't get
to muck it up.
> Also, we
> have not had the whole implementation of the LSM hook be mutable
> before and this is essentially what the KRSI provides.
It can do that wholly within KRSI hooks. You don't need to
put KRSI specific code into security.c.
>>> Networking stack converted all such places to conditional calls.
>>> In BPF land we converted indirect calls to direct jumps and direct calls.
>>> It took two years to do so. Adding new indirect calls is not an option.
>>> I'm eagerly waiting for Peter's static_call patches to land to convert
>>> a lot more indirect calls. May be existing LSMs will take advantage
>>> of static_call patches too, but static_call is not an option for BPF.
>>> That's why we introduced BPF trampoline in the last kernel release.
>> Sorry, but I don't see how BPF is so overwhelmingly special.
> My analogy here is that if every tracepoint in the kernel were of the
> type:
>
> if (trace_foo_enabled) // <-- Overhead here, solved with static key
> trace_foo(a); // <-- retpoline overhead, solved with fexit trampolines
>
> It would be very hard to justify enabling them on a production system,
> and the same can be said for BPF and KRSI.
The same can be and has been said about the LSM infrastructure.
If BPF and KRSI are that performance critical you shouldn't be
tying them to LSM, which is known to have overhead. If you can't
accept the LSM overhead, get out of the LSM. Or, help us fix the
LSM infrastructure to make its overhead closer to zero. Whether
you believe it or not, a lot of work has gone into keeping the LSM
overhead as small as possible while remaining sufficiently general
to perform its function.
No. If you're too special to play by LSM rules then you're special
enough to get into the kernel using more direct means.
More information about the Linux-security-module-archive
mailing list