From: Justin Suess <utilityemal77@gmail.com>
To: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
kpsingh@kernel.org, paul@paul-moore.com, mic@digikod.net,
viro@zeniv.linux.org.uk, brauner@kernel.org, kees@kernel.org
Cc: gnoack@google.com, jack@suse.cz, jmorris@namei.org,
serge@hallyn.com, song@kernel.org, yonghong.song@linux.dev,
martin.lau@linux.dev, m@maowtm.org, eddyz87@gmail.com,
john.fastabend@gmail.com, sdf@fomichev.me,
skhan@linuxfoundation.org, bpf@vger.kernel.org,
linux-security-module@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
Justin Suess <utilityemal77@gmail.com>
Subject: [RFC PATCH 19/20] bpf: Document BPF_MAP_TYPE_LANDLOCK_RULESET
Date: Tue, 7 Apr 2026 16:01:41 -0400 [thread overview]
Message-ID: <20260407200157.3874806-20-utilityemal77@gmail.com> (raw)
In-Reply-To: <20260407200157.3874806-1-utilityemal77@gmail.com>
Document the BPF_MAP_TYPE_LANDLOCK_RULESET map type and explain the
kfuncs it is associated with.
Signed-off-by: Justin Suess <utilityemal77@gmail.com>
---
Documentation/bpf/map_landlock_ruleset.rst | 181 +++++++++++++++++++++
1 file changed, 181 insertions(+)
create mode 100644 Documentation/bpf/map_landlock_ruleset.rst
diff --git a/Documentation/bpf/map_landlock_ruleset.rst b/Documentation/bpf/map_landlock_ruleset.rst
new file mode 100644
index 000000000000..90f3141a829b
--- /dev/null
+++ b/Documentation/bpf/map_landlock_ruleset.rst
@@ -0,0 +1,181 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+==============================
+BPF_MAP_TYPE_LANDLOCK_RULESET
+==============================
+
+``BPF_MAP_TYPE_LANDLOCK_RULESET`` is a specialized, array-backed map for
+holding references to Landlock rulesets that were created from userspace.
+It is meant to bridge BPF LSM policy selection with Landlock policy
+enforcement: userspace creates a normal Landlock ruleset, inserts its file
+descriptor into the map, and a BPF LSM program later looks up that ruleset and
+applies it with a Landlock kfunc during ``execve()`` preparation.
+
+BPF programs cannot create, inspect, or modify Landlock policy through this
+map. The looked-up object is exposed only as an opaque
+``struct bpf_landlock_ruleset`` reference.
+
+The map uses ``__u32`` keys as array indexes and stores one ruleset reference
+per slot. Like other array maps, its size is fixed at creation time and its
+elements are preallocated.
+
+Usage
+=====
+
+Kernel BPF
+----------
+
+.. note::
+ This map type is only supported for BPF LSM programs. In practice, it is
+ useful for sleepable BPF LSM programs attached to
+ ``bprm_creds_for_exec`` or ``bprm_creds_from_file``, because those are the
+ hooks where the associated Landlock kfuncs are available.
+
+bpf_map_lookup_elem()
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: c
+
+ void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)
+
+Lookup returns a trusted pointer to an opaque ``struct bpf_landlock_ruleset``.
+The verifier treats the result as a referenced BTF object, not as a pointer to
+the raw ``__u32`` map value declared in the map definition.
+
+Each successful lookup acquires a ruleset reference. The BPF program must
+release that reference with ``bpf_landlock_put_ruleset()`` on all paths after
+the lookup succeeds.
+
+The returned pointer is intended to be passed to
+``bpf_landlock_restrict_binprm()``. It is opaque and cannot be dereferenced
+or inspected from BPF.
+
+bpf_map_delete_elem()
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: c
+
+ long bpf_map_delete_elem(struct bpf_map *map, const void *key)
+
+Delete removes the ruleset reference stored in the selected slot and drops the
+map's own reference to that ruleset.
+
+Landlock kfuncs
+---------------
+
+The map contains objects designed to work with the following Landlock kfuncs:
+
+.. code-block:: c
+
+ void bpf_landlock_put_ruleset(const struct bpf_landlock_ruleset *ruleset)
+
+.. code-block:: c
+
+ int bpf_landlock_restrict_binprm(struct linux_binprm *bprm,
+ const struct bpf_landlock_ruleset *ruleset,
+ __u32 flags)
+
+``bpf_landlock_restrict_binprm()`` applies the looked-up ruleset to the new
+program credentials that are being prepared for ``execve()``. The ``flags``
+argument uses the same Landlock restriction flags as
+``landlock_restrict_self()``, including ``LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS``.
+When this flag is used from BPF, ``no_new_privs`` is staged through the exec
+context and committed only after exec reaches point-of-no-return. This avoids
+side effects on failed executions or ``AT_EXECVE_CHECK`` while ensuring that
+the resulting task cannot gain more privileges through later exec transitions.
+
+Userspace
+---------
+
+bpf_map_update_elem()
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: c
+
+ int bpf_map_update_elem(int fd, const void *key, const void *value, __u64 flags)
+
+Userspace populates the map by writing a Landlock ruleset file descriptor into
+the selected slot. The map uses FD-array update semantics:
+
+- ``key`` points to a ``__u32`` array index.
+- ``value`` points to a ``__u32`` containing the ruleset file descriptor.
+- ``flags`` must be ``BPF_ANY``.
+
+The supplied file descriptor must refer to a valid Landlock ruleset.
+
+Userspace lookup of map contents is not supported for this map type.
+
+Example
+=======
+
+Kernel BPF
+----------
+
+The following snippet shows a sleepable BPF LSM program that looks up a
+ruleset, applies it during exec credential preparation, and releases the
+lookup reference.
+
+.. code-block:: c
+
+ struct {
+ __uint(type, BPF_MAP_TYPE_LANDLOCK_RULESET);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u32);
+ } ruleset_map SEC(".maps");
+
+ SEC("lsm.s/bprm_creds_for_exec")
+ int BPF_PROG(apply_ruleset, struct linux_binprm *bprm)
+ {
+ const struct bpf_landlock_ruleset *ruleset;
+ __u32 key = 0;
+
+ ruleset = bpf_map_lookup_elem(&ruleset_map, &key);
+ if (!ruleset)
+ return 0;
+
+ bpf_landlock_restrict_binprm(
+ bprm, ruleset, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS);
+ bpf_landlock_put_ruleset(ruleset);
+ return 0;
+ }
+
+Userspace
+---------
+
+The following snippet shows how to insert a previously created Landlock
+ruleset into the map.
+
+.. code-block:: c
+
+ int populate_ruleset_map(int map_fd, int ruleset_fd)
+ {
+ __u32 key = 0;
+ __u32 value = ruleset_fd;
+
+ return bpf_map_update_elem(map_fd, &key, &value, BPF_ANY);
+ }
+
+Semantics
+=========
+
+- Map creation requires ``CONFIG_SECURITY_LANDLOCK``. Otherwise,
+ ``BPF_MAP_CREATE`` for this type fails with ``-EOPNOTSUPP``.
+- Map definitions use ``sizeof(__u32)`` for both keys and values because
+ userspace writes ruleset file descriptors into the map.
+- From BPF, only ``bpf_map_lookup_elem()`` and ``bpf_map_delete_elem()`` are
+ supported for this map type.
+- From userspace, insertion is done with ``bpf_map_update_elem()`` using a
+ Landlock ruleset FD.
+- The looked-up value is an opaque, trusted BTF object reference, so BPF must
+ treat it as a handle and release it with ``bpf_landlock_put_ruleset()``.
+- ``LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS`` on the BPF path pins the resulting
+ task with ``no_new_privs`` after exec is committed. When used from
+ ``bprm_creds_from_file``, this does not retroactively suppress privilege gain
+ for the current exec transition itself.
+- If Landlock support is disabled in the running kernel, programs using the
+ associated Landlock kfuncs may still load, but the kfunc call returns
+ ``-EOPNOTSUPP`` at runtime.
+
+See ``tools/testing/selftests/bpf/progs/landlock_kfuncs.c`` for a complete
+example.
--
2.53.0
next prev parent reply other threads:[~2026-04-07 20:02 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-07 20:01 [RFC PATCH 00/20] BPF interface for applying Landlock rulesets Justin Suess
2026-04-07 20:01 ` [RFC PATCH 01/20] landlock: Move operations from syscall into ruleset code Justin Suess
2026-04-07 20:01 ` [RFC PATCH 02/20] execve: Add set_nnp_on_point_of_no_return Justin Suess
2026-04-07 20:01 ` [RFC PATCH 03/20] landlock: Implement LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Justin Suess
2026-04-07 20:01 ` [RFC PATCH 04/20] selftests/landlock: Cover LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Justin Suess
2026-04-07 20:01 ` [RFC PATCH 05/20] landlock: Make ruleset deferred free RCU safe Justin Suess
2026-04-07 20:01 ` [RFC PATCH 06/20] bpf: lsm: Add Landlock kfuncs Justin Suess
2026-04-07 20:01 ` [RFC PATCH 07/20] bpf: arraymap: Implement Landlock ruleset map Justin Suess
2026-04-07 20:01 ` [RFC PATCH 08/20] bpf: Add Landlock ruleset map type Justin Suess
2026-04-07 20:01 ` [RFC PATCH 09/20] bpf: syscall: Handle Landlock ruleset maps Justin Suess
2026-04-07 20:01 ` [RFC PATCH 10/20] bpf: verifier: Add Landlock ruleset map support Justin Suess
2026-04-07 20:01 ` [RFC PATCH 11/20] selftests/bpf: Add Landlock kfunc declarations Justin Suess
2026-04-07 20:01 ` [RFC PATCH 12/20] selftests/landlock: Rename gettid wrapper for BPF reuse Justin Suess
2026-04-07 20:01 ` [RFC PATCH 13/20] selftests/bpf: Enable Landlock in selftests kernel Justin Suess
2026-04-07 20:01 ` [RFC PATCH 14/20] selftests/bpf: Add Landlock kfunc test program Justin Suess
2026-04-07 20:01 ` [RFC PATCH 15/20] selftests/bpf: Add Landlock kfunc test runner Justin Suess
2026-04-07 20:01 ` [RFC PATCH 16/20] landlock: Bump ABI version Justin Suess
2026-04-07 20:01 ` [RFC PATCH 17/20] tools: bpftool: Add documentation for landlock_ruleset Justin Suess
2026-04-07 20:01 ` [RFC PATCH 18/20] landlock: Document LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Justin Suess
2026-04-07 20:01 ` Justin Suess [this message]
2026-04-07 20:01 ` [RFC PATCH 20/20] MAINTAINERS: update entry for the Landlock subsystem Justin Suess
2026-04-08 4:40 ` [RFC PATCH 00/20] BPF interface for applying Landlock rulesets Ihor Solodrai
2026-04-08 11:41 ` Justin Suess
2026-04-08 14:00 ` Mickaël Salaün
2026-04-08 17:10 ` Justin Suess
2026-04-08 19:21 ` Mickaël Salaün
2026-04-10 12:43 ` 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=20260407200157.3874806-20-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=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=gnoack@google.com \
--cc=jack@suse.cz \
--cc=jmorris@namei.org \
--cc=john.fastabend@gmail.com \
--cc=kees@kernel.org \
--cc=kpsingh@kernel.org \
--cc=linux-fsdevel@vger.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=mic@digikod.net \
--cc=paul@paul-moore.com \
--cc=sdf@fomichev.me \
--cc=serge@hallyn.com \
--cc=skhan@linuxfoundation.org \
--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