* Re: [PATCH v1] mailmap: Add entry for Mickaël Salaün
From: Paul Moore @ 2026-02-11 9:45 UTC (permalink / raw)
To: Mickaël Salaün
Cc: linux-kernel, linux-security-module, Günther Noack,
James Morris
In-Reply-To: <20260207111136.577249-1-mic@digikod.net>
On Sat, Feb 7, 2026 at 6:28 AM Mickaël Salaün <mic@digikod.net> wrote:
>
> My Microsoft address is no longer used. Add a mailmap entry to reflect
> that.
>
> Cc: Günther Noack <gnoack@google.com>
> Cc: James Morris <jamorris@linux.microsoft.com>
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> ---
> .mailmap | 1 +
> 1 file changed, 1 insertion(+)
Reviewed-by: Paul Moore <paul@paul-moore.com>
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH] selftests/landlock: Remove duplicate include of stdio.h
From: Mickaël Salaün @ 2026-02-11 11:16 UTC (permalink / raw)
To: Chen Ni; +Cc: gnoack, shuah, linux-security-module, linux-kselftest,
linux-kernel
In-Reply-To: <20260211062122.2975127-1-nichen@iscas.ac.cn>
On Wed, Feb 11, 2026 at 02:21:22PM +0800, Chen Ni wrote:
> Remove duplicate inclusion of stdio.h in fs_bench.c to clean up
> redundant code.
Thanks! I also detected this issue while running `sort -u` on the
includes, so this is already taken into account in my next branch (with
other small fixes).
>
> Signed-off-by: Chen Ni <nichen@iscas.ac.cn>
> ---
> tools/testing/selftests/landlock/fs_bench.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/tools/testing/selftests/landlock/fs_bench.c b/tools/testing/selftests/landlock/fs_bench.c
> index 733c1264e5fd..551cb615ad93 100644
> --- a/tools/testing/selftests/landlock/fs_bench.c
> +++ b/tools/testing/selftests/landlock/fs_bench.c
> @@ -26,7 +26,6 @@
> #include <linux/prctl.h>
> #include <stdbool.h>
> #include <stdio.h>
> -#include <stdio.h>
> #include <errno.h>
> #include <stdlib.h>
> #include <string.h>
> --
> 2.25.1
>
>
^ permalink raw reply
* [GIT PULL] Landlock update for v7.0-rc1
From: Mickaël Salaün @ 2026-02-11 14:13 UTC (permalink / raw)
To: Linus Torvalds
Cc: Mickaël Salaün, Günther Noack, Matthieu Buffet,
Samasth Norway Ananda, linux-kernel, linux-security-module
Hi,
These changes extend Landlock to enforce restrictions on a whole
process, similarly to the seccomp's TSYNC flag. Data structure
refactoring simplifies code and improves performance. Documentation is
extended to cover missing parts.
Please pull these changes for v7.0-rc1 . These commits merge cleanly
with your master branch. The kernel changes have been tested in the
latest linux-next releases for some weeks, but I rebased the last
commits to fix a kselftest build issue on old distros, and to add a
review tag.
Test coverage for security/landlock is 91.4% of 2093 lines according to
LLVM 21, and it was 91.9% of 1933 lines before this PR.
Regards,
Mickaël
PS: I recently updated my PGP key:
https://lore.kernel.org/keys/20260206.waiCh9iex3ai@digikod.net/
--
The following changes since commit 24d479d26b25bce5faea3ddd9fa8f3a6c3129ea7:
Linux 6.19-rc6 (2026-01-18 15:42:45 -0800)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/mic/linux.git tags/landlock-7.0-rc1
for you to fetch changes up to e265b330b93e3a3f9ff5256451d4f09b5f89b239:
mailmap: Add entry for Mickaël Salaün (2026-02-11 12:03:44 +0100)
----------------------------------------------------------------
Landlock update for v7.0-rc1
----------------------------------------------------------------
Günther Noack (6):
landlock: Multithreading support for landlock_restrict_self()
selftests/landlock: Add LANDLOCK_RESTRICT_SELF_TSYNC tests
landlock: Document LANDLOCK_RESTRICT_SELF_TSYNC
selftests/landlock: Add filesystem access benchmark
landlock: Add access_mask_subset() helper
landlock: Transpose the layer masks data structure
Matthieu Buffet (2):
landlock: Minor reword of docs for TCP access rights
landlock: Refactor TCP socket type check
Mickaël Salaün (1):
mailmap: Add entry for Mickaël Salaün
Samasth Norway Ananda (3):
landlock: Add backwards compatibility for restrict flags
landlock: Add errata documentation section
landlock: Document audit blocker field format
.mailmap | 1 +
Documentation/admin-guide/LSM/landlock.rst | 35 +-
Documentation/userspace-api/landlock.rst | 105 ++++-
include/uapi/linux/landlock.h | 30 +-
security/landlock/Makefile | 11 +-
security/landlock/access.h | 35 +-
security/landlock/audit.c | 81 ++--
security/landlock/audit.h | 3 +-
security/landlock/cred.h | 12 +
security/landlock/domain.c | 44 +-
security/landlock/domain.h | 3 +-
security/landlock/errata/abi-1.h | 8 +
security/landlock/errata/abi-4.h | 7 +
security/landlock/errata/abi-6.h | 10 +
security/landlock/fs.c | 352 ++++++++--------
security/landlock/limits.h | 2 +-
security/landlock/net.c | 30 +-
security/landlock/ruleset.c | 91 ++---
security/landlock/ruleset.h | 6 +-
security/landlock/syscalls.c | 65 +--
security/landlock/tsync.c | 561 ++++++++++++++++++++++++++
security/landlock/tsync.h | 16 +
tools/testing/selftests/landlock/.gitignore | 1 +
tools/testing/selftests/landlock/Makefile | 1 +
tools/testing/selftests/landlock/base_test.c | 8 +-
tools/testing/selftests/landlock/fs_bench.c | 214 ++++++++++
tools/testing/selftests/landlock/tsync_test.c | 161 ++++++++
27 files changed, 1490 insertions(+), 403 deletions(-)
create mode 100644 security/landlock/tsync.c
create mode 100644 security/landlock/tsync.h
create mode 100644 tools/testing/selftests/landlock/fs_bench.c
create mode 100644 tools/testing/selftests/landlock/tsync_test.c
^ permalink raw reply
* Re: [PATCH v3 0/3] Landlock multithreaded enforcement
From: Mickaël Salaün @ 2026-02-11 14:55 UTC (permalink / raw)
To: Günther Noack
Cc: linux-security-module, Jann Horn, Serge Hallyn,
Konstantin Meskhidze, Tingmao Wang, Matthieu Buffet
In-Reply-To: <20260205.phu7Bo2ieMih@digikod.net>
FYI, syzkaller now supports this new flag, and it has been fuzzed for a
few months (before being merged):
https://github.com/google/syzkaller/commit/e5e258750ba4cad4408ac45a26c0aafff51d45b1
On Thu, Feb 05, 2026 at 07:53:47PM +0100, Mickaël Salaün wrote:
> Good job for writing this complex mechanic (and the related doc), this
> patch series is great! It's been in linux-next for a few weeks and I'll
> take it for Linux 7.0
>
> I did some cosmetic changes though, you'll find them in my commits.
> Some more tests are needed but I'll take this series for now.
>
> Thanks!
>
> On Thu, Nov 27, 2025 at 12:51:33PM +0100, Günther Noack wrote:
> > This patch set adds the LANDLOCK_RESTRICT_SELF_TSYNC flag to
> > landlock_restrict_self(). With this flag, the passed Landlock ruleset
> > will not only be applied to the calling thread, but to all threads
> > which belong to the same process.
> >
> > Motivation
> > ==========
> >
> > TL;DR: The libpsx/nptl(7) signal hack which we use in user space for
> > multi-threaded Landlock enforcement is incompatible with Landlock's
> > signal scoping support. Landlock can restrict the use of signals
> > across Landlock domains, but we need signals ourselves in user space
> > in ways that are not permitted any more under these restrictions.
> >
> > Enabling Landlock proves to be difficult in processes that are already
> > multi-threaded at the time of enforcement:
> >
> > * Enforcement in only one thread is usually a mistake because threads
> > do not normally have proper security boundaries between them.
> >
> > * Also, multithreading is unavoidable in some circumstances, such as
> > when using Landlock from a Go program. Go programs are already
> > multithreaded by the time that they enter the "func main()".
> >
> > So far, the approach in Go[1] was to use libpsx[2]. This library
> > implements the mechanism described in nptl(7) [3]: It keeps track of
> > all threads with a linker hack and then makes all threads do the same
> > syscall by registering a signal handler for them and invoking it.
> >
> > With commit 54a6e6bbf3be ("landlock: Add signal scoping"), Landlock
> > gained the ability to restrict the use of signals across different
> > Landlock domains.
> >
> > Landlock's signal scoping support is incompatible with the libpsx
> > approach of enabling Landlock:
> >
> > (1) With libpsx, although all threads enforce the same ruleset object,
> > they technically do the operation separately and end up in
> > distinct Landlock domains. This breaks signaling across threads
> > when using LANDLOCK_SCOPE_SIGNAL.
> >
> > (2) Cross-thread Signals are themselves needed to enforce further
> > nested Landlock domains across multiple threads. So nested
> > Landlock policies become impossible there.
> >
> > In addition to Landlock itself, cross-thread signals are also needed
> > for other seemingly-harmless API calls like the setuid(2) [4] and for
> > the use of libcap (co-developed with libpsx), which have the same
> > problem where the underlying syscall only applies to the calling
> > thread.
> >
> > Implementation details
> > ======================
> >
> > Enforcement prerequisites
> > -------------------------
> >
> > Normally, the prerequisite for enforcing a Landlock policy is to
> > either have CAP_SYS_ADMIN or the no_new_privs flag. With
> > LANDLOCK_RESTRICT_SELF_TSYNC, the no_new_privs flag will automatically
> > be applied for sibling threads if the caller had it.
> >
> > These prerequisites and the "TSYNC" behavior work the same as for
> > Seccomp and its SECCOMP_FILTER_FLAG_TSYNC flag.
> >
> > Pseudo-signals
> > --------------
> >
> > Landlock domains are stored in struct cred, and a task's struct cred
> > can only be modified by the task itself [6].
> >
> > To make that work, we use task_work_add() to register a pseudo-signal
> > for each of the affected threads. At signal execution time, these
> > tasks will coordinate to switch out their Landlock policy in lockstep
> > with each other, guaranteeing all-or-nothing semantics.
> >
> > This implementation can be thought of as a kernel-side implementation
> > of the userspace hack that glibc/NPTL use for setuid(2) [3] [4], and
> > which libpsx implements for libcap [2].
> >
> > Finding all sibling threads
> > ---------------------------
> >
> > In order to avoid grabbing the global task_list_lock, we employ the
> > scheme proposed by Jann Horn in [7]:
> >
> > 1. Loop through the list of sibling threads
> > 2. Schedule a pseudo-signal for each and make each thread wait in the
> > pseudo-signal
> > 3. Go back to 1. and look for more sibling thread that we have not
> > seen yet
> >
> > Do this until no more new threads are found. As all threads were
> > waiting in their pseudo-signals, they can not spawn additional threads
> > and we found them all.
> >
> > Coordination between tasks
> > --------------------------
> >
> > As tasks run their pseudo-signal task work, they coordinate through
> > the following completions:
> >
> > - all_prepared (with counter num_preparing)
> >
> > When done, all new sibling threads in the inner loop(!) of finding
> > new threads are now in their pseudo-signal handlers and have
> > prepared the struct cred object to commit (or written an error into
> > the shared "preparation_error").
> >
> > The lifetime of all_prepared is only the inner loop of finding new
> > threads.
> >
> > - ready_to_commit
> >
> > When done, the outer loop of finding new threads is done and all
> > sibling threads have prepared their struct cred object. Marked
> > completed by the calling thread.
> >
> > - all_finished
> >
> > When done, all sibling threads are done executing their
> > pseudo-signal handlers.
> >
> > Use of credentials API
> > ----------------------
> >
> > Under normal circumstances, sibling threads share the same struct cred
> > object. To avoid unnecessary duplication, if we find that a thread
> > uses the same struct cred as the calling thread, we side-step the
> > normal use of the credentials API [6] and place a pointer to that
> > existing struct cred instead of creating a new one using
> > prepare_creds() in the sibling thread.
> >
> > Noteworthy discussion points
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >
> > * We are side-stepping the normal credentials API [6], by re-wiring an
> > existing struct cred object instead of calling prepare_creds().
> >
> > We can technically avoid it, but it would create unnecessary
> > duplicate struct cred objects in multithreaded scenarios.
> >
> > Change Log
> > ==========
> >
> > v3:
> > - bigger organizational changes
> > - move tsync logic into own file
> > - tsync: extract count_additional_threads() and
> > schedule_task_work()
> > - code style
> > - restrict_one_thread, syscalls.c: use err instead of res (mic)
> > - restrict_one_thread: inline current_cred variable
> > - restrict_one_thread: add comment to shortcut logic (mic)
> > - rsync_works helpers: use size_t i for loop vars
> > - landlock_cred_copy: skip redundant NULL checks
> > - function name: s,tsync_works_free,tsync_works_release, (mic)
> > - tsync_works_grow_by: kzalloc into a temporary variable for
> > clarity (mic)
> > - tsync_works_contains_task: make struct task_works const
> > - bugs
> > - handle kmalloc family failures correctly (jannh)
> > - tsync_works_release: check task NULL ptr before put
> > - s/put_task_struct_rcu_user/put_task_struct/ (jannh)
> > - concurrency bugs
> > - schedule_task_work: do not return error when encountering exiting
> > tasks This can happen during normal operation, we should not
> > error due to it (jannh)
> > - landlock_restrict_sibling_threads: make current hold the
> > num_unfinished/all_finished barrier (more robust, jannh)
> > - un-wedge the deadlock using wait_for_completion_interruptible
> > (jannh) See "testing" below and discussion in
> > https://lore.kernel.org/all/CAG48ez1oS9kANZBq1bt+D76MX03DPHAFp76GJt7z5yx-Na1VLQ@mail.gmail.com/
> > - logic
> > - tsync_works_grow_by(): grow to size+n, not capacity+n
> > - tsync_works_grow_by(): add overflow check for capacity increase
> > - landlock_restrict_self(): make TSYNC and LOG flags work together
> > - set no_new_privs in the same way as seccomp,
> > whenever the calling thread had it
> > - testing
> > - add test where multiple threads call landlock_restrict_self()
> > concurrently
> > - test that no_new_privs is implicitly enabled for sibling threads
> > - bump ABI version to v8
> > - documentation improvements
> > - document ABI v8
> > - move flag documentation into the landlock.h header
> > - comment: Explain why we do not need sighand->siglock or
> > cred_guard_mutex
> > - various comment improvements
> > - reminder above struct landlock_cred_security about updating
> > landlock_cred_copy on changes
> >
> > v2:
> > - https://lore.kernel.org/all/20250221184417.27954-2-gnoack3000@gmail.com/
> > - Semantics:
> > - Threads implicitly set NO_NEW_PRIVS unless they have
> > CAP_SYS_ADMIN, to fulfill Landlock policy enforcement
> > prerequisites
> > - Landlock policy gets unconditionally overridden even if the
> > previously established Landlock domains in sibling threads were
> > diverging.
> > - Restructure discovery of all sibling threads, with the algorithm
> > proposed by Jann Horn [7]: Loop through threads multiple times, and
> > get them all stuck in the pseudo signal (task work), until no new
> > sibling threads show up.
> > - Use RCU lock when iterating over sibling threads.
> > - Override existing Landlock domains of other threads,
> > instead of applying a new Landlock policy on top
> > - Directly re-wire the struct cred for sibling threads,
> > instread of creating a new one with prepare_creds().
> > - Tests:
> > - Remove multi_threaded_failure test
> > (The only remaining failure case is ENOMEM,
> > there is no good way to provoke that in a selftest)
> > - Add test for success despite diverging Landlock domains.
> >
> > [1] https://github.com/landlock-lsm/go-landlock
> > [2] https://sites.google.com/site/fullycapable/who-ordered-libpsx
> > [3] https://man.gnoack.org/7/nptl
> > [4] https://man.gnoack.org/2/setuid#VERSIONS
> > [5] https://lore.kernel.org/all/20240805-remove-cred-transfer-v2-0-a2aa1d45e6b8@google.com/
> > [6] https://www.kernel.org/doc/html/latest/security/credentials.html
> > [7] https://lore.kernel.org/all/CAG48ez0pWg3OTABfCKRk5sWrURM-HdJhQMcWedEppc_z1rrVJw@mail.gmail.com/
> >
> > Günther Noack (3):
> > landlock: Multithreading support for landlock_restrict_self()
> > landlock: selftests for LANDLOCK_RESTRICT_SELF_TSYNC
> > landlock: Document LANDLOCK_RESTRICT_SELF_TSYNC
> >
> > Documentation/userspace-api/landlock.rst | 8 +
> > include/uapi/linux/landlock.h | 13 +
> > security/landlock/Makefile | 2 +-
> > security/landlock/cred.h | 12 +
> > security/landlock/limits.h | 2 +-
> > security/landlock/syscalls.c | 66 ++-
> > security/landlock/tsync.c | 555 ++++++++++++++++++
> > security/landlock/tsync.h | 16 +
> > tools/testing/selftests/landlock/base_test.c | 8 +-
> > tools/testing/selftests/landlock/tsync_test.c | 161 +++++
> > 10 files changed, 810 insertions(+), 33 deletions(-)
> > create mode 100644 security/landlock/tsync.c
> > create mode 100644 security/landlock/tsync.h
> > create mode 100644 tools/testing/selftests/landlock/tsync_test.c
> >
> > --
> > 2.52.0.177.g9f829587af-goog
> >
> >
^ permalink raw reply
* Re: [RFC PATCH] fs/pidfs: Add permission check to pidfd_info()
From: Daniel Durning @ 2026-02-11 19:43 UTC (permalink / raw)
To: Christian Brauner
Cc: linux-fsdevel, linux-security-module, selinux, viro, jack, paul,
stephen.smalley.work, omosnace, Oleg Nesterov
In-Reply-To: <20260209-spanplatten-zerrt-73851db30f18@brauner>
On Mon, Feb 9, 2026 at 9:01 AM Christian Brauner <brauner@kernel.org> wrote:
>
> On Fri, Feb 06, 2026 at 06:02:48PM +0000, danieldurning.work@gmail.com wrote:
> > From: Daniel Durning <danieldurning.work@gmail.com>
> >
> > Added a permission check to pidfd_info(). Originally, process info
> > could be retrieved with a pidfd even if proc was mounted with hidepid
> > enabled, allowing pidfds to be used to bypass those protections. We
> > now call ptrace_may_access() to perform some DAC checking as well
> > as call the appropriate LSM hook.
> >
> > The downside to this approach is that there are now more restrictions
> > on accessing this info from a pidfd than when just using proc (without
> > hidepid). I am open to suggestions if anyone can think of a better way
> > to handle this.
>
> This isn't really workable since this would regress userspace quite a
> bit. I think we need a different approach. I've given it some thought
> and everything's kinda ugly but this might work.
>
> In struct pid_namespace record whether anyone ever mounted a procfs
> with hidepid turned on for this pidns. In pidfd_info() we check whether
> hidepid was ever turned on. If it wasn't we're done and can just return
> the info. This will be the common case. If hidepid was ever turned on
> use kern_path("/proc") to lookup procfs. If not found check
> ptrace_may_access() to decide whether to return the info or not. If
> /proc is found check it's hidepid settings and make a decision based on
> that.
>
> You can probably reorder this to call ptrace_may_access() first and then
> do the procfs lookup dance. Thoughts?
Thanks for the feedback. I think your solution makes sense.
Unfortunately, it seems like systemd mounts procfs with hidepid enabled on
boot for services with the ProtectProc option enabled. This means that
procfs will always have been mounted with hidepid in the init pid namespace.
Do you think it would be viable to record whether or not procfs was mounted
with hidepid enabled in the mount namespace instead?
> > I have also noticed that it is possible to use pidfds to poll on any
> > process regardless of whether the process is a child of the caller,
> > has a different UID, or has a different security context. Is this
> > also worth addressing? If so, what exactly should the DAC checks be?
>
> Oleg and I had discusses this and decided that such polling isn't
> sensitive information so by default this should just work and it's
> relied upon in Android and in a bunch of other workloads. An LSM can of
> course restrict access via security_file_ioctl().
>
> Fwiw, pidfds now support persistent trusted extended attributes so if
> the LSM folks wanted we can add security.* extended attribute support
> and they can mark pidfds with persistent security labels - persistent as
> in for the lifetime of the task.
>
> > Signed-off-by: Daniel Durning <danieldurning.work@gmail.com>
> > ---
> > fs/pidfs.c | 7 +++++++
> > 1 file changed, 7 insertions(+)
> >
> > diff --git a/fs/pidfs.c b/fs/pidfs.c
> > index dba703d4ce4a..058a7d798bca 100644
> > --- a/fs/pidfs.c
> > +++ b/fs/pidfs.c
> > @@ -365,6 +365,13 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
> > goto copy_out;
> > }
> >
> > + /*
> > + * Do a filesystem cred ptrace check to verify access
> > + * to the task's info.
> > + */
> > + if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
> > + return -EACCES;
> > +
> > c = get_task_cred(task);
> > if (!c)
> > return -ESRCH;
> > --
> > 2.52.0
> >
^ permalink raw reply
* Re: [GIT PULL] Smack patches for 7.0
From: pr-tracker-bot @ 2026-02-12 0:04 UTC (permalink / raw)
To: Casey Schaufler
Cc: Linus Torvalds, LSM List, Linux kernel mailing list,
Konstantin Andreev, Taimoor Zaeem, Casey Schaufler
In-Reply-To: <28dea16f-18c3-4a2f-821c-e85b660125ed@schaufler-ca.com>
The pull request you sent on Mon, 9 Feb 2026 13:15:00 -0800:
> https://github.com/cschaufler/smack-next tags/Smack-for-7.0
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/146fa666d89f233b87f1cdc7b9bce34c61b45cbd
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [GIT PULL] Landlock update for v7.0-rc1
From: pr-tracker-bot @ 2026-02-12 0:04 UTC (permalink / raw)
To: Mickaël Salaün
Cc: Linus Torvalds, Mickaël Salaün, Günther Noack,
Matthieu Buffet, Samasth Norway Ananda, linux-kernel,
linux-security-module
In-Reply-To: <20260211141302.1134092-1-mic@digikod.net>
The pull request you sent on Wed, 11 Feb 2026 15:13:02 +0100:
> https://lore.kernel.org/keys/20260206.waiCh9iex3ai@digikod.net/ --
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/c22e26bd0906e9c8325462993f01adb16b8ea2c0
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [PATCH v2 1/3] integrity: Make arch_ima_get_secureboot integrity-wide
From: Coiby Xu @ 2026-02-12 1:28 UTC (permalink / raw)
To: Mimi Zohar
Cc: linux-integrity, Heiko Carstens, Alexander Egorenkov,
Ard Biesheuvel, Dave Hansen, Roberto Sassu, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy (CS GROUP),
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
H. Peter Anvin, Dmitry Kasatkin, Eric Snowberg, Paul Moore,
James Morris, Serge E. Hallyn, Jarkko Sakkinen, open list,
open list:LINUX FOR POWERPC (32-BIT AND 64-BIT),
open list:S390 ARCHITECTURE,
open list:EXTENSIBLE FIRMWARE INTERFACE (EFI),
open list:SECURITY SUBSYSTEM, open list:KEYS/KEYRINGS_INTEGRITY
In-Reply-To: <66f9d13875e81a965984e2a661e992a3fe43c516.camel@linux.ibm.com>
On Mon, Feb 09, 2026 at 03:43:08PM -0500, Mimi Zohar wrote:
>On Tue, 2026-02-03 at 12:14 +0800, Coiby Xu wrote:
>> EVM and other LSMs need the ability to query the secure boot status of
>> the system, without directly calling the IMA arch_ima_get_secureboot
>> function. Refactor the secure boot status check into a general function
>> named arch_get_secureboot.
>>
>> Reported-and-suggested-by: Mimi Zohar <zohar@linux.ibm.com>
>> Suggested-by: Roberto Sassu <roberto.sassu@huawei.com>
>> Signed-off-by: Coiby Xu <coxu@redhat.com>
>
>Thanks, Coiby. Other than unnecessarily splitting a line, the patch set looks
>good. As soon as the open window closes, I'll queue these patches for linux-
>next.
Hi Mimi, thanks for reviewing the patch set! Would you like me to send a
new version with the line splitting issue fixed?
>
>> diff --git a/security/integrity/ima/ima_efi.c b/security/integrity/ima/ima_efi.c
>> index 138029bfcce1..27521d665d33 100644
>> --- a/security/integrity/ima/ima_efi.c
>> +++ b/security/integrity/ima/ima_efi.c
[...]
>> {
>> - if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot()) {
>> + if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) &&
>> + arch_get_secureboot()) {
>
>No need to split the line here or below.
>
>
>> if (IS_ENABLED(CONFIG_MODULE_SIG))
>> set_module_sig_enforced();
>> if (IS_ENABLED(CONFIG_KEXEC_SIG))
>> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
>> index 5770cf691912..6d093ac82a45 100644
>> --- a/security/integrity/ima/ima_main.c
>> +++ b/security/integrity/ima/ima_main.c
>> @@ -949,8 +949,8 @@ static int ima_load_data(enum kernel_load_data_id id, bool contents)
>>
>> switch (id) {
>> case LOADING_KEXEC_IMAGE:
>> - if (IS_ENABLED(CONFIG_KEXEC_SIG)
>> - && arch_ima_get_secureboot()) {
>> + if (IS_ENABLED(CONFIG_KEXEC_SIG) &&
>> + arch_get_secureboot()) {
>
>===>
>
>Mimi
>
>> pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n");
>> return -EACCES;
>> }
>
--
Best regards,
Coiby
^ permalink raw reply
* Re: [PATCH v6 0/3] ima: Detect changes to files via kstat changes rather than i_version
From: Mimi Zohar @ 2026-02-12 19:45 UTC (permalink / raw)
To: Frederick Lawler, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn, Darrick J. Wong,
Christian Brauner, Josef Bacik, Jeff Layton
Cc: linux-kernel, linux-integrity, linux-security-module, kernel-team
In-Reply-To: <20260209-xfs-ima-fixup-v6-0-72f576f90e67@cloudflare.com>
On Mon, 2026-02-09 at 15:21 -0600, Frederick Lawler wrote:
> We uncovered a case in kernels >= 6.13 where XFS is no longer updating
> struct kstat.change_cookie on i_op getattr() access calls. Instead, XFS is
> using multigrain ctime (as well as other file systems) for
> change detection in commit 1cf7e834a6fb ("xfs: switch to
> multigrain timestamps").
>
> Because file systems may implement i_version as they see fit, IMA
> unnecessarily measures files.
Statements like this are wrong and certainly unnecessary. Refer to commit
db1d1e8b9867 ("IMA: use vfs_getattr_nosec to get the i_version"). Directly
accessing the i_version still worked on local filesystems.
I'll be posting a patch shortly that falls back to directly reading the
i_version, when STATX_CHANGE_COOKIE is not supported. It cleans up the file
change detection code, making it more readable and should simplify adding the
ctime file change detection.
> We're proposing to compare against the kstat.change_cookie
> directly to the cached version, and fall back to a ctime comparison,
> if STATX_CHANGE_COOKIE is not supplied by vfs_getattr_nosec()'s result
> mask.
Please rebase your proposed change on this patch.
Mimi
^ permalink raw reply
* Re: [PATCH v6 0/3] ima: Detect changes to files via kstat changes rather than i_version
From: Frederick Lawler @ 2026-02-12 20:01 UTC (permalink / raw)
To: Mimi Zohar
Cc: Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Paul Moore,
James Morris, Serge E. Hallyn, Darrick J. Wong, Christian Brauner,
Josef Bacik, Jeff Layton, linux-kernel, linux-integrity,
linux-security-module, kernel-team
In-Reply-To: <50c5e00a8c336e8ab393457af009c26902114688.camel@linux.ibm.com>
On Thu, Feb 12, 2026 at 02:45:58PM -0500, Mimi Zohar wrote:
> On Mon, 2026-02-09 at 15:21 -0600, Frederick Lawler wrote:
> > We uncovered a case in kernels >= 6.13 where XFS is no longer updating
> > struct kstat.change_cookie on i_op getattr() access calls. Instead, XFS is
> > using multigrain ctime (as well as other file systems) for
> > change detection in commit 1cf7e834a6fb ("xfs: switch to
> > multigrain timestamps").
> >
> > Because file systems may implement i_version as they see fit, IMA
> > unnecessarily measures files.
>
> Statements like this are wrong and certainly unnecessary. Refer to commit
> db1d1e8b9867 ("IMA: use vfs_getattr_nosec to get the i_version"). Directly
> accessing the i_version still worked on local filesystems.
Sorry, that's the intention I was trying to get across.
>
> I'll be posting a patch shortly that falls back to directly reading the
> i_version, when STATX_CHANGE_COOKIE is not supported. It cleans up the file
> change detection code, making it more readable and should simplify adding the
> ctime file change detection.
>
> > We're proposing to compare against the kstat.change_cookie
> > directly to the cached version, and fall back to a ctime comparison,
> > if STATX_CHANGE_COOKIE is not supplied by vfs_getattr_nosec()'s result
> > mask.
>
> Please rebase your proposed change on this patch.
>
Sounds good. I'll keep an eye out for it.
^ permalink raw reply
* Re: [PATCH v2 1/3] integrity: Make arch_ima_get_secureboot integrity-wide
From: Mimi Zohar @ 2026-02-12 20:25 UTC (permalink / raw)
To: Coiby Xu
Cc: linux-integrity, Heiko Carstens, Alexander Egorenkov,
Ard Biesheuvel, Dave Hansen, Roberto Sassu, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy (CS GROUP),
Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
Sven Schnelle, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT),
H. Peter Anvin, Dmitry Kasatkin, Eric Snowberg, Paul Moore,
James Morris, Serge E. Hallyn, Jarkko Sakkinen, open list,
open list:LINUX FOR POWERPC (32-BIT AND 64-BIT),
open list:S390 ARCHITECTURE,
open list:EXTENSIBLE FIRMWARE INTERFACE (EFI),
open list:SECURITY SUBSYSTEM, open list:KEYS/KEYRINGS_INTEGRITY
In-Reply-To: <aY0rZp9ROwfjPgD8@Rk>
On Thu, 2026-02-12 at 09:28 +0800, Coiby Xu wrote:
> On Mon, Feb 09, 2026 at 03:43:08PM -0500, Mimi Zohar wrote:
> > On Tue, 2026-02-03 at 12:14 +0800, Coiby Xu wrote:
> > > EVM and other LSMs need the ability to query the secure boot status of
> > > the system, without directly calling the IMA arch_ima_get_secureboot
> > > function. Refactor the secure boot status check into a general function
> > > named arch_get_secureboot.
> > >
> > > Reported-and-suggested-by: Mimi Zohar <zohar@linux.ibm.com>
> > > Suggested-by: Roberto Sassu <roberto.sassu@huawei.com>
> > > Signed-off-by: Coiby Xu <coxu@redhat.com>
> >
> > Thanks, Coiby. Other than unnecessarily splitting a line, the patch set looks
> > good. As soon as the open window closes, I'll queue these patches for linux-
> > next.
>
> Hi Mimi, thanks for reviewing the patch set! Would you like me to send a
> new version with the line splitting issue fixed?
Yes, thanks.
Mimi
>
> >
> > > diff --git a/security/integrity/ima/ima_efi.c b/security/integrity/ima/ima_efi.c
> > > index 138029bfcce1..27521d665d33 100644
> > > --- a/security/integrity/ima/ima_efi.c
> > > +++ b/security/integrity/ima/ima_efi.c
> [...]
> > > {
> > > - if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot()) {
> > > + if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) &&
> > > + arch_get_secureboot()) {
> >
> > No need to split the line here or below.
> >
> >
> > > if (IS_ENABLED(CONFIG_MODULE_SIG))
> > > set_module_sig_enforced();
> > > if (IS_ENABLED(CONFIG_KEXEC_SIG))
> > > diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> > > index 5770cf691912..6d093ac82a45 100644
> > > --- a/security/integrity/ima/ima_main.c
> > > +++ b/security/integrity/ima/ima_main.c
> > > @@ -949,8 +949,8 @@ static int ima_load_data(enum kernel_load_data_id id, bool contents)
> > >
> > > switch (id) {
> > > case LOADING_KEXEC_IMAGE:
> > > - if (IS_ENABLED(CONFIG_KEXEC_SIG)
> > > - && arch_ima_get_secureboot()) {
> > > + if (IS_ENABLED(CONFIG_KEXEC_SIG) &&
> > > + arch_get_secureboot()) {
> >
> > ===>
> >
> > Mimi
> >
> > > pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n");
> > > return -EACCES;
> > > }
> >
^ permalink raw reply
* [PATCH v3 1/3] integrity: Make arch_ima_get_secureboot integrity-wide
From: Coiby Xu @ 2026-02-13 1:28 UTC (permalink / raw)
To: linux-integrity
Cc: Heiko Carstens, Alexander Egorenkov, Ard Biesheuvel, Dave Hansen,
Mimi Zohar, Roberto Sassu, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), Vasily Gorbik,
Alexander Gordeev, Christian Borntraeger, Sven Schnelle,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT), H. Peter Anvin,
Dmitry Kasatkin, Eric Snowberg, Paul Moore, James Morris,
Serge E. Hallyn, Jarkko Sakkinen, open list,
open list:LINUX FOR POWERPC (32-BIT AND 64-BIT),
open list:S390 ARCHITECTURE,
open list:EXTENSIBLE FIRMWARE INTERFACE (EFI),
open list:SECURITY SUBSYSTEM, open list:KEYS/KEYRINGS_INTEGRITY
In-Reply-To: <20260213012851.2532722-1-coxu@redhat.com>
EVM and other LSMs need the ability to query the secure boot status of
the system, without directly calling the IMA arch_ima_get_secureboot
function. Refactor the secure boot status check into a general function
named arch_get_secureboot.
Reported-and-suggested-by: Mimi Zohar <zohar@linux.ibm.com>
Suggested-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Coiby Xu <coxu@redhat.com>
---
MAINTAINERS | 1 +
arch/powerpc/kernel/ima_arch.c | 5 --
arch/powerpc/kernel/secure_boot.c | 6 ++
arch/s390/kernel/ima_arch.c | 6 --
arch/s390/kernel/ipl.c | 5 ++
arch/x86/include/asm/efi.h | 4 +-
arch/x86/platform/efi/efi.c | 2 +-
include/linux/ima.h | 7 +--
include/linux/secure_boot.h | 19 +++++++
security/integrity/Makefile | 3 +-
security/integrity/efi_secureboot.c | 56 +++++++++++++++++++
security/integrity/ima/ima_appraise.c | 2 +-
security/integrity/ima/ima_efi.c | 47 +---------------
security/integrity/ima/ima_main.c | 3 +-
security/integrity/integrity.h | 1 +
security/integrity/platform_certs/load_uefi.c | 2 +-
security/integrity/secure_boot.c | 16 ++++++
17 files changed, 115 insertions(+), 70 deletions(-)
create mode 100644 include/linux/secure_boot.h
create mode 100644 security/integrity/efi_secureboot.c
create mode 100644 security/integrity/secure_boot.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 149deedafe2c..56242d78e4a6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12550,6 +12550,7 @@ R: Eric Snowberg <eric.snowberg@oracle.com>
L: linux-integrity@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git
+F: include/linux/secure_boot.h
F: security/integrity/
F: security/integrity/ima/
diff --git a/arch/powerpc/kernel/ima_arch.c b/arch/powerpc/kernel/ima_arch.c
index b7029beed847..0d8892a03526 100644
--- a/arch/powerpc/kernel/ima_arch.c
+++ b/arch/powerpc/kernel/ima_arch.c
@@ -7,11 +7,6 @@
#include <linux/ima.h>
#include <asm/secure_boot.h>
-bool arch_ima_get_secureboot(void)
-{
- return is_ppc_secureboot_enabled();
-}
-
/*
* The "secure_rules" are enabled only on "secureboot" enabled systems.
* These rules verify the file signatures against known good values.
diff --git a/arch/powerpc/kernel/secure_boot.c b/arch/powerpc/kernel/secure_boot.c
index 3a28795b4ed8..28436c1599e0 100644
--- a/arch/powerpc/kernel/secure_boot.c
+++ b/arch/powerpc/kernel/secure_boot.c
@@ -5,6 +5,7 @@
*/
#include <linux/types.h>
#include <linux/of.h>
+#include <linux/secure_boot.h>
#include <linux/string_choices.h>
#include <asm/secure_boot.h>
@@ -44,6 +45,11 @@ bool is_ppc_secureboot_enabled(void)
return enabled;
}
+bool arch_get_secureboot(void)
+{
+ return is_ppc_secureboot_enabled();
+}
+
bool is_ppc_trustedboot_enabled(void)
{
struct device_node *node;
diff --git a/arch/s390/kernel/ima_arch.c b/arch/s390/kernel/ima_arch.c
index f3c3e6e1c5d3..6ccbe34ce408 100644
--- a/arch/s390/kernel/ima_arch.c
+++ b/arch/s390/kernel/ima_arch.c
@@ -1,12 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/ima.h>
-#include <asm/boot_data.h>
-
-bool arch_ima_get_secureboot(void)
-{
- return ipl_secure_flag;
-}
const char * const *arch_get_ima_policy(void)
{
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index dcdc7e274848..781deb588557 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -2504,6 +2504,11 @@ void *ipl_report_finish(struct ipl_report *report)
return buf;
}
+bool arch_get_secureboot(void)
+{
+ return ipl_secure_flag;
+}
+
int ipl_report_free(struct ipl_report *report)
{
struct ipl_report_component *comp, *ncomp;
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index f227a70ac91f..ee382b56dd7b 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -401,9 +401,9 @@ extern int __init efi_memmap_split_count(efi_memory_desc_t *md,
extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap,
void *buf, struct efi_mem_range *mem);
-extern enum efi_secureboot_mode __x86_ima_efi_boot_mode(void);
+enum efi_secureboot_mode __x86_efi_boot_mode(void);
-#define arch_ima_efi_boot_mode __x86_ima_efi_boot_mode()
+#define arch_efi_boot_mode __x86_efi_boot_mode()
#ifdef CONFIG_EFI_RUNTIME_MAP
int efi_get_runtime_map_size(void);
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index d00c6de7f3b7..74032f3ab9b0 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -920,7 +920,7 @@ umode_t efi_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n)
return attr->mode;
}
-enum efi_secureboot_mode __x86_ima_efi_boot_mode(void)
+enum efi_secureboot_mode __x86_efi_boot_mode(void)
{
return boot_params.secure_boot;
}
diff --git a/include/linux/ima.h b/include/linux/ima.h
index 8e29cb4e6a01..b3927b795a60 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -11,6 +11,7 @@
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/kexec.h>
+#include <linux/secure_boot.h>
#include <crypto/hash_info.h>
struct linux_binprm;
@@ -72,14 +73,8 @@ int __init ima_get_kexec_buffer(void **addr, size_t *size);
#endif
#ifdef CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT
-extern bool arch_ima_get_secureboot(void);
extern const char * const *arch_get_ima_policy(void);
#else
-static inline bool arch_ima_get_secureboot(void)
-{
- return false;
-}
-
static inline const char * const *arch_get_ima_policy(void)
{
return NULL;
diff --git a/include/linux/secure_boot.h b/include/linux/secure_boot.h
new file mode 100644
index 000000000000..3ded3f03655c
--- /dev/null
+++ b/include/linux/secure_boot.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2026 Red Hat, Inc. All Rights Reserved.
+ *
+ * Author: Coiby Xu <coxu@redhat.com>
+ */
+
+#ifndef _LINUX_SECURE_BOOT_H
+#define _LINUX_SECURE_BOOT_H
+
+#include <linux/types.h>
+
+/*
+ * Returns true if the platform secure boot is enabled.
+ * Returns false if disabled or not supported.
+ */
+bool arch_get_secureboot(void);
+
+#endif /* _LINUX_SECURE_BOOT_H */
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index 92b63039c654..548665e2b702 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -5,7 +5,7 @@
obj-$(CONFIG_INTEGRITY) += integrity.o
-integrity-y := iint.o
+integrity-y := iint.o secure_boot.o
integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
@@ -18,6 +18,7 @@ integrity-$(CONFIG_LOAD_IPL_KEYS) += platform_certs/load_ipl_s390.o
integrity-$(CONFIG_LOAD_PPC_KEYS) += platform_certs/efi_parser.o \
platform_certs/load_powerpc.o \
platform_certs/keyring_handler.o
+integrity-$(CONFIG_EFI) += efi_secureboot.o
# The relative order of the 'ima' and 'evm' LSMs depends on the order below.
obj-$(CONFIG_IMA) += ima/
obj-$(CONFIG_EVM) += evm/
diff --git a/security/integrity/efi_secureboot.c b/security/integrity/efi_secureboot.c
new file mode 100644
index 000000000000..bfd4260a83a3
--- /dev/null
+++ b/security/integrity/efi_secureboot.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-1.0+
+/*
+ * Copyright (C) 2018 IBM Corporation
+ */
+#include <linux/efi.h>
+#include <linux/secure_boot.h>
+#include <asm/efi.h>
+
+#ifndef arch_efi_boot_mode
+#define arch_efi_boot_mode efi_secureboot_mode_unset
+#endif
+
+static enum efi_secureboot_mode get_sb_mode(void)
+{
+ enum efi_secureboot_mode mode;
+
+ if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) {
+ pr_info("integrity: secureboot mode unknown, no efi\n");
+ return efi_secureboot_mode_unknown;
+ }
+
+ mode = efi_get_secureboot_mode(efi.get_variable);
+ if (mode == efi_secureboot_mode_disabled)
+ pr_info("integrity: secureboot mode disabled\n");
+ else if (mode == efi_secureboot_mode_unknown)
+ pr_info("integrity: secureboot mode unknown\n");
+ else
+ pr_info("integrity: secureboot mode enabled\n");
+ return mode;
+}
+
+/*
+ * Query secure boot status
+ *
+ * Note don't call this function too early e.g. in __setup hook otherwise the
+ * kernel may hang when calling efi_get_secureboot_mode.
+ *
+ */
+bool arch_get_secureboot(void)
+{
+ static enum efi_secureboot_mode sb_mode;
+ static bool initialized;
+
+ if (!initialized && efi_enabled(EFI_BOOT)) {
+ sb_mode = arch_efi_boot_mode;
+
+ if (sb_mode == efi_secureboot_mode_unset)
+ sb_mode = get_sb_mode();
+ initialized = true;
+ }
+
+ if (sb_mode == efi_secureboot_mode_enabled)
+ return true;
+ else
+ return false;
+}
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 5149ff4fd50d..9737bf76ce17 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -27,7 +27,7 @@ core_param(ima_appraise, ima_appraise_cmdline_default, charp, 0);
void __init ima_appraise_parse_cmdline(void)
{
const char *str = ima_appraise_cmdline_default;
- bool sb_state = arch_ima_get_secureboot();
+ bool sb_state = arch_get_secureboot();
int appraisal_state = ima_appraise;
if (!str)
diff --git a/security/integrity/ima/ima_efi.c b/security/integrity/ima/ima_efi.c
index 138029bfcce1..78191879dd98 100644
--- a/security/integrity/ima/ima_efi.c
+++ b/security/integrity/ima/ima_efi.c
@@ -2,52 +2,9 @@
/*
* Copyright (C) 2018 IBM Corporation
*/
-#include <linux/efi.h>
#include <linux/module.h>
#include <linux/ima.h>
-#include <asm/efi.h>
-
-#ifndef arch_ima_efi_boot_mode
-#define arch_ima_efi_boot_mode efi_secureboot_mode_unset
-#endif
-
-static enum efi_secureboot_mode get_sb_mode(void)
-{
- enum efi_secureboot_mode mode;
-
- if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) {
- pr_info("ima: secureboot mode unknown, no efi\n");
- return efi_secureboot_mode_unknown;
- }
-
- mode = efi_get_secureboot_mode(efi.get_variable);
- if (mode == efi_secureboot_mode_disabled)
- pr_info("ima: secureboot mode disabled\n");
- else if (mode == efi_secureboot_mode_unknown)
- pr_info("ima: secureboot mode unknown\n");
- else
- pr_info("ima: secureboot mode enabled\n");
- return mode;
-}
-
-bool arch_ima_get_secureboot(void)
-{
- static enum efi_secureboot_mode sb_mode;
- static bool initialized;
-
- if (!initialized && efi_enabled(EFI_BOOT)) {
- sb_mode = arch_ima_efi_boot_mode;
-
- if (sb_mode == efi_secureboot_mode_unset)
- sb_mode = get_sb_mode();
- initialized = true;
- }
-
- if (sb_mode == efi_secureboot_mode_enabled)
- return true;
- else
- return false;
-}
+#include <linux/secure_boot.h>
/* secureboot arch rules */
static const char * const sb_arch_rules[] = {
@@ -67,7 +24,7 @@ static const char * const sb_arch_rules[] = {
const char * const *arch_get_ima_policy(void)
{
- if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot()) {
+ if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_get_secureboot()) {
if (IS_ENABLED(CONFIG_MODULE_SIG))
set_module_sig_enforced();
if (IS_ENABLED(CONFIG_KEXEC_SIG))
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 5770cf691912..4aa8f0a20950 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -949,8 +949,7 @@ static int ima_load_data(enum kernel_load_data_id id, bool contents)
switch (id) {
case LOADING_KEXEC_IMAGE:
- if (IS_ENABLED(CONFIG_KEXEC_SIG)
- && arch_ima_get_secureboot()) {
+ if (IS_ENABLED(CONFIG_KEXEC_SIG) && arch_get_secureboot()) {
pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n");
return -EACCES;
}
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 7b388b66cf80..4636629533af 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/integrity.h>
+#include <linux/secure_boot.h>
#include <crypto/sha1.h>
#include <crypto/hash.h>
#include <linux/key.h>
diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
index d1fdd113450a..c0d6948446c3 100644
--- a/security/integrity/platform_certs/load_uefi.c
+++ b/security/integrity/platform_certs/load_uefi.c
@@ -212,7 +212,7 @@ static int __init load_uefi_certs(void)
}
/* the MOK/MOKx can not be trusted when secure boot is disabled */
- if (!arch_ima_get_secureboot())
+ if (!arch_get_secureboot())
return 0;
mokx = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &status);
diff --git a/security/integrity/secure_boot.c b/security/integrity/secure_boot.c
new file mode 100644
index 000000000000..fc2693c286f8
--- /dev/null
+++ b/security/integrity/secure_boot.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 Red Hat, Inc. All Rights Reserved.
+ *
+ * Author: Coiby Xu <coxu@redhat.com>
+ */
+#include <linux/secure_boot.h>
+
+/*
+ * Default weak implementation.
+ * Architectures that support secure boot must override this.
+ */
+__weak bool arch_get_secureboot(void)
+{
+ return false;
+}
--
2.53.0
^ permalink raw reply related
* [PATCH v3 2/3] evm: Don't enable fix mode when secure boot is enabled
From: Coiby Xu @ 2026-02-13 1:28 UTC (permalink / raw)
To: linux-integrity
Cc: Heiko Carstens, Alexander Egorenkov, Ard Biesheuvel, Dave Hansen,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn,
open list:SECURITY SUBSYSTEM, open list
In-Reply-To: <20260213012851.2532722-1-coxu@redhat.com>
Similar to IMA fix mode, forbid EVM fix mode when secure boot is
enabled.
Reported-and-suggested-by: Mimi Zohar <zohar@linux.ibm.com>
Suggested-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Coiby Xu <coxu@redhat.com>
---
security/integrity/evm/evm_main.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 73d500a375cb..a54cb73b51ee 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -72,17 +72,25 @@ static struct xattr_list evm_config_default_xattrnames[] = {
LIST_HEAD(evm_config_xattrnames);
+static char *evm_cmdline __initdata;
+core_param(evm, evm_cmdline, charp, 0);
+
static int evm_fixmode __ro_after_init;
-static int __init evm_set_fixmode(char *str)
+static void __init evm_set_fixmode(void)
{
- if (strncmp(str, "fix", 3) == 0)
- evm_fixmode = 1;
- else
- pr_err("invalid \"%s\" mode", str);
+ if (!evm_cmdline)
+ return;
- return 1;
+ if (strncmp(evm_cmdline, "fix", 3) == 0) {
+ if (arch_get_secureboot()) {
+ pr_info("Secure boot enabled: ignoring evm=fix");
+ return;
+ }
+ evm_fixmode = 1;
+ } else {
+ pr_err("invalid \"%s\" mode", evm_cmdline);
+ }
}
-__setup("evm=", evm_set_fixmode);
static void __init evm_init_config(void)
{
@@ -1119,6 +1127,8 @@ static int __init init_evm(void)
evm_init_config();
+ evm_set_fixmode();
+
error = integrity_init_keyring(INTEGRITY_KEYRING_EVM);
if (error)
goto error;
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] xfrm: kill xfrm_dev_{state,policy}_flush_secctx_check()
From: Steffen Klassert @ 2026-02-13 10:19 UTC (permalink / raw)
To: Tetsuo Handa
Cc: Paul Moore, SELinux, linux-security-module, Herbert Xu,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Network Development
In-Reply-To: <7c17884d-dbf1-4c2c-9813-0c5369cfdcc9@I-love.SAKURA.ne.jp>
On Mon, Feb 09, 2026 at 11:26:14PM +0900, Tetsuo Handa wrote:
> On 2026/02/09 20:22, Steffen Klassert wrote:
> > On Mon, Feb 09, 2026 at 07:02:47PM +0900, Tetsuo Handa wrote:
> >> On 2026/02/09 18:25, Steffen Klassert wrote:
> >>> The problem is that, with adding IPsec offloads to netdevices, security
> >>> critical resources came into the netdevices. Someone who has no
> >>> capabilities to delete xfrm states or xfrm policies should not be able
> >>> to unregister the netdevice if xfrm states or xfrm policies are
> >>> offloaded. Unfortunately, unregistering can't be canceled at this stage
> >>> anymore. So I think we need some netdevice unregistration hook for
> >>> the LSM subsystem so it can check for xfrm states or xfrm policies
> >>> and refuse the unregistration before we actually start to remove
> >>> the device.
> >>
> >> Unfortunately, unregistering is not always triggered by a user's request. ;-)
> >
> > As far as I remember, a security context is not always tied to a
> > user request. It can also be attached to system tasks or objects.
>
> That is not what I wanted to say. There are at least three routes (listed below)
> that can trigger xfrm_dev_unregister() path. You could insert LSM hooks into the
> netlink_sendmsg() route and the del_device_store() route, but the cleanup_net()
> route is a result of tear-down action which is too late to insert LSM hooks.
Yes, I know that.
> The NETDEV_UNREGISTER path can be triggered by just doing "unshare -n ip addr show"
> (i.e. implicit cleanup of a network namespace due to termination of init process in
> that namespace). We are not allowed to reject the cleanup_net() route.
And here we come to the other problem I mentioned. When a LSM policy
rejects to flush the xfrm states and policies on network namespace
exit, we leak all the xfrm states and policies in that namespace.
Here we have no other option, we must flush the xfrm states and
policies regardless of any LSM policy. This can be fixed with
something like that:
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 72678053bd69..8a4b2cbba0e0 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1822,9 +1822,11 @@ int xfrm_policy_flush(struct net *net, u8 type, bool task_valid)
spin_lock_bh(&net->xfrm.xfrm_policy_lock);
- err = xfrm_policy_flush_secctx_check(net, type, task_valid);
- if (err)
- goto out;
+ if (task_valid) {
+ err = xfrm_policy_flush_secctx_check(net, type, task_valid);
+ if (err)
+ goto out;
+ }
again:
list_for_each_entry(pol, &net->xfrm.policy_all, walk.all) {
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f2aef404b583..fd00f2d20425 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -923,9 +923,11 @@ int xfrm_state_flush(struct net *net, u8 proto, bool task_valid)
int i, err = 0, cnt = 0;
spin_lock_bh(&net->xfrm.xfrm_state_lock);
- err = xfrm_state_flush_secctx_check(net, proto, task_valid);
- if (err)
- goto out;
+ if (task_valid) {
+ err = xfrm_state_flush_secctx_check(net, proto, task_valid);
+ if (err)
+ goto out;
+ }
err = -ESRCH;
for (i = 0; i <= net->xfrm.state_hmask; i++) {
> >
> >> For example, we don't check permission for unmount when a mount is deleted
> >> due to teardown of a mount namespace. I wonder why you want to check permission
> >> for unregistering a net_device when triggered by a teardown path.
> >
> > I just try to find out what's the right thing to do here.
> > If a policy goes away, packets that match this policy will
> > find another path through the network stack. As best, they
> > are dropped somewhere, but they can also leave on some other
> > device without encryption. A LSM that implements xfrm hooks
> > must be able to check the permission to delete the xfrm policy
> > or state.
>
> Do you mean that calling xfrm_dev_down()/xfrm_dev_unregister() might
> result in network traffic to be sent in cleartext ?
Yes this can happen, but it is known. You can either install
a global block policy with low priority or use a LSM to
prevent this. The latter does not work unfortunately.
>
> If yes, we need to consider updating the other patch at
> https://lkml.kernel.org/r/20260202123655.GK34749@unreal to replace
> the NETDEV_UNREGISTER net_device with the blackhole_netdev. (That is,
> xfrm_dev_{state,policy}_flush() does not actually delete a state/policy
> but instead updates that state/policy to behave as a blackhole. Then,
> we won't need to call LSM hooks because we no longer delete).
I think there is a clean way to fix this. We could just unlink
policy and state from the device. Then we could do the same as
we do when a state becomes unavailable due to expiration. We mark
the state as invalid with a flag. On expiration we do this with
XFRM_STATE_EXPIRED. We can add a new flag and do the same as
xfrm_state_check_expire() does on a hard expire. I.e. fire
a timer that notifies the userspace key manager that this
path is not avalable anymore and return an error. This way
userspace is informed about that and all packets matching
the policy are dropped.
This is of course a bit more work and requires testing.
^ permalink raw reply related
* Re: [PATCH] xfrm: kill xfrm_dev_{state,policy}_flush_secctx_check()
From: Tetsuo Handa @ 2026-02-13 13:59 UTC (permalink / raw)
To: Steffen Klassert, Paul Moore, SELinux, linux-security-module
Cc: Herbert Xu, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Network Development
In-Reply-To: <aY76t_xYCHmLq6Ur@secunet.com>
On 2026/02/13 19:19, Steffen Klassert wrote:
On 2026/02/13 19:19, Steffen Klassert wrote:
>> The NETDEV_UNREGISTER path can be triggered by just doing "unshare -n ip addr show"
>> (i.e. implicit cleanup of a network namespace due to termination of init process in
>> that namespace). We are not allowed to reject the cleanup_net() route.
>
> And here we come to the other problem I mentioned. When a LSM policy
> rejects to flush the xfrm states and policies on network namespace
> exit, we leak all the xfrm states and policies in that namespace.
> Here we have no other option, we must flush the xfrm states and
> policies regardless of any LSM policy. This can be fixed with
> something like that:
This something is what I explained at
https://lkml.kernel.org/r/1bb453af-3ef2-4ab6-a909-0705bd07c136@I-love.SAKURA.ne.jp .
The "task_valid" argument does not always reflect whether LSM policy can reject or not.
Anyway, the patch to add xfrm_dev_unregister(dev) seems OK if we do like
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit?h=next-20260123&id=fc0f090e41e652d158f946c616cdd82baed3c8f4 ?
^ permalink raw reply
* Re: [PATCH v4 10/17] module: Move integrity checks into dedicated function
From: Nicolas Schier @ 2026-02-13 15:09 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Petr Pavlu,
Sami Tolvanen, Daniel Gomez, Paul Moore, James Morris,
Serge E. Hallyn, Jonathan Corbet, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Naveen N Rao, Mimi Zohar,
Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Bouchinet,
Xiu Jianfeng, Fabian Grünbichler, Arnout Engelen,
Mattia Rizzolo, kpcyrd, Christian Heusel, Câju Mihai-Drosi,
Sebastian Andrzej Siewior, linux-kbuild, linux-kernel, linux-arch,
linux-modules, linux-security-module, linux-doc, linuxppc-dev,
linux-integrity
In-Reply-To: <20260113-module-hashes-v4-10-0b932db9b56b@weissschuh.net>
On Tue, Jan 13, 2026 at 01:28:54PM +0100, Thomas Weißschuh wrote:
> With the addition of hash-based integrity checking, the configuration
> matrix is easier to represent in a dedicated function and with explicit
> usage of IS_ENABLED().
>
> Drop the now unnecessary stub for module_sig_check().
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> kernel/module/internal.h | 7 -------
> kernel/module/main.c | 18 ++++++++++++++----
> 2 files changed, 14 insertions(+), 11 deletions(-)
>
Reviewed-by: Nicolas Schier <nsc@kernel.org>
^ permalink raw reply
* Re: [PATCH v4 11/17] module: Move lockdown check into generic module loader
From: Nicolas Schier @ 2026-02-13 15:14 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Petr Pavlu,
Sami Tolvanen, Daniel Gomez, Paul Moore, James Morris,
Serge E. Hallyn, Jonathan Corbet, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Naveen N Rao, Mimi Zohar,
Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Bouchinet,
Xiu Jianfeng, Fabian Grünbichler, Arnout Engelen,
Mattia Rizzolo, kpcyrd, Christian Heusel, Câju Mihai-Drosi,
Sebastian Andrzej Siewior, linux-kbuild, linux-kernel, linux-arch,
linux-modules, linux-security-module, linux-doc, linuxppc-dev,
linux-integrity
In-Reply-To: <20260113-module-hashes-v4-11-0b932db9b56b@weissschuh.net>
On Tue, Jan 13, 2026 at 01:28:55PM +0100, Thomas Weißschuh wrote:
> The lockdown check buried in module_sig_check() will not compose well
> with the introduction of hash-based module validation.
> Move it into module_integrity_check() which will work better.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> kernel/module/main.c | 6 +++++-
> kernel/module/signing.c | 3 +--
> 2 files changed, 6 insertions(+), 3 deletions(-)
>
Reviewed-by: Nicolas Schier <nsc@kernel.org>
^ permalink raw reply
* Re: [PATCH v4 14/17] lockdown: Make the relationship to MODULE_SIG a dependency
From: Nicolas Schier @ 2026-02-13 15:32 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Nathan Chancellor, Arnd Bergmann, Luis Chamberlain, Petr Pavlu,
Sami Tolvanen, Daniel Gomez, Paul Moore, James Morris,
Serge E. Hallyn, Jonathan Corbet, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Naveen N Rao, Mimi Zohar,
Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Daniel Gomez,
Aaron Tomlin, Christophe Leroy (CS GROUP), Nicolas Bouchinet,
Xiu Jianfeng, Fabian Grünbichler, Arnout Engelen,
Mattia Rizzolo, kpcyrd, Christian Heusel, Câju Mihai-Drosi,
Sebastian Andrzej Siewior, linux-kbuild, linux-kernel, linux-arch,
linux-modules, linux-security-module, linux-doc, linuxppc-dev,
linux-integrity
In-Reply-To: <20260113-module-hashes-v4-14-0b932db9b56b@weissschuh.net>
On Tue, Jan 13, 2026 at 01:28:58PM +0100, Thomas Weißschuh wrote:
> The new hash-based module integrity checking will also be able to
> satisfy the requirements of lockdown.
> Such an alternative is not representable with "select", so use
> "depends on" instead.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> ---
> security/lockdown/Kconfig | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Nicolas Schier <nsc@kernel.org>
^ permalink raw reply
* [GIT PULL] capabilities update for v7.0
From: Serge E. Hallyn @ 2026-02-13 22:56 UTC (permalink / raw)
To: Linus Torvalds, Paul Moore, linux-security-module, linux-kernel
Cc: Ondrej Mosnacek, Ryan Foster
Hi Linus,
The following changes since commit 9ace4753a5202b02191d54e9fdf7f9e3d02b85eb:
Linux 6.19-rc4 (2026-01-04 14:41:55 -0800)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux.git tags/caps-pr-20260213
for you to fetch changes up to 071588136007482d70fd2667b827036bc60b1f8f:
ipc: don't audit capability check in ipc_permissions() (2026-01-27 21:30:42 -0600)
----------------------------------------------------------------
Capabilities update for 7.0
This branch contains two patches which have been in linux-next for a
few weeks. The first,
security: Add KUnit tests for kuid_root_in_ns and vfsuid_root_in_currentns
adds some tests of core capabilities helpers. The second
ipc: don't audit capability check in ipc_permissions()
avoids emitting audit messages when there's not actually a permission
being denied.
----------------------------------------------------------------
Ondrej Mosnacek (1):
ipc: don't audit capability check in ipc_permissions()
Ryan Foster (1):
security: Add KUnit tests for kuid_root_in_ns and vfsuid_root_in_currentns
MAINTAINERS | 1 +
include/linux/capability.h | 6 +
ipc/ipc_sysctl.c | 2 +-
security/Kconfig | 17 +++
security/commoncap.c | 4 +
security/commoncap_test.c | 288 +++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 317 insertions(+), 1 deletion(-)
create mode 100644 security/commoncap_test.c
^ permalink raw reply
* Re: [RFC PATCH v3 0/8] landlock: Add UDP access control support
From: Mickaël Salaün @ 2026-02-14 10:34 UTC (permalink / raw)
To: Matthieu Buffet, Paul Moore
Cc: Günther Noack, linux-security-module, Mikhail Ivanov,
konstantin.meskhidze, netdev, Tingmao Wang, Justin Suess
In-Reply-To: <20251212163704.142301-1-matthieu@buffet.re>
I had a chat with Matthieu and here is a summary of our discussion
(Matthieu, please complete if necessary):
First, this patch series is hight quality. The remaining issues are
related to the semantic and the capabilities of the enforced
restrictions.
1/ Simplify access rights
It would make more sense to have only two access rights, one to set the
source port and another to set the destination port. The source port is
should be handled by LANDLOCK_ACCESS_NET_BIND_UDP, but the destination
port is should also be handle by a unique access right, something like
LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP because it can be set with
connect(2) or sendmsg(2). Any suggestion for a better name?
2/ Autobind handling
If an UDP socket is not explicitly binded to a port, inet_autobind() is
called and provides an implicit port. In this case, the socket_bind
hook is not called and we cannot enforce any kind of restriction
(without relying on Netfilter like SELinux does).
The idea would be to lazily detect previous autobinds when one of the
socket_bind, socket_connect, socket_sendmsg, or socket_recvmsg hook is
called. This would mean to attach a Landlock security blob to all
sockets and store their state there. A better alternative would be to
only rely on the struct socket to infer this information, but we're not
sure if this is possible.
3/ AF_UNSPEC trick
As explained in patch 5/8, the network stack behaves differntly when
AF_UNSPEC is used with sendmsg(2) against an IPv4 or an IPv6 socket.
In a nutshell, because the LSM hook is not called while the socket is
locked, there is a possible race condition that Landlock needs to
handle to avoid policy bypass.
It's not clear yet what can be implemented safely but one new solution
would be to implement a socket_setsockopt hook to detect (potentially
concurrent) change of a socket type and store in a new Landlock socket
security blob the state of the socket (e.g. if it was IPv6 and it is now
IPv4). This would enables us to detect a malicious race condition while
allowing legitimate use cases.
When such deny would be triggered, Landlock should log that, probably
with a new dedicated blocker. One reason is because this should help
users to understand the issue (which should be very rare), and another
reason is because audit_log_lsm_data() currently ignores
LSM_AUDIT_DATA_NET records if the socket family is not AF_INET* nor
AF_UNIX.
Paul, not sure we'll need it now but, do you think it would be OK to add
a new case for LSM_AUDIT_DATA_NET to log the socket family for
AF_INET/AF_INET6/AF_UNIX and also for currently unhandled families?
Something like " family=%x" .
On Fri, Dec 12, 2025 at 05:36:56PM +0100, Matthieu Buffet wrote:
> Hi Mickaël, Günther, Mikhail, Konstantin,
>
> Here is v3 of UDP support for Landlock. My apologies for the delay, I've
> had to deal with unrelated problems. All feedback from v1/v2 should be
> merged, thanks again for taking the time to review them.
>
> I based these patches on linux-mic/next commit 1a3cedbdc156 ("landlock:
> Fix wrong type usage") plus my previous patch "landlock: Fix TCP
> handling of short AF_UNSPEC addresses" to avoid adding UDP with already
> known bugs, duplicated from TCP. I waited a bit to get feedback on that
> patch and no one yelled, so I hope it's acceptable, tell me if it's not.
> Link: https://lore.kernel.org/linux-security-module/20251027190726.626244-4-matthieu@buffet.re/
>
> Changes since v2
> ================
> Link: https://lore.kernel.org/all/20241214184540.3835222-1-matthieu@buffet.re/
> - removed support for sending datagrams with explicit destination
> address of family AF_UNSPEC, which allowed to bypass restrictions with
> a race condition
> - rebased on linux-mic/next => add support for auditing
> - fixed mistake in selftests when using unspec_srv variables, which were
> implicitly of type SOCK_STREAM and did not actually test UDP code
> - add tests for IPPROTO_IP
> - improved docs, split off TCP-related refactoring into another commit
>
> Changes since v1
> ================
> Link: https://lore.kernel.org/all/20240916122230.114800-1-matthieu@buffet.re/
> - recvmsg hook is gone and sendmsg hook doesn't apply to connected
> sockets anymore, to improve performance
> - don't add a get_addr_port() helper function, which required a weird
> "am I in IPv4 or IPv6 context" to avoid a addrlen > sizeof(struct
> sockaddr_in) check in connect(AF_UNSPEC) IPv6 context. A helper was
> useful when ports also needed to be read in a recvmsg() hook, now it
> is just a simple switch case in the sendmsg() hook, more readable
> - rename sendmsg access right to LANDLOCK_ACCESS_NET_UDP_SENDTO
> - reorder hook prologue for consistency: check domain, then type and
> family
> - add additional selftests cases around minimal address length
> - update documentation
>
> All important cases should have a selftest now. lcov gives me net.c
> going from 91.9% lines/82.5% branches to 93.4% lines/87% branches.
> Thank you for taking the time to read this!
>
> Closes: https://github.com/landlock-lsm/linux/issues/10
>
> Matthieu Buffet (8):
> landlock: Minor reword of docs for TCP access rights
> landlock: Refactor TCP socket type check
> landlock: Add UDP bind+connect access control
> selftests/landlock: Add UDP bind/connect tests
> landlock: Add UDP sendmsg access control
> selftests/landlock: Add tests for UDP sendmsg
> samples/landlock: Add sandboxer UDP access control
> landlock: Add documentation for UDP support
>
> Documentation/userspace-api/landlock.rst | 94 ++-
> include/uapi/linux/landlock.h | 46 +-
> samples/landlock/sandboxer.c | 58 +-
> security/landlock/audit.c | 3 +
> security/landlock/limits.h | 2 +-
> security/landlock/net.c | 119 +++-
> security/landlock/syscalls.c | 2 +-
> tools/testing/selftests/landlock/base_test.c | 2 +-
> tools/testing/selftests/landlock/net_test.c | 691 ++++++++++++++++---
> 9 files changed, 869 insertions(+), 148 deletions(-)
>
>
> base-commit: 1a3cedbdc156e100eb1a5208a8562a3265c35d87
> prerequisite-patch-id: 22051d5d4076a87481b22798c127ce84e219ca97
> prerequisite-patch-id: 37a1b44596a2d861ba91989edb1d7aac005931d6
> prerequisite-patch-id: c7be1c906699a2590ab7112cdf2ab6892178ec07
> --
> 2.47.3
>
>
^ permalink raw reply
* Re: [GIT PULL] capabilities update for v7.0
From: pr-tracker-bot @ 2026-02-14 20:54 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: Linus Torvalds, Paul Moore, linux-security-module, linux-kernel,
Ondrej Mosnacek, Ryan Foster
In-Reply-To: <aY+sOhXciC+Xerwo@mail.hallyn.com>
The pull request you sent on Fri, 13 Feb 2026 16:56:58 -0600:
> https://git.kernel.org/pub/scm/linux/kernel/git/sergeh/linux.git tags/caps-pr-20260213
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/6179d7a630c2747e2a9329149de2a7aa67a95978
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [RFC PATCH 0/9] Landlock supervise: a mechanism for interactive permission requests
From: Tingmao Wang @ 2026-02-15 2:41 UTC (permalink / raw)
To: Tetsuo Handa
Cc: Mickaël Salaün, Günther Noack, Justin Suess,
linux-security-module
In-Reply-To: <898462aa-8e5e-47ed-9a76-69e4acfbab07@I-love.SAKURA.ne.jp>
On 3/24/25 10:43, Tetsuo Handa wrote:
> Hello.
>
> On 2025/03/24 10:58, Tingmao Wang wrote:
>> Hi Tetsuo,
>>
>> Thanks for commenting on this RFC and thanks for mentioning TOMOYO - I wasn't
>> aware that another LSM has a similar permission prompting mechanism already
>> (and in fact, I only recently found out AppArmor / Ubuntu has also built
>> something like this [1], although AFAIK it's not upstream'd to mainland Linux,
>> and the current implementation may be somewhat coupled with Snap?), and this
>> is valuable and interesting for me to know :)
>
> I mentioned TOMOYO as an example of how to implement a supervisor feature, for
> there is a pitfall when involving userspace. What is important for implementing
> a supervisor feature is how to avoid deadlocks, for userspace might unexpectedly
> pause due to page fault events. If the supervisor process is blocked due to a
> page fault event, the process which is requesting some access is also blocked.
>
> [...]
>
> For landlock, I guess you assume that the supervisor process is not blocked
> (because landlock is intended for subset of userspace processes), but what if
> the supervisor process tries something that will be blocked by landlock
> (e.g. spawning a userspace program in landlock-controlled environment) ?
> Is there a guarantee that the supervisor process can never request something
> that will be blocked by landlock itself (or other security modules that are
> active) ?
Thanks for raising this and apologies that I missed to reply at the time.
I'm revisiting the supervisor series and these are good points.
For page fault events specifically, I don't think Landlock controls
anything involved in the reading back or writeout of pages (file accesses
are granted or denied at open() time, and as far as I'm aware, page faults
cannot _naturally_ lead to creation of new files or re-opening files), and
so if a supervisor is blocked on a page fault, my claim is that it will
never be due to Landlock itself (And I think perhaps the same is true for
TOMOYO as well - it doesn't look like TOMOYO has any access rights that
can directly be in the path of anything a page fault would need to do
either). One can presumably set up a situation where, for example, a page
fault in a Landlock supervisor results in a userfaultfd event that needs
to, for some reason, be handled by a process confined by that supervisor,
but this seems unlikely.
Also, for Landlock, the supervisor can only control its "descendants" (but
there is some edge case here - see below). If a supervisor gets blocked
in Landlock, it will be some parent supervisor above it that needs to
respond, so usually there can't actually be a deadlock from waiting on
Landlock requests (Landlock domains form a tree).
However, if for some reason the supervisor tries to landlock_restrict_self()
itself (i.e. not within a fork), passing in a Landlock ruleset with itself
being the supervisor, such deadlock can happen. We should probably
disallow landlock_restrict_self() with a process being its own supervisor,
as it doesn't make much sense, doesn't provide security, and can lead to
deadlocks like you mentioned.
Another thing that might happen is if a Landlock supervisor is blocked in
some other LSM (such as TOMOYO), and that LSM requires a reply from a
child process of that supervisor, and that child is blocked in Landlock
waiting for the original supervisor to respond. I don't have a solution
for this, but this also seems like an unlikely situation that will just
require manual intervention (e.g. killing the supervisor process, which
will then deny the Landlock access request in the child, unblocking it).
Kind regards,
Tingmao
^ permalink raw reply
* [RFC] Landlock: mutable domains (and supervisor notification uAPI options)
From: Tingmao Wang @ 2026-02-15 2:54 UTC (permalink / raw)
To: Günther Noack, Mickaël Salaün
Cc: Justin Suess, Amir Goldstein, Jan Kara, Song Liu, Tetsuo Handa,
Jann Horn, linux-security-module
Hi,
Recently I have been continuing work on the previously proposed Landlock
supervise feature (context below). While I do have some rough PoCs, and
I'm aware that sometimes code is better than talk, because of the amount
of work involved, I would like to get some early feedback on the design
before continuing.
Scrappy demo (just 2-3 min screencasts):
- user-space implemented "permissive mode":
https://fileshare.maowtm.org/landlock-20260214/demo.mp4
- mutable domains based on a reloadable config file:
https://fileshare.maowtm.org/landlock-20260213/demo.mp4
While I would be glad to receive reviews from anyone (and I've added
people who have replied to the previous RFC in CC), Günther, when you are
not too busy, can you kindly give this a review? A lot of this has
already been discussed with Mickaël, in fact a large part of this design
was from his suggestions. I apologize in advance for the length of this
email - please feel free to respond to any part of it, and whenever you
have time to.
PoC code used in the above videos are largely generated, somewhat buggy,
and unreviewed, but they are available:
- mutable domains:
https://github.com/micromaomao/linux-dev/pull/26/changes
- supervisor notification:
https://github.com/micromaomao/linux-dev/pull/27/changes
The motivations listed in [1] are still relevant, and to add to that, here
are some additional examples of things we can do with the supervisor
feature (all from unprivileged applications):
- Implementing a version of StemJail [2] which does not rely on bind
mounts and LD_PRELOAD (for the notification part, not for access
control). Or in fact, any other uses of LD_PRELOAD for the purpose of
finding out what files are accessed.
- For island [3], some sort of denial logging tied to the context,
integrated in the tool itself (rather than through kernel audit) and
live config reload.
- Use in a non-security related context, such as automated build
dependency tracking.
[1]: https://lore.kernel.org/all/cover.1741047969.git.m@maowtm.org/
[2]: https://github.com/stemjail/stemjail
[3]: https://github.com/landlock-lsm/island
Background
----------
A while ago I sent a "Landlock supervise" RFC patch series [1], in which I
proposed to extend Landlock with additional functionality to support
"interactive" rule enforcement. In discussion with Mickaël, we decided to
split this work into 3 stages: quiet flag, mutable domains, and finally
supervisor notification. Relevant discussions are at [4] and in replies
to [1].
The patch for quiet flag [5] has gone through multiple review iterations
already. It is useful on its own, but it was also motivated by the
eventual use in controlling supervisor notification.
The next stage is to introduce "mutable domains". The motivation for this
is two fold:
1. This allows the supervisor to allow access to (large) file hierarchies
without needing to be woken up again for each access.
2. Because we cannot block within security_path_mknod and other
directory-modification related hooks [6], the proposal was to return
immediately from those hooks after queuing the supervisor notification,
then wait in a separate task_work. This however means that we cannot
directly "allow" access (and even if we can, it may introduce TOCTOU
problems). In order to allow access to requested files, the supervisor
has to add additional rules to the (now mutable) domain which will
allow the required access.
[1]: https://lore.kernel.org/all/cover.1741047969.git.m@maowtm.org/
[4]: https://github.com/landlock-lsm/linux/issues/44
[5]: https://lore.kernel.org/all/cover.1766330134.git.m@maowtm.org/
[6]: https://lore.kernel.org/all/20250311.Ti7bi9ahshuu@digikod.net/
Proposed changes
----------------
This patchset introduces the concept of "supervisor" and "supervisee"
rulesets (alternative names for this are "static"/"dynamic",
"mutable"/"immutable" etc), which are Landlock rulesets that are joined
together when enforced. The supervisee ruleset can be thought of as the
"static" part of a domain, and the supervisor ruleset can be thought of as
the "dynamic" part. The two rulesets can have different rules and access
rights for individual rules, but they internally have the same sets of
handled access and scope bits. When an access request is evaluated for
processes in such domains, the access is allowed if, for each layer,
either the supervisee or the supervisor ruleset of that domain allows the
access.
A Landlock supervisor will first create the supervisor ruleset, which
internally creates a ref-counted landlock_supervisor which the unmerged
(and in fact, unmergeable, to prevent accidental misuse) landlock_ruleset
will point to. Through a new ioctl, the user can get a supervisee ruleset
with the attached supervisor (this relationship does not necessarily have
to be 1-1), which can then be passed to landlock_restrict_self() by a
child process. The supervisor can also at any time (before the ioctl,
before the landlock_restrict_self() call, or after it) modify the
supervisor ruleset to add or remove (via a new "intersect" flag) rules or
change access rights, and commit those changes through a flag passed to
landlock_add_rule() (although maybe this would be better done as an
ioctl() on the supervisor?), after which the changes start affecting the
child.
The supervisee ruleset is immutable, it is basically the current
landlock_ruleset, and internally we continue to "fold" rules from parents
into the child's rbtree. However, since all ancestor supervisor rulesets
are mutable, we cannot simply fold the supervisor rules from parents into
its children at enforce time, as it may be removed or changed later at a
parent layer. Therefore, if an access is not allowed by any layer's
supervisee ruleset (which is quick to check thanks to the "folding" of the
supervisee rules), Landlock will then have to check that the access is
allowed by the supervisor rulesets of all the denying layers. (The access
is also denied if any of the denying layers does not have a supervisor
ruleset, in this case we don't even have to check the other supervisor
rulesets.)
To enable removing rules from a ruleset, we also implement the
LANDLOCK_ADD_RULE_INTERSECT flag for landlock_add_rule(). If this is
passed, instead of adding rules, the corresponding rule, if it exists, is
updated to be the intersection of the existing access rights and the
specified access rights. If the result is zero, the rule is removed. For
API consistency, the LANDLOCK_ADD_RULE_INTERSECT flag will be supported
for both supervisor and supervisee (i.e. existing) rulesets, but it is
probably only useful for supervisor rulesets.
(I'm not very certain about this intersect flag - see below for
alternative designs)
Later on, a supervisor notification mechanism can be implemented to allow
the supervisor to be notified when an access is denied by its supervised
layer, but this is not in scope for the "mutable domains" feature on its
own (although it does make it significantly more useful). This will be
the step after mutable domains, if we keep with the plan previously
discussed with Mickaël.
uAPI example
------------
```c
/*
* This landlock_ruleset_attr controls the handled/quiet/scope bits for
* this layer (internally shared by both the supervisor and supervisee
* rulesets).
*/
struct landlock_ruleset_attr attr = {
.handled_access_fs = ...,
/* ... */
};
/* supervisor_fd default to CLOEXEC */
int supervisor_fd = landlock_create_ruleset(
&attr, sizeof(attr), LANDLOCK_CREATE_RULESET_SUPERVISOR);
if (supervisor_fd < 0)
perror("landlock_create_ruleset");
/*
* supervisor_fd can then be passed to landlock_add_rule, but it does not
* work with landlock_restrict_self. Not working for restrict_self means
* that if a sandboxer accidentally passes the supervisor fd to the child,
* it would not work in the same way as the supervisee fd, and therefore
* the error is more discoverable.
*/
if (landlock_add_rule(supervisor_fd, ...) < 0)
perror("landlock_add_rule");
/*
* Any changes to the supervisor ruleset must be committed, even before
* any child calls landlock_restrict_self(). Without committing, the
* supervisor ruleset still behaves as if it is empty.
*/
if (landlock_add_rule(supervisor_fd, ..., ...,
LANDLOCK_ADD_RULE_COMMIT_SUPERVISOR) < 0)
perror("landlock_add_rule(COMMIT)");
/* Creates the supervisee ruleset */
int supervisee_fd = ioctl(supervisor_fd,
LANDLOCK_IOCTL_GET_SUPERVISEE_RULESET, /* flags= */ 0);
if (supervisee_fd < 0)
perror("ioctl(LANDLOCK_IOCTL_GET_SUPERVISEE_RULESET)");
pid_t child = fork();
if (child == 0) {
/* The supervisor should not leak supervisor_fd to any untrusted code. */
close(supervisor_fd);
if (landlock_restrict_self(supervisee_fd, 0) < 0)
perror("landlock_restrict_self");
execve(...);
perror("execve");
} else {
close(supervisee_fd);
/*
* Here, the supervisor can add rules via landlock_add_rule(), Or
* remove rules via landlock_add_rule() with
* LANDLOCK_ADD_RULE_INTERSECT.
*
* Added rules doesn't come into effect until a final
* landlock_add_rule() with commit flag (which may also just add a
* dummy rule with access=0):
*/
if (landlock_add_rule(supervisor_fd, ..., ..., LANDLOCK_ADD_RULE_COMMIT_SUPERVISOR) < 0)
perror("landlock_add_rule(COMMIT)");
}
```
Discussion on LANDLOCK_ADD_RULE_INTERSECT
-----------------------------------------
This was initially proposed by Mickaël, although now after writing some
example code against it [7], I'm not 100% sure that it is the most useful
uAPI. For a supervisor based on some sort of config file, it already has
to track which rules are added to know what to remove, and thus I feel
that it would be easier (both to use and to implement) to have an API that
simply "replaces" a rule, rather than do a bitwise AND on the access.
Another alternative is to simply have a "clear all rules in this ruleset"
flag. This allows the supervisor to not have to track what is already
allowed - if it reloads the config file, it can simply clear the ruleset,
re-add all rules based on the config, then commit it. Although I worry
that this might make implementing some other use cases more difficult.
(We can of course implement both)
[7]: https://github.com/micromaomao/linux-dev/blob/94477974c616126762f24cc268967d7f989cc96d/samples/landlock/supervisor_sandboxer.c#L437-L481
Why require a commit operation?
-------------------------------
This is not a strictly necessary requirement with an rbtree based
implementation - it can be made thread-safe with RCU while still allowing
lockless access checks without too much overhead (although the code is
indeed more tricky to write). However, there is a possibility that the
domain lookup might become a hashtable with some future enhancement [8],
at which point it would be better to have an explicit commit operation to
avoid rebuilding the hashtable for every landlock_add_rule(). Having a
commit operation will likely also make some atomicity properties easier to
achieve, depending on the supervisor's needs.
I've actually previously implemented hashtable domains [9], but after
benchmarking it I did not find a very significant performance improvement
(2.2% with 10 dir depth and 10 rules, 8.6% with 29 depth and 1000 rules) [10]
especially considering the complexity of the changes required. After
discussion with Mickaël I've decided to not pursue it for now, but I'm
open to suggestions. If Mickaël and Günther are open to taking it, I can
revive the patch.
[8]: https://github.com/landlock-lsm/linux/issues/1
[9]: https://lore.kernel.org/all/cover.1751814658.git.m@maowtm.org/
Note that the benchmark posted here was inaccurate, due to the
relatively high cost of kfunc probes compared to the work required
to handle one openat(). For a more proper benchmark, refer to the
comment below:
[10]: https://github.com/landlock-lsm/landlock-test-tools/pull/17#issuecomment-3594121269
See specifically the collapsed section "parse-microbench.py
base-vm.log arraydomain-vm.log"
Proposed implementation
-----------------------
In order to store additional data and locks for the supervisor, we create
a new `struct landlock_supervisor`. Both the supervisor and supervisee
rulesets, and the landlock_hierarchy of each layer, will point to this
struct. (A future revision may optimize on this to reduce pointer chasing
when needing to check supervisor rulesets of parent layers.)
One of the main tricky areas of this work is the implementation of
LANDLOCK_ADD_RULE_COMMIT_SUPERVISOR and the access checks. We want:
- atomic commit: the supervised program should not "experience" any rule
changes until they are committed, and once it is committed it should see
all the changes together
- lockless access checks (even when the supervisee ruleset does not allow
the access, necessitating checking the supervisor rulesets, this should
still not involve any locks)
- atomic access checks: an access check should either be completely based
on the "old" rules or the "new" rules, even if a commit happens in the
middle of a path walk. This prevents incorrect denials when a commit
moves a rule from /a to /a/b when we've just finished checking /a/b and
about to check /a.
In order to achieve atomic commit, the supervisor fd cannot actually point
to (and thus allow editing) the "live" ruleset. Instead, when a
`LANDLOCK_ADD_RULE_COMMIT_SUPERVISOR` is requested, a new `struct
landlock_ruleset` is created, the rules are copied over from the existing
supervisor ruleset, and the pointer in the landlock_supervisor is swapped.
In order to keep access checks lockless (as it is currently), the live
ruleset pointer needs to be RCU-protected. To reduce complexity, this
initial implementation uses synchronize_rcu() directly in the calling
thread of `LANDLOCK_ADD_RULE_COMMIT_SUPERVISOR`, and frees the old
supervisor ruleset afterwards, but this can be rewritten to use call_rcu()
in a future iteration if necessary (which will allow quicker commits,
which can be quite impactful if we use this to auto-generate rulesets).
During access checks, for each step of the path walk, after
landlock_unmask_layers()-ing the supervisee rule, if the access is not
already allowed, we check for rules in the supervisor ruleset and
effectively does landlock_unmask_layers() on them too.
In order to have atomic access checks, we need to pre-capture the
supervisor committed ruleset pointers for all layers at the start of the
path walk (in `is_access_to_paths_allowed`). Storing this on the stack,
this takes the space of 16 pointers, hence 128 bytes on 64-bit (I'm keen
to hear suggestions on how best to mitigate this). Another effect of this
"caching" is that in order to be able to release rcu in the path walk
(which is required for the path_put()), we actually need to take refcount
on the committed ruleset (and free it at the end of
is_access_to_paths_allowed).
Optional accesses
-----------------
Optional access (truncate and ioctl) handling is also tricky. There are
two possible alternatives:
- The allowed optional actions are still entirely determined at file open
time. This likely works in the majority of cases, where truncate (and
maybe also ioctl) are given or taken away together with write access.
However, this may mean that we need to send an access request
notification immediately at open() time if e.g. write access is given
but truncate (or ioctl) is not, even if truncate (or ioctl) is not
attempted yet, since the supervisor would not be able to allow it later.
(or alternatively we can choose to not send this notification, and the
supervisor will just have to "know" to add truncate/ioctl rights if
required, in advance.)
- The allowed optional actions are considered to be determined at
operation time (even though for a static ruleset it is cached). This
means that for supervised layers, we will always have to re-check their
supervisor rulesets, whether or not the access was initially allowed,
which will involve doing a path walk. This does however means that the
supervisor can be notified "in the moment" when a truncate (or more
likely to be relevant - ioctl) is attempted.
The PoC partially implements the second one (but has bugs), but I'm not
sure which is best. The second one is most flexible and makes more sense
to me from a user perspective, but does come with performance
implications.
(Disallowing) self-supervision
------------------------------
We should figure out a way to ensure that a process cannot call
landlock_restrict_self() with a ruleset that has a supervisor for which it
has access to (i.e. via a supervisor ruleset fd). This prevents
accidental misuse, and also prevents deadlocks as discussed in [11]. I'm
not sure if this will be easy to implement, however.
[11]: https://lore.kernel.org/all/cc3e131f-f9a3-417b-9267-907b45083dc3@maowtm.org/
Supervisor notification
-----------------------
The above RFC only covers mutable domains. The natural next stage of this
work is to send notification to the supervisor on access denials, so that
it can decide whether to allow the access or not. For that, there are
also lots of questions at this stage:
- Should we in fact implement that first, before mutable domains? This
means that the supervisor would only be able to find out about denials,
but not allow them without a sandbox restart. We still eventually want
the mutable domains, since that makes this a lot more useful, but I can
see some use cases for just the notification part (e.g. island denial
log), and I can't see a likely use case for just mutable domains, aside
from live reload of landlock-config (maybe that _is_ useful on its own,
considering that you can also find out about denials from the kernel
audit log, and add missing rules based on that).
- Earlier when implementing the Landlock supervise v1 RFC, I basically
came up with an ad-hoc uAPI for the notification [12], and the PoC code
linked to above also uses this uAPI. There are of course many problems
with this as it stands, e.g. it only having one destname, which means
that for rename, the fd1 needs to be the child being moved, which does
not align with the vfs semantic and how Landlock treat it (i.e. the
thing being updated here is the parent directory, not the child itself).
Same for delete, which currently sends the child as fd1.
But also, in discussion with Mickaël last year, he mentioned that we
could reuse the fsnotify infrastructure, and perhaps additionally, use
fanotify to deliver these notifications. I do think there is some
potential here, as fanotify already implements an event header, a
mechanism for receiving and replying to events, etc. We could possibly
extend it to send Landlock specific notifications via a new kind of mark
(FAN_MARK_LANDLOCK_DOMAIN ??) and add one or more new corresponding
event types. Mickaël mentioned mount notifications [13] as an example
of using fanotify to send notifications other than file/dir
modifications.
I'm not sure if directly extending the fanotify uAPI is a good idea tho,
considering that Landlock is not a feature specific to the filesystem -
we will also have denial events for net_port rules, and perhaps more in
the future. However, Mickaël mentioned that there might be some
internal infrastructure which we can re-use (even if we have our own
notification uAPI).
- The other uAPI alternative which I have been thinking of is to extend
seccomp-unotify. For example, a Landlock denial could result in the
syscall being trapped and a `struct seccomp_notif` being sent to the
seccomp supervisor (via the existing mechanism), with additional
information (mostly, the file(s) / net ports being accessed and access
rights requested) attached to the notification _somehow_. Then the
supervisor can use the same kind of responses one would use for
seccomp-unotify to cause the syscall to either be retried (possibly via
`SECCOMP_USER_NOTIF_FLAG_CONTINUE`) or return with an error code of its
choice (or alternatively, carry out the operation on behalf of the
child, and pretend that the syscall succeed, which might be useful to
implement an "allow file creation but only this file" / "allow `mktemp
-d` but not arbitrary create on anything under /tmp").
Looking at `struct seccomp_notif` and `struct seccomp_data` however, I'm
not sure how feasible / doable this extension would be. Also,
seccomp-unotify is supposed to trigger before a syscall is actually
executed, whereas if we use it this way, we will want it to trigger
after we're already midway through the syscall (in the LSM hook). This
might make it hard to implement (and also twists a bit the uAPI
semantics of seccomp-unotify).
Are there any immediate reasons, from Landlock's perspective, to rule out
either of them? (I will probably wait for at least a first review from
the Landlock side before directing this explicitly to the fanotify and/or
seccomp-unotify maintainers, in case the plan significantly changes, but
if somehow a maintainer/reviewer from either of those areas are already
reading this, firstly thanks, and feedback would be very valuable :D )
[12]: https://lore.kernel.org/all/cde6bbf0b52710b33170f2787fdcb11538e40813.1741047969.git.m@maowtm.org/#iZ31include:uapi:linux:landlock.h
[13]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v6.15-rc1&id=fd101da676362aaa051b4f5d8a941bd308603041
^ permalink raw reply
* Re: [PATCH v4 4/6] landlock/selftests: Test named UNIX domain socket restrictions
From: Tingmao Wang @ 2026-02-15 3:01 UTC (permalink / raw)
To: Günther Noack
Cc: Mickaël Salaün, Justin Suess, linux-security-module
In-Reply-To: <20260209.Noh6thae5cho@digikod.net>
On 2/9/26 17:29, Mickaël Salaün wrote:
> On Mon, Feb 09, 2026 at 12:10:14AM +0100, Günther Noack wrote:
>> * Exercise the access right for connect() and sendmsg() on named UNIX
>> domain sockets, in various combinations of Landlock domains and
>> socket types.
>> * Extract common helpers from an existing IOCTL test that
>> also uses pathname unix(7) sockets.
>>
>> The tested combinations are the cross product of these sets of fixture
>> fields:
>>
>> * {{.handled=RESOLVE_UNIX},
>> {.handled=RESOLVE_UNIX, .allowed=RESOLVE_UNIX}}
>> * {{.sock_type=SOCK_STREAM},
>> {.sock_type=SOCK_DGRAM},
>> {.sock_type=SOCK_DGRAM, .use_sendto=true},
>> {.sock_type=SOCK_SEQPACKET}}
>> * {{.server_in_same_domain=false},
>> {.server_in_same_domain=true}}
>
> It would improve test clarity to follow the same approach as Tingmao to
> check the scope, especially to use the scoped_base_variant.h:
> https://lore.kernel.org/all/88de5bed60b06ba97088d87803f7bb3dbcc9a808.1767115163.git.m@maowtm.org/
> Even if there is no more explicit scoped flag anymore, this test suite
> is still relevant.
>
> The fs_test.c part would then mostly check the
> LANDLOCK_ACCESS_FS_RESOLVE_UNIX rules/exceptions.
>
Günther, if you have not already started working on this but agrees with
the suggestion here, I'm happy to take a stab at rebasing the relevant
selftests patches in the scope series to test this new series.
Kind regards,
Tingmao
^ permalink raw reply
* [PATCH v5 0/9] landlock: UNIX connect() control by pathname and scope
From: Günther Noack @ 2026-02-15 10:51 UTC (permalink / raw)
To: Mickaël Salaün, John Johansen, Paul Moore, James Morris,
Serge E . Hallyn
Cc: Günther Noack, linux-security-module, Tingmao Wang,
Justin Suess, Samasth Norway Ananda, Matthieu Buffet,
Mikhail Ivanov, konstantin.meskhidze, Demi Marie Obenour,
Alyssa Ross, Jann Horn, Tahera Fahimi, Simon Horman, netdev,
Alexander Viro, Christian Brauner
Hello!
This patch set introduces a filesystem-based Landlock restriction
mechanism for connecting to UNIX domain sockets (or addressing them
with sendmsg(2)). It introduces the filesystem access right
LANDLOCK_ACCESS_FS_RESOLVE_UNIX.
For the connection-oriented SOCK_STREAM and SOCK_SEQPACKET type
sockets, the access right makes the connect(2) operation fail with
EACCES, if denied.
SOCK_DGRAM-type UNIX sockets can be used both with connect(2), or by
passing an explicit recipient address with every sendmsg(2)
invocation. In the latter case, the Landlock check is done when an
explicit recipient address is passed to sendmsg(2) and can make
sendmsg(2) return EACCES. When UNIX datagram sockets are connected
with connect(2), a fixed recipient address is associated with the
socket and the check happens during connect(2) and may return EACCES.
When LANDLOCK_ACCESS_FS_RESOLVE_UNIX is handled within a Landlock
domain, this domain will only allow connect(2) and sendmsg(2) to
server sockets that were created within the same domain. Or, to
phrase it the other way around: Unless it is allow-listed with a
LANDLOCK_PATH_BENEATH rule, the newly created domain denies connect(2)
and sendmsg(2) actions that are directed *outwards* of that domain.
In that regard, LANDLOCK_ACCESS_FS_RESOLVE_UNIX has the same semantics
as one of the "scoped" access rights.
== Motivation
Currently, landlocked processes can connect to named UNIX sockets
through the BSD socket API described in unix(7), by invoking socket(2)
followed by connect(2) with a suitable struct sockname_un holding the
socket's filename. This is a surprising gap in Landlock's sandboxing
capabilities for users (e.g. in [1]) and it can be used to escape a
sandbox when a Unix service offers command execution (various such
scenarios were listed by Tingmao Wang in [2]).
The original feature request is at [4].
== Alternatives and Related Work
=== Alternative: Use existing LSM hooks
We have carefully and seriously considered the use of existing LSM
hooks, but still came to the conclusion that a new LSM hook is better
suited in this case:
The existing hooks security_unix_stream_connect(),
security_unix_may_send() and security_socket_connect() do not give
access to the resolved filesystem path.
* Resolving the filesystem path in the struct sockaddr_un again within
a Landlock would produce a TOCTOU race, so this is not an option.
* We would therefore need to wire through the resolved struct path
from unix_find_bsd() to one of the existing LSM hooks which get
called later. This would be a more substantial change to af_unix.c.
The struct path that is available in the listening-side struct sock is
can be read through the existing hooks, but it is not an option to use
this information: As the listening socket may have been bound from
within a different namespace, the path that was used for that can is
in the general case not meaningful for a sandboxed process. In
particular, it is not possible to use this path (or prefixes thereof)
when constructing a sandbox policy in the client-side process.
Paul Moore also chimed in in support of adding a new hook, with the
rationale that the simplest change to the LSM hook interface has
traditionally proven to be the most robust. [11]
More details are on the Github issue at [6] and on the LKML at [9].
In a the discussion of the V2 review, started by Christian Brauner
[10], we have further explored the approach of reusing the existing
LSM hooks but still ended up leaning on the side of introducing a new
hook, with Paul Moore and me (gnoack) arguing for that option.
Further insights about the LSM hook were shared in the V3 review by
Tingmao Wang [12], who spotted additional requirements due to the two
approaches being merged into one patch set. The summary of that
discussion is in [13].
=== Related work: Scope Control for Pathname Unix Sockets
The motivation for this patch is the same as in Tingmao Wang's patch
set for "scoped" control for pathname Unix sockets [2], originally
proposed in the Github feature request [5].
In [14], we have settled on the decision to merge the two patch sets
into this one, whose primary way of controlling connect(2) is
LANDLOCK_ACCESS_FS_RESOLVE_UNIX, but where this flag additionally has
the semantics of only restricting this unix(7) IPC *outwards* of the
created Landlock domain, in line with the logic that exists for the
existing "scoped" flags already.
By having LANDLOCK_ACCESS_FS_RESOLVE_UNIX implement "scoping"
semantics, we can avoid introducing two separate interacting flags for
now, but we retain the option of introducing
LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET at a later point in time, should
such a flag be needed to express additional rules.
== Credits
The feature was originally suggested by Jann Horn in [7].
Tingmao Wang and Demi Marie Obenour have taken the initiative to
revive this discussion again in [1], [4] and [5].
Tingmao Wang has sent the patch set for the scoped access control for
pathname Unix sockets [2] and has contributed substantial insights
during the code review, shaping the form of the LSM hook and agreeing
to merge the pathname and scoped-flag patch sets.
Justin Suess has sent the patch for the LSM hook in [8] and
subsequently through this patch set.
Christian Brauner and Paul Moore have contributed to the design of the
new LSM hook, discussing the tradeoffs in [10].
Ryan Sullivan has started on an initial implementation and has brought
up relevant discussion points on the Github issue at [4].
As maintainer of Landlock, Mickaël Salaün has done the main review so
far and particularly pointed out ways in which the UNIX connect()
patch sets interact with each other and what we need to look for with
regards to UAPI consistency as Landlock evolves.
[1] https://lore.kernel.org/landlock/515ff0f4-2ab3-46de-8d1e-5c66a93c6ede@gmail.com/
[2] Tingmao Wang's "Implement scope control for pathname Unix sockets"
https://lore.kernel.org/all/cover.1767115163.git.m@maowtm.org/
[3] https://lore.kernel.org/all/20251230.bcae69888454@gnoack.org/
[4] Github issue for FS-based control for named Unix sockets:
https://github.com/landlock-lsm/linux/issues/36
[5] Github issue for scope-based restriction of named Unix sockets:
https://github.com/landlock-lsm/linux/issues/51
[6] https://github.com/landlock-lsm/linux/issues/36#issuecomment-2950632277
[7] https://lore.kernel.org/linux-security-module/CAG48ez3NvVnonOqKH4oRwRqbSOLO0p9djBqgvxVwn6gtGQBPcw@mail.gmail.com/
[8] Patch for the LSM hook:
https://lore.kernel.org/all/20251231213314.2979118-1-utilityemal77@gmail.com/
[9] https://lore.kernel.org/all/20260108.64bd7391e1ae@gnoack.org/
[10] https://lore.kernel.org/all/20260113-kerngesund-etage-86de4a21da24@brauner/
[11] https://lore.kernel.org/all/CAHC9VhQHZCe0LMx4xzSo-h1SWY489U4frKYnxu4YVrcJN3x7nA@mail.gmail.com/
[12] https://lore.kernel.org/all/e6b6b069-384c-4c45-a56b-fa54b26bc72a@maowtm.org/
[13] https://lore.kernel.org/all/aYMenaSmBkAsFowd@google.com/
[14] https://lore.kernel.org/all/20260205.Kiech3gupee1@digikod.net/
---
== Patch set history
V1: https://lore.kernel.org/all/20260101134102.25938-1-gnoack3000@gmail.com/
V2: https://lore.kernel.org/all/20260110143300.71048-2-gnoack3000@gmail.com/
V3: https://lore.kernel.org/all/20260119203457.97676-2-gnoack3000@gmail.com/
V4: https://lore.kernel.org/all/20260208231017.114343-1-gnoack3000@gmail.com/
Changes in V5:
This change primarily adds tests, changing the testing approach for
the main test to use the scoped_domains fixture as in Tingmao's patch
set [2], and adding tests for the audit and coredump cases.
* Selftests:
* Replaced the main selftest with one based on scoped_domains
* Added audit test
* Added test for the coredump case
* Added a follow-up commit that simplifies ruleset enforcement
* Kernel code:
* Mark coredump check as unlikely (per Justin's review)
* Drop check for socket type (per Mickaël's review)
Changes in V4:
Since this version, this patch set subsumes the scoping semantics from
Tingmao Wang's "Scope Control" patch set [2], per discussion with
Tingmao Wang and Mickaël Salaün in [14] and in the thread leading up
to it.
Now, LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET only restricts connect(2) and
sendmsg(2) *outwards* of the domain where it is restricted, *with the
same semantics as a "scoped" flag*.
* Implement a layer-mask based version of domain_is_scoped():
unmask_scoped_access(). Rationale: domain_is_scoped() returns
early, which we can't do in the layer masks based variant. The two
variants are similar enough.
* LSM hook: Replace 'type' argument with 'sk' argument,
per discussion in [12] and [13].
* Bump ABI version to 9 (pessimistically assuming that we won't make
it for 7.0)
* Documentation fixes in header file and in Documentation/
* selftests: more test variants, now also parameterizing whether the
server socket gets created within the Landlock domain or before that
* selftests: use EXPECT_EQ() for test cleanup
Changes in V3:
* LSM hook: rename it to security_unix_find() (Justin Suess)
(resolving the previously open question about the LSM hook name)
Related discussions:
https://lore.kernel.org/all/20260112.Wufar9coosoo@digikod.net/
https://lore.kernel.org/all/CAHC9VhSRiHwLEWfFkQdPEwgB4AXKbXzw_+3u=9hPpvUTnu02Bg@mail.gmail.com/
* Reunite the three UNIX resolving access rights back into one
(resolving the previously open question about the access right
structuring) Related discussion:
https://lore.kernel.org/all/20260112.Wufar9coosoo@digikod.net/)
* Sample tool: Add new UNIX lookup access rights to ACCESS_FILE
Changes in V2:
* Send Justin Suess's LSM hook patch together with the Landlock
implementation
* LSM hook: Pass type and flags parameters to the hook, to make the
access right more generally usable across LSMs, per suggestion from
Paul Moore (Implemented by Justin)
* Split the access right into the three types of UNIX domain sockets:
SOCK_STREAM, SOCK_DGRAM and SOCK_SEQPACKET.
* selftests: More exhaustive tests.
* Removed a minor commit from V1 which adds a missing close(fd) to a
test (it is already in the mic-next branch)
Günther Noack (8):
landlock: Control pathname UNIX domain socket resolution by path
samples/landlock: Add support for named UNIX domain socket
restrictions
landlock/selftests: Test LANDLOCK_ACCESS_FS_RESOLVE_UNIX
landlock/selftests: Audit test for LANDLOCK_ACCESS_FS_RESOLVE_UNIX
landlock/selftests: Check that coredump sockets stay unrestricted
landlock/selftests: fs_test: Simplify ruleset creation and enforcement
landlock: Document FS access right for pathname UNIX sockets
landlock: Document design rationale for scoped access rights
Justin Suess (1):
lsm: Add LSM hook security_unix_find
Documentation/security/landlock.rst | 38 +
Documentation/userspace-api/landlock.rst | 16 +-
include/linux/lsm_hook_defs.h | 5 +
include/linux/security.h | 11 +
include/uapi/linux/landlock.h | 10 +
net/unix/af_unix.c | 8 +
samples/landlock/sandboxer.c | 15 +-
security/landlock/access.h | 11 +-
security/landlock/audit.c | 1 +
security/landlock/fs.c | 102 +-
security/landlock/limits.h | 2 +-
security/landlock/syscalls.c | 2 +-
security/security.c | 20 +
tools/testing/selftests/landlock/base_test.c | 2 +-
tools/testing/selftests/landlock/fs_test.c | 1301 ++++++++++--------
15 files changed, 942 insertions(+), 602 deletions(-)
--
2.52.0
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox