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>,
netdev@vger.kernel.org,
"Christian Brauner (Amutable)" <brauner@kernel.org>,
stable@kernel.org
Subject: [PATCH 0/8] ns: fixes for the namespace LSM hooks
Date: Mon, 26 Oct 2026 10:57:08 +0100 [thread overview]
Message-ID: <20261026-work-security-namespace_free-v1-0-ffa3ebbf71bd@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 keeps logging zero for denied namespace creation because that's
what it documents.
I'd want to get the first three patches into v7.4 since the hooks are
new this cycle. 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>
---
Christian Brauner (8):
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
landlock: pass the namespace id to log to check_ns_type()
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
fs/namespace.c | 6 +-
include/linux/ns_common.h | 16 ++-
include/linux/nstree.h | 29 +----
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 | 11 +-
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 +
16 files changed, 314 insertions(+), 54 deletions(-)
---
base-commit: 21a7f44fd0765fcc5194130b28767786eba1d1e7
change-id: 20261026-work-security-namespace_free-7aaf89b5b00e
next reply other threads:[~2026-10-26 9:57 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-26 9:57 Christian Brauner [this message]
2026-10-26 9:57 ` [PATCH 1/8] lsm: always call the namespace_free hook Christian Brauner
2026-10-26 9:57 ` [PATCH 2/8] bpf: don't mark namespace_init and namespace_free arguments as trusted Christian Brauner
2026-10-26 9:57 ` [PATCH 3/8] selftests/bpf: add verifier tests for the namespace LSM hooks Christian Brauner
2026-10-26 9:57 ` [PATCH 4/8] landlock: pass the namespace id to log to check_ns_type() Christian Brauner
2026-10-26 9:57 ` [PATCH 5/8] ns: allocate the namespace id before the namespace_init hook Christian Brauner
2026-10-26 9:57 ` [PATCH 6/8] nstree: drop ns_tree_add_raw() Christian Brauner
2026-10-26 9:57 ` [PATCH 7/8] lsm: fix the security_namespace_init() kernel-doc Christian Brauner
2026-10-26 9:57 ` [PATCH 8/8] selftests/bpf: add a lifecycle test for the namespace LSM hooks Christian Brauner
2026-10-26 20:31 ` [PATCH 0/8] ns: fixes " Paul Moore
2026-10-27 9:24 ` Christian Brauner
2026-10-27 14:36 ` Daniel Borkmann
2026-10-27 22:37 ` Paul Moore
2026-10-28 10:42 ` Christian Brauner
2026-10-26 23:31 ` Alexei Starovoitov
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=20261026-work-security-namespace_free-v1-0-ffa3ebbf71bd@kernel.org \
--to=brauner@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=stable@kernel.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