[PATCH bpf-next 0/8] New BPF map and BTF security LSM hooks
Andrii Nakryiko
andrii.nakryiko at gmail.com
Mon Apr 17 23:31:24 UTC 2023
On Thu, Apr 13, 2023 at 9:54 AM Casey Schaufler <casey at schaufler-ca.com> wrote:
>
> On 4/12/2023 10:16 PM, Andrii Nakryiko wrote:
> > On Wed, Apr 12, 2023 at 7:56 PM Paul Moore <paul at paul-moore.com> wrote:
> >> On Wed, Apr 12, 2023 at 9:43 PM Andrii Nakryiko
> >> <andrii.nakryiko at gmail.com> wrote:
> >>> On Wed, Apr 12, 2023 at 12:07 PM Paul Moore <paul at paul-moore.com> wrote:
> >>>> On Wed, Apr 12, 2023 at 2:28 PM Kees Cook <keescook at chromium.org> wrote:
> >>>>> On Wed, Apr 12, 2023 at 02:06:23PM -0400, Paul Moore wrote:
> >>>>>> On Wed, Apr 12, 2023 at 1:47 PM Kees Cook <keescook at chromium.org> wrote:
> >>>>>>> On Wed, Apr 12, 2023 at 12:49:06PM -0400, Paul Moore wrote:
> >>>>>>>> On Wed, Apr 12, 2023 at 12:33 AM Andrii Nakryiko <andrii at kernel.org> wrote:
> >> ...
> >>
> >>>>>>> For example, in many places we have things like:
> >>>>>>>
> >>>>>>> if (!some_check(...) && !capable(...))
> >>>>>>> return -EPERM;
> >>>>>>>
> >>>>>>> I would expect this is a similar logic. An operation can succeed if the
> >>>>>>> access control requirement is met. The mismatch we have through-out the
> >>>>>>> kernel is that capability checks aren't strictly done by LSM hooks. And
> >>>>>>> this series conceptually, I think, doesn't violate that -- it's changing
> >>>>>>> the logic of the capability checks, not the LSM (i.e. there no LSM hooks
> >>>>>>> yet here).
> >>>>>> Patch 04/08 creates a new LSM hook, security_bpf_map_create(), which
> >>>>>> when it returns a positive value "bypasses kernel checks". The patch
> >>>>>> isn't based on either Linus' tree or the LSM tree, I'm guessing it is
> >>>>>> based on a eBPF tree, so I can't say with 100% certainty that it is
> >>>>>> bypassing a capability check, but the description claims that to be
> >>>>>> the case.
> >>>>>>
> >>>>>> Regardless of how you want to spin this, I'm not supportive of a LSM
> >>>>>> hook which allows a LSM to bypass a capability check. A LSM hook can
> >>>>>> be used to provide additional access control restrictions beyond a
> >>>>>> capability check, but a LSM hook should never be allowed to overrule
> >>>>>> an access denial due to a capability check.
> >>>>>>
> >>>>>>> The reason CAP_BPF was created was because there was nothing else that
> >>>>>>> would be fine-grained enough at the time.
> >>>>>> The LSM layer predates CAP_BPF, and one could make a very solid
> >>>>>> argument that one of the reasons LSMs exist is to provide
> >>>>>> supplementary controls due to capability-based access controls being a
> >>>>>> poor fit for many modern use cases.
> >>>>> I generally agree with what you say, but we DO have this code pattern:
> >>>>>
> >>>>> if (!some_check(...) && !capable(...))
> >>>>> return -EPERM;
> >>>> I think we need to make this more concrete; we don't have a pattern in
> >>>> the upstream kernel where 'some_check(...)' is a LSM hook, right?
> >>>> Simply because there is another kernel access control mechanism which
> >>>> allows a capability check to be skipped doesn't mean I want to allow a
> >>>> LSM hook to be used to skip a capability check.
> >>> This work is an attempt to tighten the security of production systems
> >>> by allowing to drop too coarse-grained and permissive capabilities
> >>> (like CAP_BPF, CAP_PERFMON, CAP_NET_ADMIN, which inevitable allow more
> >>> than production use cases are meant to be able to do) and then grant
> >>> specific BPF operations on specific BPF programs/maps based on custom
> >>> LSM security policy, which validates application trustworthiness using
> >>> custom production-specific logic.
> >> There are ways to leverage the LSMs to apply finer grained access
> >> control on top of the relatively coarse capabilities that do not
> >> require circumventing those capability controls. One grants the
> >> capabilities, just as one would do today, and then leverages the
> >> security functionality of a LSM to further restrict specific users,
> >> applications, etc. with a level of granularity beyond that offered by
> >> the capability controls.
> > Please help me understand something. What you and Casey are proposing,
> > when taken to the logical extreme, is to grant to all processes root
> > permissions and then use LSM to restrict specific actions, do I
> > understand correctly?
>
> No. You grant a process the capabilities it needs (CAP_BPF, CAP_WHATEVER)
> and only those capabilities. If you want additional restrictions you include
> an LSM that implements those restrictions. If you want finer control over
> the operations controlled by CAP_BPF you include an LSM that implements
> those controls.
>
See previous replies. We can't grant CAP_BPF, even if we wanted to, if
the process is in a user namespace.
> > This strikes me as a less secure and more
> > error-prone way of doing things. If there is some problem with
> > installing LSM policy,
>
> LSMs are not required to have loadable or dynamic policies. That's
> up to the developer.
>
Sure, but having a more dynamic policy is a very attractive feature
and one of the reasons for people to use BPF LSM. So it might not be
required, but it's something that people are using in practice, so if
we can make all this less error-prone, that would be better for
everyone.
> > it could go unnoticed for a really long time,
> > while the system would be way more vulnerable.
>
> There is no way Paul or I are going to solve the mis-configured system
> problem.
>
Please see my example about (hypothetical) 21st added hook that is
very easy to miss, because the kernel is big and there are tons of
people doing development, and so it's no wonder that users might miss
a new hook they are supposed to restrict.
But again, even with all that said, granting CAP_BPF is impossible for
user namespaced applications.
> > Why do you prefer such
> > an approach instead of going with no extra permissions by default, but
> > allowing custom LSM policy to grant few exceptions for known and
> > trusted use cases?
>
> Because that's not how capabilities work. Capabilities are independent
> of other controls. If you want to propose a change to how capabilities
> work, you need to propose that to the capability maintainer.
>
> Because that's not how LSMs work. LSMs implement additional restrictions
> to the existing policy. The restrictive vs. authoritative debate was closed
> long ago. It's a fundamental property of how LSMs work.
There doesn't seem to be anything fundamentally and technically
preventing LSM hooks to say "yep, looks good, no need to fallback to
CAP_BPF checks due to lack of other signal". [0] also outright said
that authoritative hooks can be the next step, but didn't reject it
outright.
[0] https://lwn.net/2001/1108/a/no-auth-hooks.php3
>
> > By the way, even the above proposal of yours doesn't work for
> > production use cases when user namespaces are involved, as far as I
> > understand. We cannot grant CAP_BPF+CAP_PERFMON+CAP_NET_ADMIN for
> > containers running inside user namespaces, as CAP_BPF in non-init
> > namespace is not enough for bpf() syscall to allow loading BPF maps or
> > BPF program (bpf() doesn't do ns_capable(), it's only using
> > capable()). What solution would you suggest for such production
> > setups?
>
> If user namespaces don't work the way you'd like, you should take that
> up with the namespace maintainers. Or, since this appears to be an issue
> with BPF not being namespace aware, fix BPF's use of capable() and ns_capable().
Can't be fixed on the BPF side, unfortunately. Don't know enough about
namespaces to tell if it's a bug or feature that root CAP_BPF can't be
checked from inside userns. So yep, I should perhaps ask.
>
> > Also, in previous email you said:
> >
> >> Simply because there is another kernel access control mechanism which
> >> allows a capability check to be skipped doesn't mean I want to allow a
> >> LSM hook to be used to skip a capability check.
> > I understand your stated position, but can you please help me
> > understand the reasoning behind it? What would be wrong with some LSM
> > hooks granting effective capabilities?
>
> You keep asking the question and ignoring the answer. See above.
>
> > How would that change anything
> > about LSM design? As far as I can see, I'm not doing anything crazy
> > with my LSM hook implementation.
>
> You keep asking the question and ignoring the answer. See above.
>
>
> > It's reusing the standard
> > call_int_hook() mechanism very straightforwardly with a default result
> > of 0. And then just interprets 0, <0, and >0 results accordingly. Is
> > that abusing the LSM mechanism itself somehow?
> >
> > Does the above also mean that you'd be fine if we just don't plug into
> > the LSM subsystem at all and instead come up with some ad-hoc solution
> > to allow effectively the same policies?
>
> No, because you would be breaking the capability system in that case.
>
> There is an example of a feature that does just what you're suggesting.
> POSIX ACLs aren't an LSM because they don't just add restrictions, they
> change the semantics of the file mode bits. Look at that implementation
> before you seriously consider going that route.
Are you referring to posix_acl_permission() and fs/posix_acl.c? I'll
take a look, not familiar. Thanks for the suggestion!
I'd still prefer to avoid building a new access control system just
for BPF, of course. But let me take a look at the code and see what
you are referring to.
>
> > This sounds detrimental both
> > to LSM and BPF subsystems, so I hope we can talk this through before
> > finalizing decisions.
> >
> > Lastly, you mentioned before:
> >
> >>>> I think we need to make this more concrete; we don't have a pattern in
> >>>> the upstream kernel where 'some_check(...)' is a LSM hook, right?
> > Unfortunately I don't have enough familiarity with all LSM hooks, so I
> > can't confirm or disprove the above statement. But earlier someone
> > brought to my attention the case of security_vm_enough_memory_mm(),
> > which seems to be granting effectively CAP_SYS_ADMIN for the purposes
> > of memory accounting. Am I missing something subtle there or does it
> > grant effective caps indeed?
> >
> >
> >
> >
> >> --
> >> paul-moore.com
More information about the Linux-security-module-archive
mailing list