From: Christian Brauner <brauner@kernel.org>
To: linux-fsdevel@vger.kernel.org, bpf@vger.kernel.org
Cc: linux-security-module@vger.kernel.org,
"Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Paul Moore" <paul@paul-moore.com>,
"Mickaël Salaün" <mic@digikod.net>,
"Günther Noack" <gnoack@google.com>,
netdev@vger.kernel.org,
"Linus Torvalds" <torvalds@linux-foundation.org>,
"Christian Brauner (Amutable)" <brauner@kernel.org>,
stable@kernel.org
Subject: [PATCH v2 0/7] ns: fixes for the namespace LSM hooks
Date: Thu, 29 Oct 2026 17:40:55 +0100 [thread overview]
Message-ID: <20261029-work-security-namespace_free-v2-0-65591dbba7b3@kernel.org> (raw)
I tried to switch systemd-nsresourced over to the namespace_free LSM
hook that went in this cycle. I explicitly developed it to work nicely
with that. But the version that is merged is broken for that case.
The namespace_free hook is never called. security_namespace_free() bails
if ns->ns_security is NULL and that's only allocated if an LSM requests
a namespace blob. Nobody does. Landlock doesn't care as it only uses
namespace_init and namespace_install but a bpf program attached to
namespace_free never runs. And it can't work around that either. We
could make the bpf LSM request a blob but that would just be a way to
make the hook fire. So call it unconditionally like we do for
superblocks, files and bpf maps.
The bpf LSM also marks the arguments of namespace_init and
namespace_free as trusted. Curiously that patch was also dropped.
namespace_init is called before the namespace is set up and if anything
fails afterwards the namespace is freed without looking at its reference
count. namespace_free is called on the way out. There's no kfunc that
takes a namespace yet but once there is one a program could take a
reference to a namespace that's about to be freed. So add both hooks to
untrusted_lsm_hooks.
The namespace_init hook also always sees a namespace id of zero because
the id is only allocated after the hook has run. The id is the only
identifier of a namespace that is never recycled. So it's what a bpf LSM
wants to use to track a namespace from namespace_init until
namespace_free.
The inode number is recycled way too quickly for that. So allocate the
id in __ns_common_init() before the hook is called. Then ns_tree_add()
doesn't need to allocate ids anymore and ns_tree_add_raw() can go.
Landlock now logs that id instead of zero when it denies the creation of
a namespace.
I'd want to get the whole series into v7.4 since the hooks are new this
cycle. Otherwise v7.4 is the only release where namespace_init sees a
zero id and where Landlock logs zero for a denied namespace creation.
The systemd change I have for this uses the namespace_free hook whenever
the kernel has it. On a kernel with the hook but without the first fix
it would never learn about dead user namespaces.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
---
Changes in v2:
- Drop "landlock: pass the namespace id to log to check_ns_type()".
Landlock now logs the real namespace id for denied namespace creation
and its documentation and selftests are updated in "ns: allocate the
namespace id before the namespace_init hook" (Mickaël):
https://patch.msgid.link/20261028.oonaisai0Doh@digikod.net
- Link to v1: https://patch.msgid.link/20261026-work-security-namespace_free-v1-0-ffa3ebbf71bd@kernel.org
---
Christian Brauner (7):
lsm: always call the namespace_free hook
bpf: don't mark namespace_init and namespace_free arguments as trusted
selftests/bpf: add verifier tests for the namespace LSM hooks
ns: allocate the namespace id before the namespace_init hook
nstree: drop ns_tree_add_raw()
lsm: fix the security_namespace_init() kernel-doc
selftests/bpf: add a lifecycle test for the namespace LSM hooks
Documentation/admin-guide/LSM/landlock.rst | 5 +-
Documentation/trace/events-landlock.rst | 5 +-
fs/namespace.c | 6 +-
include/linux/ns_common.h | 16 ++-
include/linux/nstree.h | 29 +----
include/trace/events/landlock.h | 3 +-
ipc/namespace.c | 3 +-
kernel/bpf/bpf_lsm.c | 2 +
kernel/nscommon.c | 7 +-
kernel/nstree.c | 2 +-
net/core/net_namespace.c | 4 +-
security/landlock/ns.c | 3 +-
security/security.c | 9 +-
.../selftests/bpf/prog_tests/ns_lifecycle.c | 145 +++++++++++++++++++++
tools/testing/selftests/bpf/prog_tests/verifier.c | 2 +
.../selftests/bpf/progs/test_ns_lifecycle.c | 88 +++++++++++++
.../selftests/bpf/progs/verifier_lsm_namespace.c | 38 ++++++
.../testing/selftests/bpf/test_kmods/bpf_testmod.c | 5 +
.../selftests/bpf/test_kmods/bpf_testmod_kfunc.h | 1 +
tools/testing/selftests/landlock/ns_test.c | 7 +-
20 files changed, 323 insertions(+), 57 deletions(-)
---
base-commit: 21a7f44fd0765fcc5194130b28767786eba1d1e7
change-id: 20261026-work-security-namespace_free-7aaf89b5b00e
next reply other threads:[~2026-10-29 16:41 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 16:40 Christian Brauner [this message]
2026-10-29 16:40 ` [PATCH v2 1/7] lsm: always call the namespace_free hook Christian Brauner
2026-10-29 16:48 ` sashiko-bot
2026-10-29 16:40 ` [PATCH v2 2/7] bpf: don't mark namespace_init and namespace_free arguments as trusted Christian Brauner
2026-10-29 16:47 ` sashiko-bot
2026-10-29 16:40 ` [PATCH v2 3/7] selftests/bpf: add verifier tests for the namespace LSM hooks Christian Brauner
2026-10-29 16:46 ` sashiko-bot
2026-10-29 16:40 ` [PATCH v2 4/7] ns: allocate the namespace id before the namespace_init hook Christian Brauner
2026-10-29 16:51 ` sashiko-bot
2026-10-29 22:13 ` Mickaël Salaün
2026-10-29 16:41 ` [PATCH v2 5/7] nstree: drop ns_tree_add_raw() Christian Brauner
2026-10-29 16:49 ` sashiko-bot
2026-10-29 16:41 ` [PATCH v2 6/7] lsm: fix the security_namespace_init() kernel-doc Christian Brauner
2026-10-29 16:50 ` sashiko-bot
2026-10-29 16:41 ` [PATCH v2 7/7] selftests/bpf: add a lifecycle test for the namespace LSM hooks Christian Brauner
2026-10-29 16:55 ` sashiko-bot
2026-10-29 21:06 ` [PATCH v2 0/7] ns: fixes " Paul Moore
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=20261029-work-security-namespace_free-v2-0-65591dbba7b3@kernel.org \
--to=brauner@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=gnoack@google.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=mic@digikod.net \
--cc=netdev@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
/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