mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Justin Suess <utilityemal77@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: "Paul Moore" <paul@paul-moore.com>,
	"Alexei Starovoitov" <ast@kernel.org>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"Andrii Nakryiko" <andrii@kernel.org>,
	"KP Singh" <kpsingh@kernel.org>,
	"Matt Bobrowski" <matt@bobrowski.net>,
	"Mickaël Salaün" <mic@digikod.net>,
	"Alexander Viro" <viro@zeniv.linux.org.uk>,
	"Christian Brauner" <brauner@kernel.org>,
	"Kees Cook" <kees@kernel.org>,
	"Casey Schaufler" <casey@schaufler-ca.com>,
	"Günther Noack" <gnoack@google.com>, "Jan Kara" <jack@suse.cz>,
	"Song Liu" <song@kernel.org>,
	"Yonghong Song" <yonghong.song@linux.dev>,
	"Martin KaFai Lau" <martin.lau@linux.dev>,
	Eduard <eddyz87@gmail.com>,
	"Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
	"Jiri Olsa" <jolsa@kernel.org>, "Tingmao Wang" <m@maowtm.org>,
	bpf <bpf@vger.kernel.org>,
	"LSM List" <linux-security-module@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH bpf-next v3 04/15] lsm: Add the bpf_lsm_policy_release kfunc and policy object destructor
Date: Mon, 14 Sep 2026 21:13:29 -0400	[thread overview]
Message-ID: <aqiJrkNyGM6hYu9A@zenbox> (raw)
In-Reply-To: <CAADnVQ+v9_a8Q_YOvS9fmXG+-Ga0ADKrjGDDUCiFaipo2vUDmg@mail.gmail.com>

On Sun, Sep 13, 2026 at 07:31:44PM -0700, Alexei Starovoitov wrote:
> On Sun, Sep 13, 2026 at 5:20 PM Justin Suess <utilityemal77@gmail.com> wrote:
> >
> > Sure, in some perfect world in the future where every verifier
> > challenge is solved and BPF has feature parity with in-tree c on
> > a 1:1 basis, you could implement something like SELinux, or Landlock
> > in pure eBPF.
> 
> Try.. give it a shot? What is missing in the verifier?
>
Howdy Alexei,

I'll stick to Landlock as the concrete case, as it's what I'm most familiar with.

From security/landlock/fs.c: hook_sb_delete() holds the superblock's
s_inode_list_lock, takes a nested lock of the inode's i_lock inside it, takes the RCU
read lock inside that to dereference the per-inode Landlock object, and
then the object's own lock, which is four levels of lock nesting, and even with
all of that it still has to handle a race by re-checking
inode_state_read() for specific flags to maintain VFS invariants.  BPF
cannot take any of these kernel locks, and the current BPF locking model
deliberately excludes any nesting (bpf_spin_lock) or resolves contention by
bailing out (trylock style); the opposite of what maintaining VFS invariants
requires.  To do effective inode-based access control without TOCTOU or
bailing out of a long path walk, you'd need to solve nested locking with colored
locks: inode spinlocks, superblock locks, unix_state_lock, etc, and
solve nested locking along the way.

You'd also need to convince the verifier that an upward VFS walk
(dget_parent) is bounded, and find a way to cross mount boundaries;
getting from a vfsmount to its struct mount is container_of(). (Pointer
is arithmetic rejected even on trusted pointers).  Pointers walked
via d_parent become untrusted, so they can't be passed to any kfunc
(bpf_path_d_path(), bpf_inode_storage_get()): inode local storage,
which is otherwise an idiomatic inode security blob replacement, is only
usable for the object at hand, but not its ancestors required for VFS
walk.

Making it string/pathname based instead doesn't help either: any string-based method
fails because the same file can be linked from multiple places, the same
path string means different things in different mount namespaces, and
strings aren't TOCTOU safe (the path can change during the walk).  And you can't
currently take references or locks on inodes, dentries or mounts from
BPF, so any hierarchy walk is a lockless, unreferenced snapshot racing
against rename, whereas Landlock's walk holds path_get()/dget_parent() 
holds the references at every step.

