All of lore.kernel.org
 help / color / mirror / Atom feed
From: Justin Suess <utilityemal77@gmail.com>
To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	kpsingh@kernel.org, matt@bobrowski.net, paul@paul-moore.com,
	mic@digikod.net, viro@zeniv.linux.org.uk, brauner@kernel.org,
	kees@kernel.org
Cc: casey@schaufler-ca.com, gnoack@google.com, jack@suse.cz,
	song@kernel.org, yonghong.song@linux.dev, martin.lau@linux.dev,
	eddyz87@gmail.com, memxor@gmail.com, jolsa@kernel.org,
	m@maowtm.org, bpf@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Justin Suess <utilityemal77@gmail.com>
Subject: [PATCH bpf-next v3 06/15] lsm: Add the bpf_lsm_policy_acquire kfunc
Date: Wed,  9 Sep 2026 15:37:09 -0400	[thread overview]
Message-ID: <20260909193719.518517-7-utilityemal77@gmail.com> (raw)
In-Reply-To: <20260909193719.518517-1-utilityemal77@gmail.com>

Add the kfunc acquiring a reference on a policy object the program
does not own:

  bpf_lsm_policy_acquire(object)        KF_ACQUIRE|KF_RCU|KF_RET_NULL

bpf_kptr_xchg() is the only way to take an owned pointer out of a map
kptr field, and it empties the slot: concurrent executions of an
enforcement program would race for the one stored reference.  Modeled
after bpf_task_acquire(), this kfunc removes the exclusivity: a
program loads the kptr field with a plain read under
bpf_rcu_read_lock(), acquires its own reference through the
policy_object_get hook, and leaves the map slot untouched.  The
acquired reference survives bpf_rcu_read_unlock(), carrying over to a
sleepable bpf_lsm_policy_apply_bprm() call, and is released with
bpf_lsm_policy_release().

Adding struct lsm_policy_object to the verifier's rcu_protected_types
set makes the plain load yield an RCU-protected pointer instead of an
untrusted one.  This is where the policy object contract's RCU
requirements become load-bearing: the kfunc and the get hook examine
the object concurrently with a possible last put, which is safe
because implementations free only after an RCU grace period and
acquire with inc-not-zero semantics.  A failed get makes the kfunc
return NULL, per KF_RET_NULL.

The kfunc does not sleep and is meaningful wherever a policy object
pointer can be loaded, so the filter adds no per-kfunc rule.

Cc: Paul Moore <paul@paul-moore.com>
Cc: KP Singh <kpsingh@kernel.org>
Signed-off-by: Justin Suess <utilityemal77@gmail.com>
---

Notes:
    v2->v3:
        - No change.

 kernel/bpf/verifier.c     |  3 +++
 security/bpf_lsm_kfuncs.c | 34 +++++++++++++++++++++++++++++++++-
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9e79750e2480..d1af0090d38f 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -4660,6 +4660,9 @@ BTF_ID(struct, bpf_crypto_ctx)
 #ifdef CONFIG_INET
 BTF_ID(struct, bpf_ksock)
 #endif
+#ifdef CONFIG_BPF_LSM
+BTF_ID(struct, lsm_policy_object)
+#endif
 BTF_SET_END(rcu_protected_types)
 
 static bool rcu_protected_object(const struct btf *btf, u32 btf_id)
diff --git a/security/bpf_lsm_kfuncs.c b/security/bpf_lsm_kfuncs.c
index 988dcd6f4dd9..43a4bf57fd31 100644
--- a/security/bpf_lsm_kfuncs.c
+++ b/security/bpf_lsm_kfuncs.c
@@ -14,6 +14,36 @@
 
 __bpf_kfunc_start_defs();
 
+/**
+ * bpf_lsm_policy_acquire - Acquire a reference on a shared policy object
+ * @object: RCU-protected pointer to a policy object, e.g. loaded from
+ *          a map kptr field under bpf_rcu_read_lock()
+ *
+ * Acquire a reference of its own on a policy object the program does
+ * not own, so that any number of concurrent program executions can
+ * use the object shared through one map kptr field, without emptying
+ * it as bpf_kptr_xchg() would.  The returned reference stays valid
+ * after bpf_rcu_read_unlock() and must be released with
+ * bpf_lsm_policy_release().
+ *
+ * Return: A referenced policy object, or NULL if the object's
+ * reference count concurrently dropped to zero.
+ */
+__bpf_kfunc struct lsm_policy_object *
+bpf_lsm_policy_acquire(struct lsm_policy_object *object)
+{
+	struct lsm_static_call *scall;
+
+	lsm_for_each_hook(scall, policy_object_get) {
+		if (scall->hl->lsmid->id != object->lsmid)
+			continue;
+		if (scall->hl->hook.policy_object_get(object))
+			return NULL;
+		return object;
+	}
+	return NULL;
+}
+
 /**
  * bpf_lsm_policy_from_fd - Get an LSM policy object from a fd
  * @fd: file descriptor referring to a policy object, resolved in the
@@ -57,7 +87,8 @@ __bpf_kfunc struct lsm_policy_object *bpf_lsm_policy_from_fd(int fd, u32 flags)
  * bpf_lsm_policy_release - Release a policy object reference
  * @object: policy object to release
  *
- * Release a reference acquired with bpf_lsm_policy_from_fd().
+ * Release a reference acquired with bpf_lsm_policy_from_fd() or
+ * bpf_lsm_policy_acquire().
  */
 __bpf_kfunc void bpf_lsm_policy_release(struct lsm_policy_object *object)
 {
@@ -83,6 +114,7 @@ CFI_NOSEAL(bpf_lsm_policy_release_dtor);
 __bpf_kfunc_end_defs();
 
 BTF_KFUNCS_START(bpf_lsm_policy_kfunc_ids)
+BTF_ID_FLAGS(func, bpf_lsm_policy_acquire, KF_ACQUIRE | KF_RCU | KF_RET_NULL)
 BTF_ID_FLAGS(func, bpf_lsm_policy_from_fd,
 	     KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
 BTF_ID_FLAGS(func, bpf_lsm_policy_release, KF_RELEASE)
-- 
2.55.0


  parent reply	other threads:[~2026-09-09 19:38 UTC|newest]

Thread overview: 29+ 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-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 ` Justin Suess [this message]
2026-09-09 20:30   ` [PATCH bpf-next v3 06/15] lsm: Add the bpf_lsm_policy_acquire kfunc 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-09 19:55   ` sashiko-bot
2026-09-09 20:20     ` 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=20260909193719.518517-7-utilityemal77@gmail.com \
    --to=utilityemal77@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.