Re: [PATCH bpf-next 00/13] BPF interface for applying Landlock rulesets
From: Justin Suess
Date: Fri Aug 07 2026 - 18:08:16 EST
On Fri, Aug 07, 2026 at 04:36:20PM -0400, Paul Moore wrote:
> On Wed, Aug 5, 2026 at 8:32 PM Justin Suess <utilityemal77@xxxxxxxxx> wrote:
> > On Wed, Aug 05, 2026 at 06:51:56PM -0400, Paul Moore wrote:
> > > On Wed, Aug 5, 2026 at 5:37 PM Justin Suess <utilityemal77@xxxxxxxxx> wrote:
> > > > On Fri, Jul 31, 2026 at 04:30:39PM -0400, Paul Moore wrote:
> > > > > On Thu, Jul 30, 2026 at 10:21 PM Justin Suess <utilityemal77@xxxxxxxxx> wrote:
> > > > > [...]
> > > > > As you may, or may not have seen, there is currently an ongoing debate
> > > > > regarding the location of LSM kfuncs that will impact this patchset.
> > > > > Sadly, we don't appear to be approaching an agreement on this issue
> > > > > which introduces some additional risk to this patchset. We'll have to
> > > > > see how that ends up, but I just wanted you to be aware of the
> > > > > situation.
> > > >
> > > > Quick aside question: Would security/bpf/ be a better place for these
> > > > type of kfuncs?
> > > >
> > > > security/bpf/bpf_lsm_kfuncs.c could be for LSM framework kfuncs,
> > > > and each LSM could maintain their own security/bpf/<lsm>_kfuncs.c
> > > > for kfuncs dealing with lsm-specific types.
> > >
> > > This gets back to the other issue in the patchset that we've
> > > discussed: general LSM interfaces vs Landlock specific interfaces.
> > > There are plenty of reasons why we don't support the kernel calling
> > > directly into individual LSMs, and from my perspective this is another
> >
> > I'm 100% on board with the no calling directly into individual LSMs part.
> >
> > > instance of that. Here it just happens to be that the kernel caller
> > > was written in BPF and not C (or Rust for that matter).
> >
> > The intention is the opposite. The point of the separate directory is
> > that the kfuncs can never call into an individual LSM, they only get
> > the LSM framework API in <linux/security.h>.
> >
> > Every kfunc is a thin wrapper over the generic policy kptr hooks:
> >
> > bpf_landlock_get_ruleset_from_fd()
> > -> security_policy_kptr_from_fd(LSM_ID_LANDLOCK, ...)
> > -> Landlock's hook implementation
> >
> > So kfunc -> generic lsm hook -> individual LSM, same as any other
> > caller in the kernel.
>
> Not exactly. That "bpf_*landlock*_XXX" kfuncs are a move away from an
> LSM agnostic API and not something we currently do in the kernel.
> Some will, and have, argued that this is more akin to the Landlock
> syscalls, but I see (at least) two problems with that comparison: the
> kfuncs being presented aren't syscalls, they are cross-subsystem
> kernel function calls; the Landlock syscalls were created in a
I see the argument for normal in-tree kernel interfaces.
Unlike normal kernel interfaces, kfuncs:
1. Can exist without in-tree callers.
2. Are explicitly allowed to change or be removed at any time [1].
3. Can't break builds or other in-tree subsystems when they do.
This isn't hypothetical: the entire KF_KPTR_GET class
(bpf_task_kptr_get(), bpf_cgroup_kptr_get(), the flag itself) was
removed and replaced with a better abstraction within about a year
of introduction.
If Landlock (or any LSM) dies, there's zero uapi/in-tree cost to
removing the kfuncs, unlike syscalls which are burned into the uapi
forever, or ones with in-tree callers where we can break builds.
I argue that the transient, low-commitment nature of kfuncs mitigates
maintainability issues that arise from lsm-specific interfaces with
in-tree callers. (which we are both opposed to).
> different time, today these would need to be reframed as LSM
> syscalls*.
>
LSM-specific interfaces exist both in the LSM syscalls and in my design.
The only disagreement we have is the abstraction layer that the
"LSM-specific" part comes into effect.
1) In the lsm syscalls, it's inside of the lsm_ctx and the LSM_ID.
2) In my design for kfuncs, it's in the function signature and the kptr
types.
It's fine to have binary blobs like lsm_ctx where we always assume
userspace is untrusted. They can pass garbage through the syscall that
we have to handle, which is expected.
BPF and kfuncs are a ring-0, kernel internal interface, trusted after
verification. You can't cast pointers, or deserialize them from binary blobs
like lsm_ctx in BPF. The ownership and types of pointers must be verified at
load time. kfuncs, their annotations, (KF_ACQUIRE/KF_RELEASE) and kptrs are the
primary interface by which BPF checks correctness.
An LSM-agnostic bpf_lsm_policy_from_fd(lsm_id, fd) multiplexer would
lock every current and future LSM's policy object into a single set of
lifetime and context rules, and would move type errors from load time
to runtime.
This would prove to be less maintainable, because the main way of
ensuring correctness (kfunc signatures + kptr types) would be taken
away.
To avoid strawman style arguments, I ask what you would see as
an alternative interface?
Justin
[1] https://docs.kernel.org/bpf/kfuncs.html
> (* To be clear, we're not going to remove the Landlock syscalls for
> all the obvious reasons, but we're also not going to support APIs like
> that unless we have throughly exhausted all other options.)
>
> --
> paul-moore.com