You'd also need credential-attached storage. BPF task storage has a
different lifecycle, and is no substitute. It does not define how policy
is shared by threads using the same credentials, copied or replaced
during credential transitions, propogated through file->f_cred,
or synchronized across a thread group. Recreating those semantics in
BPF would require explicit BPF APIs for credential storage to be
consistent.

> > Why force every eBPF program that needs to make security
> > decisions to reeinvent the wheel?
> 
> What specific reinvention are you talking about?
>
Path based access control, done to the same correctness 
level as in Landlock, (TOCTOU free).
> > BPF already calls into LSM through security hooks. This is no
> > different than bpf_map_create hooks.
> 
> what? It doesn't. bpf progs avoid lsm hooks as a plague.
> Not a single kfuncs calls into lsm directly.
> It may call into security_*() by accident because
> it calls some kernel mechanisms.
>

I was referring to the security_bpf_map_create()
call in kernel/bpf/syscall.c, where BPF calls into LSM via an LSM hook
just to show that kernel/bpf already calls security hooks directly
(and now that I look, there are other security_bpf_*() calls in
kernel/bpf/ too).  Those hooks exist so LSM can mediate what BPF is
allowed to do.

(These in this patch hooks are contrary; they are giving BPF control over
LSM policy. And, indeed, no hook is called from kfuncs, as you stated).

The proposal is intended to add a narrow generic bridge, not to expose
Landlock-specific kfuncs or make BPF depend on Landlock internals:


  /* setup (BPF_PROG_TYPE_SYSCALL context) */
  obj = bpf_lsm_policy_from_fd(fd, 0);
  old = bpf_kptr_xchg(&map_val->policy, obj);
  
  /* enforcement (sleepable BPF_PROG_TYPE_LSM on a bprm hook) */
  bpf_rcu_read_lock();
  obj = bpf_lsm_policy_acquire(map_val->policy);
  bpf_rcu_read_unlock();
  if (obj) {
         bpf_lsm_policy_apply_bprm(obj, bprm, 0);
         bpf_lsm_policy_release(obj);
  }

BPF never sees a Landlock kptr or any Landlock-specific type.  It holds
an opaque policy reference and invokes a generic operation. The LSM
can evolve its internal representation and its hook-specific
implementation without exporting breakage into the BPF ABI: the signature
of the data the LSM sees can change independently of the kfunc (that's
what the body-less hooks in patches 1-2 are for), avoiding breakage and
easing refactoring.

> > Nothing about the way BPF works changes with this patchset.
> > There's no verifier internal changes.
> 
> If the verifier is in the way of what you want to accomplish
> then please improve it.

There are also verifier improvements I'd like to make, (I can also work
on these if you desire prerequisites or seperate fixes).

For instance, my silly bpf_lsm_policy_apply_bprm allowlist exists
because there's no way to distinguish a linux_binprm seen from a
tracepoint from one seen in an LSM hook (both are KF_TRUSTED) and
it matters because there are tracepoints where it's no longer safe to
modify the linux_binprm.

I'd rather have the verifier do that legwork through its type system
than through BTF_ID sets, and I think you feel the same way.

....

The goal here is to keep LSM firmly *out of the way* of BPF business
and let each subsystem focus on its core technology. It's my belief
BPF and LSM  subsystems can benefit from something like this given a chance,
with a well-defined structured interface / guardrails.

