[PATCH bpf-next 00/13] BPF interface for applying Landlock rulesets
Justin Suess
utilityemal77 at gmail.com
Fri Jul 31 21:15:20 UTC 2026
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 at gmail.com> wrote:
> >
> > Howdy,
> >
> > This series lets BPF programs apply an existing, userspace-created
> > Landlock ruleset to a program during exec. The goal is unchanged from
> > the RFC [1]: BPF does not create, inspect, or mutate Landlock policy,
> > it only decides whether a ruleset that was already created and
> > validated through Landlock's existing userspace API should be applied,
> > based on runtime exec context.
> >
> > Motivation
> > ---
> > Deploying Landlock today requires the sandboxed program's
> > cooperation. A process can only restrict itself, so applying a
> > policy system-wide means wrapping every launch path with a helper
> > that calls landlock_restrict_self(2) before exec, and anything
> > spawned outside those wrappers runs unconfined. Supervising exec
> > from userspace instead (ptrace, seccomp user notifications) is racy
> > and slow. Meanwhile, the tools that do enforce system-wide policy
> > with BPF LSM programs today (container security agents such as
> > KubeArmor and Tetragon) end up reimplementing path-based access
> > control in BPF, fraught with horrors of path reconstruction, bind
> > mounts, rename races, and worse, which is exactly the problem Landlock
> > already solves in the kernel, with maintained and versioned semantics.
> >
> > This series composes BPF and Landlock along their natural grain. The
> > intended deployment: a supervisor creates one ruleset per policy
> > class through the existing syscalls, a syscall BPF program parks
> > them in map kptr fields, and an LSM BPF program picks which (if
> > any) to apply to an execution based on its runtime context. The
> > policy semantics stay Landlock's; BPF contributes only the
> > programmable decision of when and to whom. Deciding inside the
> > exec path closes the race a userspace supervisor cannot: the
> > policy is in place before the first instruction of the new program
> > runs.
>
> Discretionary models are fun, and useful in certain situations, but
> they do have their limitations ;) To be fair, mandatory models have
> their limitations too :)
>
This series does kind of blur the lines between DAC and MAC
a little... interesting thought.
> I've only just barely skimmed some of the patches in this patchset,
> and I didn't have a chance to fully read your reply in the previous
> revision yet, so I wanted to get you a quick response here ... as
> incomplete as it may be.
>
> 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.
>
I'll hold off on further iterations until that's resolved.
Moving these kfuncs anywhere fortunately amounts to a trivial
cut/paste on end anyway.
> I need to look closer at both the LSM hooks and the BPF kfuncs before
> I can really definitively comment on them. It looks like there has
> been some progress towards an LSM agnostic interface, but I'm
> concerned more work might be needed. However, as I said earlier, a
> closer examination is needed and perhaps that will reveal something
> different.
>
> It's also worth mentioning that this functionality looks an awful lot
> like a call to lsm_set_self_attr(LSM_ATTR_EXEC,
> <lsm_ctx:LSM_ID_LANDLOCK>, size, 0) with a lsm_ctx::ctx set to a
> policy fd. Once again, perhaps a closer inspection will reveal that
> it is nothing like that, but it kept popping into my head while
> reading things so I wanted to mention it, especially as it a lot of
> the framework infrastructure already exists.
They were the direct inspiration for the hooks (and set/getprocattr).
Main difference being the object in the hook is a trusted kernel pointer
rather than a lsm_ctx blob or fd. We can't use an fd here since the
sandboxed task and supervisor don't share an fd table.
I'll wait for your full review, no rush.
Justin
>
> --
> paul-moore.com
More information about the Linux-security-module-archive
mailing list