All in good faith, 
Justin

  reply	other threads:[~2026-09-15  1:13 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-09 19:37 [PATCH bpf-next v3 00/15] BPF interface for applying Landlock rulesets Justin Suess
2026-09-09 19:37 ` [PATCH bpf-next v3 01/15] lsm: Add the LSM policy object lifetime hooks Justin Suess
2026-09-09 19:37 ` [PATCH bpf-next v3 02/15] lsm: Add the bprm_apply_policy_object LSM hook Justin Suess
2026-09-09 19:37 ` [PATCH bpf-next v3 03/15] lsm: Move the lsm_for_each_hook() macro to security/lsm.h Justin Suess
2026-09-09 19:37 ` [PATCH bpf-next v3 04/15] lsm: Add the bpf_lsm_policy_release kfunc and policy object destructor Justin Suess
2026-09-09 20:29   ` bot+bpf-ci
2026-09-09 21:34   ` Paul Moore
2026-09-09 22:20     ` Justin Suess
2026-09-09 23:08       ` Paul Moore
2026-09-12  3:37         ` Alexei Starovoitov
2026-09-12  5:26           ` Justin Suess
2026-09-12 19:33             ` Alexei Starovoitov
2026-09-13 19:41               ` Paul Moore
2026-09-13 23:24                 ` LSM boundaries. Was: " Alexei Starovoitov
2026-09-14  0:10                   ` Paul Moore
2026-09-14  2:24                     ` Alexei Starovoitov
2026-09-14 21:18                       ` Dr. Greg
2026-09-14  0:20               ` Justin Suess
2026-09-14  2:31                 ` Alexei Starovoitov
2026-09-15  1:13                   ` Justin Suess [this message]
2026-09-15  9:25               ` Mickaël Salaün
2026-09-09 19:37 ` [PATCH bpf-next v3 05/15] lsm: Add the bpf_lsm_policy_from_fd kfunc Justin Suess
2026-09-09 20:46   ` bot+bpf-ci
2026-09-09 19:37 ` [PATCH bpf-next v3 06/15] lsm: Add the bpf_lsm_policy_acquire kfunc Justin Suess
2026-09-09 20:30   ` bot+bpf-ci
2026-09-09 19:37 ` [PATCH bpf-next v3 07/15] lsm: Add the bpf_lsm_policy_apply_bprm kfunc Justin Suess
2026-09-12  3:38   ` Alexei Starovoitov
2026-09-12  5:39     ` Justin Suess
2026-09-09 19:37 ` [PATCH bpf-next v3 08/15] lsm: Document the LSM policy object interface Justin Suess
2026-09-09 19:37 ` [PATCH bpf-next v3 09/15] selftests/bpf: Add tests for the LSM policy object kfuncs Justin Suess
2026-09-09 20:30   ` bot+bpf-ci
2026-09-09 19:37 ` [PATCH bpf-next v3 10/15] landlock: Expose the ruleset fd lookup to the rest of Landlock Justin Suess
2026-09-09 19:37 ` [PATCH bpf-next v3 11/15] landlock: Factor the credential restriction out of landlock_restrict_self() Justin Suess
2026-09-09 20:29   ` bot+bpf-ci
2026-09-09 19:37 ` [PATCH bpf-next v3 12/15] landlock: Free rulesets after an RCU grace period Justin Suess
2026-09-09 20:46   ` bot+bpf-ci
2026-09-09 19:37 ` [PATCH bpf-next v3 13/15] landlock: Implement the LSM policy object hooks Justin Suess
2026-09-09 20:46   ` bot+bpf-ci
2026-09-09 19:37 ` [PATCH bpf-next v3 14/15] selftests/bpf: Test the LSM policy object kfuncs with Landlock Justin Suess
2026-09-09 20:46   ` bot+bpf-ci
2026-09-09 19:37 ` [PATCH bpf-next v3 15/15] landlock: Document the BPF policy interface Justin Suess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aqiJrkNyGM6hYu9A@zenbox \
    --to=utilityemal77@gmail.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brauner@kernel.org \
    --cc=casey@schaufler-ca.com \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=gnoack@google.com \
    --cc=jack@suse.cz \
    --cc=jolsa@kernel.org \
    --cc=kees@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=m@maowtm.org \
    --cc=martin.lau@linux.dev \
    --cc=matt@bobrowski.net \
    --cc=memxor@gmail.com \
    --cc=mic@digikod.net \
    --cc=paul@paul-moore.com \
    --cc=song@kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®