Linux Security Modules development
 help / color / mirror / Atom feed
* Re: [PATCH 04/11] treewide: Convert struct kernel_param_ops initializers to DEFINE_KERNEL_PARAM_OPS
From: jim.cromie @ 2026-06-10 21:06 UTC (permalink / raw)
  To: Petr Pavlu
  Cc: Kees Cook, Luis Chamberlain, Pengpeng Hou, Richard Weinberger,
	Anton Ivanov, Johannes Berg, Rafael J. Wysocki, Len Brown,
	Corey Minyard, Gabriel Somlo, Michael S. Tsirkin, Jani Nikula,
	Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, David Airlie,
	Simona Vetter, Bart Van Assche, Jason Gunthorpe, Leon Romanovsky,
	Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
	Bjorn Helgaas, Hannes Reinecke, James E.J. Bottomley,
	Martin K. Petersen, Daniel Lezcano, Zhang Rui, Lukasz Luba,
	Greg Kroah-Hartman, Jiri Slaby, Alan Stern, Jason Wang, Xuan Zhuo,
	Eugenio Pérez, Jason Baron, Tiwei Bie, Benjamin Berg,
	Ilpo Järvinen, David E. Box, Maciej W. Rozycki,
	Srinivas Pandruvada, Peter Zijlstra, Heiko Carstens,
	Vasily Gorbik, Sean Christopherson, Paolo Bonzini,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Vinod Koul, Frank Li, Daniel Gomez, Sami Tolvanen,
	Aaron Tomlin, Alexander Potapenko, Marco Elver, Dmitry Vyukov,
	Andrew Morton, John Johansen, Paul Moore, James Morris,
	Serge E. Hallyn, Andy Shevchenko, Georgia Garcia, kvm, dmaengine,
	linux-modules, kasan-dev, linux-mm, apparmor,
	linux-security-module, linux-um, linux-acpi, openipmi-developer,
	qemu-devel, intel-gfx, dri-devel, linux-rdma, linux-media,
	linux-pci, linux-scsi, linux-pm, linuxppc-dev, linux-serial,
	linux-usb, usb-storage, virtualization, linux-kernel, linux-arch,
	netdev, linux-fsdevel, linux-hardening
In-Reply-To: <da358ae1-91b4-4a16-ac76-ffab99c230b9@suse.com>

On Mon, May 25, 2026 at 7:35 AM Petr Pavlu <petr.pavlu@suse.com> wrote:
>
> On 5/21/26 3:33 PM, Kees Cook wrote:
> > Using Coccinelle, rewrite every struct kernel_param_ops initializer that
> > sets .get into a DEFINE_KERNEL_PARAM_OPS-family macro invocation,
> > for example:
> >
> > @@
> > declarer name DEFINE_KERNEL_PARAM_OPS;
> > identifier OPS;
> > expression SET, GET;
> > @@
> > - const struct kernel_param_ops OPS = {
> > -       .set = SET,
> > -       .get = GET,
> > - };
> > + DEFINE_KERNEL_PARAM_OPS(OPS, SET, GET);
> >
> > Using the macro for initialization means future changes can manipulate
> > the struct layout and callback prototypes without having to change every
> > initializer.
>
> Nit: For consistency, I suggest also converting the few remaining
> kernel_param_ops instances that specify only .set and no .get, such as
> simdisk_param_ops_filename.
>
> --
> Thanks,
> Petr

for the dynamic-debug changes

Reviewed-by: Jim Cromie <jim.cromie@gmail.com>

^ permalink raw reply

* Re: [PATCH] cred: prevent slab cache merging for cred_jar
From: Kees Cook @ 2026-06-10 20:45 UTC (permalink / raw)
  To: Mohammed EL Kadiri
  Cc: Paul Moore, Serge Hallyn, Vlastimil Babka, linux-security-module,
	linux-hardening, linux-kernel
In-Reply-To: <20260606142558.13809-1-med08elkadiri@gmail.com>

On Sat, Jun 06, 2026 at 03:25:58PM +0100, Mohammed EL Kadiri wrote:
> The cred_jar slab cache holds struct cred objects, which contain
> process credentials: uid, gid, euid, egid, and capability sets.
> Overwriting any of these fields is sufficient for privilege escalation.
> 
> On a default Ubuntu 6.17.0-23-generic system, cred_jar (named "cred"
> in sysfs) has 2 aliases, meaning 2 unrelated object types share its
> slab pages (object_size=184, objs_per_slab=42).
> 
> Cross-cache heap exploitation relies on slab cache merging to achieve
> type confusion between unrelated kernel objects. CVE-2022-29582
> demonstrates this technique: an io_uring use-after-free is leveraged
> across cache boundaries through page-level reallocation, ultimately
> achieving root. struct cred is a primary target in this class of
> attacks due to the direct privilege escalation that results from
> corrupting any of its identity or capability fields.
> 
> Add SLAB_NO_MERGE to ensure cred_jar receives dedicated slab pages,
> so that freed credential slots can only be reallocated as struct cred
> objects. The memory overhead is minimal: one struct cred exists per
> task, and with 42 objects per slab page, the cost of dedicated pages
> is negligible. There is zero performance impact on the allocation
> hot path.
> 
> This follows the precedent set by skbuff_head_cache (net/core/skbuff.c)
> and key_jar (security/keys/key.c) which use SLAB_NO_MERGE for similar
> isolation requirements.
> 
> Signed-off-by: Mohammed EL Kadiri <med08elkadiri@gmail.com>

Yes please. :)

Reviewed-by: Kees Cook <kees@kernel.org>

-- 
Kees Cook

^ permalink raw reply

* Re: [PATCH] hardening: Default randstruct off with rust for better allmodconfig support
From: Miguel Ojeda @ 2026-06-10 20:41 UTC (permalink / raw)
  To: Kees Cook
  Cc: Mark Brown, Gustavo A. R. Silva, Paul Moore, James Morris,
	Serge E. Hallyn, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, linux-hardening,
	linux-security-module, linux-kernel, rust-for-linux
In-Reply-To: <202606101335.648C6993@keescook>

On Wed, Jun 10, 2026 at 10:37 PM Kees Cook <kees@kernel.org> wrote:
>
> Can we instead just allow it? This has been ready to go for a while,
> IIUC:
> https://lore.kernel.org/all/CANiq72n=hgH4bqJjp8MsMHAaxaAo75GSBcHGTvFT3NTSaVPGWg@mail.gmail.com/

Mark sent a v2 where I mentioned that! :) Please see:

  https://lore.kernel.org/rust-for-linux/CANiq72mmzfBg0_y+TMTsUUuO0cJFE0=n60-ttwOynai06_y=zg@mail.gmail.com/

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH v2] hardening: Default randstruct off with rust for better allmodconfig support
From: Kees Cook @ 2026-06-10 20:41 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Mark Brown, Gustavo A. R. Silva, Paul Moore, James Morris,
	Serge E. Hallyn, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, linux-hardening,
	linux-security-module, linux-kernel, rust-for-linux
In-Reply-To: <CANiq72mmzfBg0_y+TMTsUUuO0cJFE0=n60-ttwOynai06_y=zg@mail.gmail.com>

On Fri, Jun 05, 2026 at 07:22:54PM +0200, Miguel Ojeda wrote:
> On Fri, Jun 5, 2026 at 6:51 PM Mark Brown <broonie@kernel.org> wrote:
> >
> > Currently randstruct does not support rust so we have Kconfig dependencies
> > which prevent rust being enabled when randstruct is. Unfortunately this
> > prevents rust being enabled in allmodconfig, our standard coverage build.
> > randstruct gets turned on by default, then the dependency on !RANDSTRUCT
> > causes rust to get disabled.
> >
> > Work around this by disabling randstruct by default if we have a usable
> > rust toolchain and rust support for the architecture, circular
> > dependencies prevent us directly depending on !RUST. This means we might
> > end up with a configuration that disables both rust and randstruct but
> > hopefully it's more likely go give the expected result.
> >
> > Signed-off-by: Mark Brown <broonie@kernel.org>
> 
> Thanks Mark!
> 
> Kees, Gustavo: applying this would help Mark's testing of Rust in
> linux-next, which is important to keep.
> 
> An alternative would be to move forward with `RANDSTRUCT` support:
> 
>   https://lore.kernel.org/rust-for-linux/20260323130224.165738-1-ojeda@kernel.org/
> 
> Either the conditional (on the Rust side) or the unconditional
> approaches (modifying the C side) should be fine, i.e. whatever
> Kees/Gustavo think is best. The unconditional one would make things
> easier on the Rust side, but it is a "bigger" change in terms of
> impact. We can always start with the conditional one instead.

Oops, I missed this v2. :)

For the linux-next testing, are you doing GCC + llvm rustc builds? IIUC,
then the support patch mentioned, I think, doesn't actually solve the
problem?

-Kees

-- 
Kees Cook

^ permalink raw reply

* Re: [PATCH] hardening: Default randstruct off with rust for better allmodconfig support
From: Kees Cook @ 2026-06-10 20:37 UTC (permalink / raw)
  To: Mark Brown
  Cc: Gustavo A. R. Silva, Paul Moore, James Morris, Serge E. Hallyn,
	Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, linux-hardening, linux-security-module,
	linux-kernel, rust-for-linux
In-Reply-To: <20260605-rust-reverse-randstruct-dep-v1-1-45ce9ee8d0d1@kernel.org>

On Fri, Jun 05, 2026 at 05:01:46PM +0100, Mark Brown wrote:
> Currently randstruct does not support rust so we have Kconfig dependencies
> which prevent rust being enabled when randstruct is. Unfortunately this
> prevents rust being enabled in allmodconfig, our standard coverage build.
> randstruct gets turned on by default, then the dependency on !RANDSTRUCT
> causes rust to get disabled.
> 
> Work around this by disabling randstruct by default if we have a usable
> rust toolchain, circular dependencies prevent us directly depending on
> !RUST. This means we might end up with a configuration that disables both
> rust and randstruct but hopefully it's more likely go give the expected
> result.
> 
> Signed-off-by: Mark Brown <broonie@kernel.org>

Can we instead just allow it? This has been ready to go for a while,
IIUC:
https://lore.kernel.org/all/CANiq72n=hgH4bqJjp8MsMHAaxaAo75GSBcHGTvFT3NTSaVPGWg@mail.gmail.com/

-Kees

> ---
>  security/Kconfig.hardening | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
> index 86f8768c63d4..1677c4f9637b 100644
> --- a/security/Kconfig.hardening
> +++ b/security/Kconfig.hardening
> @@ -285,7 +285,7 @@ config CC_HAS_RANDSTRUCT
>  
>  choice
>  	prompt "Randomize layout of sensitive kernel structures"
> -	default RANDSTRUCT_FULL if COMPILE_TEST && (GCC_PLUGINS || CC_HAS_RANDSTRUCT)
> +	default RANDSTRUCT_FULL if !RUST_IS_AVAILABLE && COMPILE_TEST && (GCC_PLUGINS || CC_HAS_RANDSTRUCT)
>  	default RANDSTRUCT_NONE
>  	help
>  	  If you enable this, the layouts of structures that are entirely
> 
> ---
> base-commit: e43ffb69e0438cddd72aaa30898b4dc446f664f8
> change-id: 20260605-rust-reverse-randstruct-dep-5a504c861128
> 
> Best regards,
> --  
> Mark Brown <broonie@kernel.org>
> 

-- 
Kees Cook

^ permalink raw reply

* Re: [PATCH] keys: Pin request_key_auth payload in instantiate paths
From: eee sss @ 2026-06-10 15:21 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: keyrings, linux-security-module, linux-kernel, David Howells,
	Paul Moore, James Morris, Serge E. Hallyn
In-Reply-To: <aik5YaJhjRuOKE7I@kernel.org>

Thanks, Jarkko. Sorry for the delayed response.

I checked the commit in for-next-keys. The updated commit message and the
cleanup look good to me.

Best,
Shaomin

On Wed, 10 Jun 2026 13:16:01 +0300, Jarkko Sakkinen <jarkko@kernel.org> wrote:
> On Mon, Jun 08, 2026 at 08:42:21AM +0300, Jarkko Sakkinen wrote:
> > On Mon, Jun 08, 2026 at 08:29:11AM +0300, Jarkko Sakkinen wrote:
> > > On Mon, Jun 08, 2026 at 06:10:23AM +0300, Jarkko Sakkinen wrote:
> > > > On Mon, Jun 08, 2026 at 06:06:21AM +0300, Jarkko Sakkinen wrote:
> > > > > On Tue, May 26, 2026 at 10:48:38AM +0800, Shaomin Chen wrote:
> > > > > > keyctl_instantiate_key_common() reads request_key_auth from the assumed
> > > > > > auth key before copying an instantiation payload from userspace. The copy
> > > > > > can fault and sleep. If the request completes and revokes the auth key in
> > > > > > that window, the auth payload can be detached and freed before the
> > > > > > instantiate path uses it again.
> > > > > >
> > > > > > A request-key helper reproducer can trigger this race. One helper child
> > > > > > blocks in KEYCTL_INSTANTIATE_IOV while the original helper instantiates the
> > > > > > requested key and returns. KASAN then reports a use-after-free from the
> > > > > > stale request_key_auth payload in keyctl_instantiate_key_common().
> > > > > >
> > > > > > Give request_key_auth payloads a refcount. Take a payload reference while
> > > > >
> > > > > Please, name concrete things accurately. I.e. 'usage' in this case. If
> > > > > you have a name, use it instead of obfuscating generalizations.
> > > > >
> > > > > > authkey->sem stabilizes the payload and revocation state. Hold that
> > > > > > reference across the instantiate and reject paths. Drop the auth key
> > > > > > owning reference from revoke and destroy.
> > > > > >
> > > > > > Reported-by: Shaomin Chen <eeesssooo020@gmail.com>
> > > > > > Closes: https://lore.kernel.org/r/20260519144403.436694-1-eeesssooo020@gmail.com
> > > > > > Signed-off-by: Shaomin Chen <eeesssooo020@gmail.com>
> > > > > > ---
> > > > > > include/keys/request_key_auth-type.h | 2 ++
> > > > > > security/keys/internal.h | 2 ++
> > > > > > security/keys/keyctl.c | 24 +++++++++++++++-----
> > > > > > security/keys/request_key_auth.c | 33 ++++++++++++++++++++++++++--
> > > > > > 4 files changed, 53 insertions(+), 8 deletions(-)
> > > > >
> > > > > So first, couple of things.
> > > > >
> > > > > I'm not going to test not that well documented involving OOT driver.
> > > >
> > > > Oops, sorry typo. "not that well documented reproducer" :-)
> > > >
> > > > But it is cool we just then need to draw the picture.
> > >
> > > I think I got this:
> > >
> > > A: request_key() B: KEYCTL_INSTANTIATE_IOV
> > > ---------------- -------------------------
> > > create auth key
> > > store rka in auth key
> > > wait for helper
> > > get auth key
> > > load rka from auth key
> > > copy user payload
> > > sleep on #PF
> > > helper completed
> > > detach and free rka
> > > destroy auth key
> > > wake up
> > > use rka->target_key
> > > **USE-AFTER-FREE**
> > >
> > > So nothing really complicated here, is there?
> >
> > Send v2 with the code changes that I proposed as we want to the change
> > as ergonomic as possible.
> >
> > Use this as the commit message:
> >
> > keys: Pin request_key_auth payload in instantiate paths
> >
> > A: request_key() B: KEYCTL_INSTANTIATE_IOV
> > ---------------- -------------------------
> > create auth key
> > store rka in auth key
> > wait for helper
> > get auth key
> > load rka from auth key
> > copy user payload
> > sleep on #PF
> >
> > helper completed
> > detach and free rka
> > destroy auth key
> > wake up
> > use rka->target_key
> > **USE-AFTER-FREE**
> >
> > Give request_key_auth payloads a refcount. Take a payload reference while
> > authkey->sem stabilizes the payload and revocation state. Hold that
> > reference across the instantiate and reject paths. Drop the auth key
> > owning reference from revoke and destroy.
> >
> > [jarkko: Replaced the first two paragraphs of text with a concurrency scenario.]
> >
> > And it includes also the remark at the end.
> >
> > BR, Jarkko
>
> Nothing heard so I pushed:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git/commit/?h=for-next-keys&id=9feb0bb3468e863b2b82a2eabfaeec4c7c44b90c
>
> It has the commit message change.
>
> BR, Jarkko

^ permalink raw reply

* Re: [PATCH 2/2] landlock: replace __sk_common struct sock field accesses
From: Mickaël Salaün @ 2026-06-10 13:48 UTC (permalink / raw)
  To: Matthieu Buffet
  Cc: Günther Noack, Mikhail Ivanov, Tingmao Wang,
	konstantin.meskhidze, linux-security-module
In-Reply-To: <20260610.rai6icahch2L@digikod.net>

On Wed, Jun 10, 2026 at 03:41:06PM +0200, Mickaël Salaün wrote:
> Thanks for the fixes, but can you please send a full v5 patch series?

Ok, these are not part of the UDP patch series, but this part of the
same thread, my bad...  I'll pick them, thanks!

> 
> On Tue, Jun 09, 2026 at 11:15:11PM +0200, Matthieu Buffet wrote:
> > Use the proper macro to access __sk_common.skc_family like everywhere
> > else.
> > 
> > Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
> > ---
> >  security/landlock/net.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/security/landlock/net.c b/security/landlock/net.c
> > index 111e58fd9325..fc2acf8bd898 100644
> > --- a/security/landlock/net.c
> > +++ b/security/landlock/net.c
> > @@ -71,7 +71,7 @@ static int current_check_access_socket(struct socket *const sock,
> >  	 * The socket is not locked, so sk_family can change concurrently
> >  	 * due to e.g. setsockopt(IPV6_ADDRFORM).
> >  	 */
> > -	sock_family = READ_ONCE(sock->sk->__sk_common.skc_family);
> > +	sock_family = READ_ONCE(sock->sk->sk_family);
> >  
> >  	switch (address->sa_family) {
> >  	case AF_UNSPEC:
> > -- 
> > 2.47.3
> > 
> > 

^ permalink raw reply

* Re: [PATCH v4 0/7] landlock: Add UDP access control support
From: Mickaël Salaün @ 2026-06-10 13:44 UTC (permalink / raw)
  To: Matthieu Buffet
  Cc: Günther Noack, linux-security-module, Mikhail Ivanov,
	konstantin.meskhidze, Tingmao Wang
In-Reply-To: <ed2805ed-72cf-4277-993e-8a0ca73e65ee@buffet.re>

On Sat, Jun 06, 2026 at 07:01:24PM +0200, Matthieu Buffet wrote:
> Hi Mickaël, Günther,
> 
> Thank you both for your reviews, I will follow up with these last fixes in a
> v5.
> 
> On 5/22/2026 11:08 PM, Mickaël Salaün wrote:
> > > I'm just not super happy about the clarity of logs generated for denied
> > > autobinds ("domain=xxxxxx blockers=net.bind_udp"), due to the fact that
> > > addresses and ports are currently only logged if they are non-0. A later
> > > (coordinated LSM-wide) patch could improve readability by replacing != 0
> > > checks with new booleans in struct lsm_network_audit.
> > 
> > Do you plan to send such patch after this series?  I guess we could add
> > has_{port,addr} fields to lsm_network_audit and handle AF_UNSPEC too?
> 
> I have not come up with anything better than adding boolean fields, so if
> you're in, I will draft a proposition along these lines (and cc: LSM
> subsystem maintainers to synchronize the change across LSMs, I guess)

This sounds good to me.

> 
> > > I'm also not
> > > exactly happy with the integration in existing TCP selftests, but
> > > refactoring them has already been discussed earlier.
> > 
> > Can you remind us what was your concern and the potential fix?
> 
> Regarding TCP selftests, I was referencing that discussion about readability
> (length, and usage of conditionals in what are already test variants) :
> https://lore.kernel.org/linux-security-module/22dcebae-dc5d-0bf1-c686-d2f444558106@huawei-partners.com/
> Nothing blocking, refactoring can be done when things are less busy.

Yes, let's keep that in mind and discuss it once this patch series is
merged.

> 
> -- 
> Matthieu
> 

^ permalink raw reply

* Re: [PATCH 2/2] landlock: replace __sk_common struct sock field accesses
From: Mickaël Salaün @ 2026-06-10 13:41 UTC (permalink / raw)
  To: Matthieu Buffet
  Cc: Günther Noack, Mikhail Ivanov, Tingmao Wang,
	konstantin.meskhidze, linux-security-module
In-Reply-To: <20260609211511.85630-2-matthieu@buffet.re>

Thanks for the fixes, but can you please send a full v5 patch series?

On Tue, Jun 09, 2026 at 11:15:11PM +0200, Matthieu Buffet wrote:
> Use the proper macro to access __sk_common.skc_family like everywhere
> else.
> 
> Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
> ---
>  security/landlock/net.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/security/landlock/net.c b/security/landlock/net.c
> index 111e58fd9325..fc2acf8bd898 100644
> --- a/security/landlock/net.c
> +++ b/security/landlock/net.c
> @@ -71,7 +71,7 @@ static int current_check_access_socket(struct socket *const sock,
>  	 * The socket is not locked, so sk_family can change concurrently
>  	 * due to e.g. setsockopt(IPV6_ADDRFORM).
>  	 */
> -	sock_family = READ_ONCE(sock->sk->__sk_common.skc_family);
> +	sock_family = READ_ONCE(sock->sk->sk_family);
>  
>  	switch (address->sa_family) {
>  	case AF_UNSPEC:
> -- 
> 2.47.3
> 
> 

^ permalink raw reply

* Re: [PATCH v3 1/3] landlock: Require LANDLOCK_ACCESS_FS_MAKE_WHITEOUT for RENAME_WHITEOUT
From: Mickaël Salaün @ 2026-06-10 13:38 UTC (permalink / raw)
  To: Günther Noack
  Cc: Christian Brauner, linux-security-module, Paul Moore,
	Amir Goldstein, Miklos Szeredi, Serge Hallyn, Stephen Smalley
In-Reply-To: <20260610092318.3868884-2-gnoack@google.com>

Making MAKE_CHAR not covering MAKE_WHITEOUT is not addressed (see
previous discussion).  MAKE_CHAR should not restrict whiteout creation
*if* MAKE_WHITEOUT is handled.  Specific tests should check that all
these cases are proprely handled.

There is no documentation update related to the new feature.  A note
should also explain what exactly is a whiteout and why it is not
considered a character device (see previous discussions).

The sandboxer is not updated.

There is no audit tests.


On Wed, Jun 10, 2026 at 11:23:16AM +0200, Günther Noack wrote:
> renameat2(2) with the RENAME_WHITEOUT flag places a whiteout character
> device file in the source file location in place of the moved file.
> This creates a directory entry even in cases where all
> LANDLOCK_ACCESS_FS_MAKE_* rights are denied.
> 
> Introduce the LANDLOCK_ACCESS_FS_MAKE_WHITEOUT right, which is checked
> for the origin directory if RENAME_WHITEOUT is passed.
> 
> This does not affect normal renames within layered OverlayFS mounts:
> When OverlayFS invokes rename with RENAME_WHITEOUT as part of a
> "normal" rename operation, it does so in ovl_rename() using the
> credentials that were set at the time of mounting the OverlayFS.
> 
> Bump the Landlock ABI version to 10.
> 
> Suggested-by: Christian Brauner <brauner@kernel.org>
> Suggested-by: Mickaël Salaün <mic@digikod.net>
> Signed-off-by: Günther Noack <gnoack@google.com>
> ---
>  include/uapi/linux/landlock.h                |  3 +++
>  security/landlock/audit.c                    |  1 +
>  security/landlock/fs.c                       | 17 ++++++++++++++---
>  security/landlock/limits.h                   |  2 +-
>  security/landlock/syscalls.c                 |  2 +-
>  tools/testing/selftests/landlock/base_test.c |  4 ++--
>  tools/testing/selftests/landlock/fs_test.c   |  5 +++--
>  7 files changed, 25 insertions(+), 9 deletions(-)
> 
> diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
> index 10a346e55e95..1f8a1d6d25f1 100644
> --- a/include/uapi/linux/landlock.h
> +++ b/include/uapi/linux/landlock.h
> @@ -328,6 +328,8 @@ struct landlock_net_port_attr {
>   *
>   *   If multiple requirements are not met, the ``EACCES`` error code takes
>   *   precedence over ``EXDEV``.
> + * - %LANDLOCK_ACCESS_FS_MAKE_WHITEOUT: Create a whiteout object through
> + *   :manpage:`rename(2)` with ``RENAME_WHITEOUT``.
>   *
>   * .. warning::
>   *
> @@ -356,6 +358,7 @@ struct landlock_net_port_attr {
>  #define LANDLOCK_ACCESS_FS_TRUNCATE			(1ULL << 14)
>  #define LANDLOCK_ACCESS_FS_IOCTL_DEV			(1ULL << 15)
>  #define LANDLOCK_ACCESS_FS_RESOLVE_UNIX			(1ULL << 16)
> +#define LANDLOCK_ACCESS_FS_MAKE_WHITEOUT		(1ULL << 17)
>  /* clang-format on */
>  
>  /**
> diff --git a/security/landlock/audit.c b/security/landlock/audit.c
> index 8d0edf94037d..09c97083f599 100644
> --- a/security/landlock/audit.c
> +++ b/security/landlock/audit.c
> @@ -38,6 +38,7 @@ static const char *const fs_access_strings[] = {
>  	[BIT_INDEX(LANDLOCK_ACCESS_FS_TRUNCATE)] = "fs.truncate",
>  	[BIT_INDEX(LANDLOCK_ACCESS_FS_IOCTL_DEV)] = "fs.ioctl_dev",
>  	[BIT_INDEX(LANDLOCK_ACCESS_FS_RESOLVE_UNIX)] = "fs.resolve_unix",
> +	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_WHITEOUT)] = "fs.make_whiteout",
>  };
>  
>  static_assert(ARRAY_SIZE(fs_access_strings) == LANDLOCK_NUM_ACCESS_FS);
> diff --git a/security/landlock/fs.c b/security/landlock/fs.c
> index c1ecfe239032..67810d5242b2 100644
> --- a/security/landlock/fs.c
> +++ b/security/landlock/fs.c
> @@ -1080,6 +1080,7 @@ static bool collect_domain_accesses(const struct landlock_ruleset *const domain,
>   * @new_dentry: Destination file or directory.
>   * @removable: Sets to true if it is a rename operation.
>   * @exchange: Sets to true if it is a rename operation with RENAME_EXCHANGE.
> + * @whiteout: Sets to true if it is a rename operation with RENAME_WHITEOUT.
>   *
>   * Because of its unprivileged constraints, Landlock relies on file hierarchies
>   * (and not only inodes) to tie access rights to files.  Being able to link or
> @@ -1127,7 +1128,8 @@ static bool collect_domain_accesses(const struct landlock_ruleset *const domain,
>  static int current_check_refer_path(struct dentry *const old_dentry,
>  				    const struct path *const new_dir,
>  				    struct dentry *const new_dentry,
> -				    const bool removable, const bool exchange)
> +				    const bool removable, const bool exchange,
> +				    const bool whiteout)
>  {
>  	const struct landlock_cred_security *const subject =
>  		landlock_get_applicable_subject(current_cred(), any_fs, NULL);
> @@ -1159,6 +1161,14 @@ static int current_check_refer_path(struct dentry *const old_dentry,
>  		access_request_parent2 |= maybe_remove(new_dentry);
>  	}
>  
> +	/*
> +	 * In case of renameat2(2) with RENAME_WHITEOUT, a whiteout object is
> +	 * created in the source location, so we require an additional access
> +	 * right there.
> +	 */
> +	if (whiteout)
> +		access_request_parent1 |= LANDLOCK_ACCESS_FS_MAKE_WHITEOUT;
> +
>  	/* The mount points are the same for old and new paths, cf. EXDEV. */
>  	if (old_dentry->d_parent == new_dir->dentry) {
>  		/*
> @@ -1509,7 +1519,7 @@ static int hook_path_link(struct dentry *const old_dentry,
>  			  struct dentry *const new_dentry)
>  {
>  	return current_check_refer_path(old_dentry, new_dir, new_dentry, false,
> -					false);
> +					false, false);
>  }
>  
>  static int hook_path_rename(const struct path *const old_dir,
> @@ -1520,7 +1530,8 @@ static int hook_path_rename(const struct path *const old_dir,
>  {
>  	/* old_dir refers to old_dentry->d_parent and new_dir->mnt */
>  	return current_check_refer_path(old_dentry, new_dir, new_dentry, true,
> -					!!(flags & RENAME_EXCHANGE));
> +					!!(flags & RENAME_EXCHANGE),
> +					!!(flags & RENAME_WHITEOUT));
>  }
>  
>  static int hook_path_mkdir(const struct path *const dir,
> diff --git a/security/landlock/limits.h b/security/landlock/limits.h
> index b454ad73b15e..e59378e8e897 100644
> --- a/security/landlock/limits.h
> +++ b/security/landlock/limits.h
> @@ -19,7 +19,7 @@
>  #define LANDLOCK_MAX_NUM_LAYERS		16
>  #define LANDLOCK_MAX_NUM_RULES		U32_MAX
>  
> -#define LANDLOCK_LAST_ACCESS_FS		LANDLOCK_ACCESS_FS_RESOLVE_UNIX
> +#define LANDLOCK_LAST_ACCESS_FS		LANDLOCK_ACCESS_FS_MAKE_WHITEOUT
>  #define LANDLOCK_MASK_ACCESS_FS		((LANDLOCK_LAST_ACCESS_FS << 1) - 1)
>  #define LANDLOCK_NUM_ACCESS_FS		__const_hweight64(LANDLOCK_MASK_ACCESS_FS)
>  
> diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
> index accfd2e5a0cd..d45469d5d464 100644
> --- a/security/landlock/syscalls.c
> +++ b/security/landlock/syscalls.c
> @@ -166,7 +166,7 @@ static const struct file_operations ruleset_fops = {
>   * If the change involves a fix that requires userspace awareness, also update
>   * the errata documentation in Documentation/userspace-api/landlock.rst .
>   */
> -const int landlock_abi_version = 9;
> +const int landlock_abi_version = 10;
>  
>  /**
>   * sys_landlock_create_ruleset - Create a new ruleset
> diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c
> index 30d37234086c..6c8113c2ded1 100644
> --- a/tools/testing/selftests/landlock/base_test.c
> +++ b/tools/testing/selftests/landlock/base_test.c
> @@ -76,8 +76,8 @@ TEST(abi_version)
>  	const struct landlock_ruleset_attr ruleset_attr = {
>  		.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
>  	};
> -	ASSERT_EQ(9, landlock_create_ruleset(NULL, 0,
> -					     LANDLOCK_CREATE_RULESET_VERSION));
> +	ASSERT_EQ(10, landlock_create_ruleset(NULL, 0,
> +					      LANDLOCK_CREATE_RULESET_VERSION));
>  
>  	ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0,
>  					      LANDLOCK_CREATE_RULESET_VERSION));
> diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
> index cdb47fc1fc0a..53d1b659849f 100644
> --- a/tools/testing/selftests/landlock/fs_test.c
> +++ b/tools/testing/selftests/landlock/fs_test.c
> @@ -579,7 +579,7 @@ TEST_F_FORK(layout1, inval)
>  	LANDLOCK_ACCESS_FS_IOCTL_DEV | \
>  	LANDLOCK_ACCESS_FS_RESOLVE_UNIX)
>  
> -#define ACCESS_LAST LANDLOCK_ACCESS_FS_RESOLVE_UNIX
> +#define ACCESS_LAST LANDLOCK_ACCESS_FS_MAKE_WHITEOUT
>  
>  #define ACCESS_ALL ( \
>  	ACCESS_FILE | \
> @@ -593,7 +593,8 @@ TEST_F_FORK(layout1, inval)
>  	LANDLOCK_ACCESS_FS_MAKE_FIFO | \
>  	LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
>  	LANDLOCK_ACCESS_FS_MAKE_SYM | \
> -	LANDLOCK_ACCESS_FS_REFER)
> +	LANDLOCK_ACCESS_FS_REFER | \
> +	LANDLOCK_ACCESS_FS_MAKE_WHITEOUT)
>  
>  /* clang-format on */
>  
> -- 
> 2.54.0.1099.g489fc7bff1-goog
> 

^ permalink raw reply

* Re: [PATCH] keys: allow request-key path to be configured via Kconfig
From: Gary Guo @ 2026-06-10 13:37 UTC (permalink / raw)
  To: Jarkko Sakkinen, Gary Guo
  Cc: David Howells, Paul Moore, James Morris, Serge E. Hallyn,
	keyrings, linux-security-module, linux-kernel
In-Reply-To: <ailfPUbn8gbUqB1D@kernel.org>

On Wed Jun 10, 2026 at 1:57 PM BST, Jarkko Sakkinen wrote:
> On Mon, Jun 08, 2026 at 11:30:06AM +0100, Gary Guo wrote:
>> 
>> This is really just for distros to be able to configure where /sbin is located.
>> Given usr merge and (some distros) bin/sbin merge, the canonical path of
>> request-key binary is very likely not /sbin/request-key anymore, so it seems to
>> make sense to me to allow this to be changed rather than always go through
>> compatibility symlinks.
>
> I doubt there's a huge demand other than NixOS. Just basing this on that
> no other noise have been made so far.

Just to add on this, both Fedora and openSUSE for example changes their
CONFIG_MODPROBE_PATH to be /usr/sbin/modprobe after /usr merge. They still have
the /sbin -> /usr/sbin symlink available, so it's not like they cannot work with
/sbin/request-key, but I would think that if the option is available then they
might switch to use /usr/sbin/request-key, too.

After all, why would one perform a symlink walk for no reason?

Best,
Gary

^ permalink raw reply

* Re: [PATCH] keys: allow request-key path to be configured via Kconfig
From: Gary Guo @ 2026-06-10 13:31 UTC (permalink / raw)
  To: Jarkko Sakkinen, Gary Guo
  Cc: David Howells, Paul Moore, James Morris, Serge E. Hallyn,
	keyrings, linux-security-module, linux-kernel
In-Reply-To: <ailgG5JF6Qu_6v0P@kernel.org>

On Wed Jun 10, 2026 at 2:01 PM BST, Jarkko Sakkinen wrote:
> On Wed, Jun 10, 2026 at 03:57:37PM +0300, Jarkko Sakkinen wrote:
>> On Mon, Jun 08, 2026 at 11:30:06AM +0100, Gary Guo wrote:
>> > On Mon Jun 8, 2026 at 5:59 AM BST, Jarkko Sakkinen wrote:
>> > > On Mon, Jun 08, 2026 at 07:50:03AM +0300, Jarkko Sakkinen wrote:
>> > >> On Sun, Jun 07, 2026 at 02:49:27PM +0100, Gary Guo wrote:
>> > >> > From: Gary Guo <gary@garyguo.net>
>> > >> > 
>> > >> > Some Linux distributions (e.g. NixOS) does not have /sbin present, and they
>> > >> > currently carry patches to replace /sbin/request-key to some other path.
>> > >> 
>> > >> Sorry but no configuration for introducing API divergence.
>> > 
>> > What is the API divergence here? Distros can already patch the kernel or place a
>> > different binary there, so I don't see what's being gained on not allowing to
>> > change this with Kconfig.
>> 
>> There's lot of out-of-tree drivers too that distributions. I'm not
>> finding anything usefel in this argument.

Out-of-tree drivers are, well, out of tree. This one requires patching the tree.
Unlike many other distros, so far the only patches needed for NixOS is patching
out /sbin.

>> 
>> > 
>> > Also to note, the actual binary being called can already be swapped out by
>> > CONFIG_STATIC_USERMODEHELPER_PATH, although for the NixOS this is not the proper
>> > mechanism as it affects coredump too which isn't a fixed path binary in /sbin.
>> 
>> I have not seen actual uses of CONFIG_STATIC_USERMODEHELPER_PATH. You
>> could probably use it with busybox?

I think it's used for hardening.

>> > 
>> > This is really just for distros to be able to configure where /sbin is located.
>> > Given usr merge and (some distros) bin/sbin merge, the canonical path of
>> > request-key binary is very likely not /sbin/request-key anymore, so it seems to
>> > make sense to me to allow this to be changed rather than always go through
>> > compatibility symlinks.
>> 
>> I doubt there's a huge demand other than NixOS. Just basing this on that
>> no other noise have been made so far.
>> 
>> > 
>> > How about a something like CONFIG_DEFAULT_USERMODEHELPER_PATH which defaults to
>> > /sbin, and then request-key uses that concatenated with "/request-key"?
>> > 
>> > [snip]
>> 
>> I don't frankly care how NixOS works per se in details. Scope this into
>> message to problem that it addresses.

Well, I reckon that's what's going to happen, so in the commit message I just
included "binary is not in /sbin". But the idea is that there's a good reason
that it's not in /sbin.

>
> Not 100% NAK but this does not have "universal logic" embedded into it"
>
> "Distro's use it" is popularity opinion, which has no place over here.
> Mastodon, Threads etc. work for that so much better.

I disagree. Distro is really just a collection of users. I would rather than
phrase this as "user's using it this way". If something needs to be patched to
be used, I think that's rather a good reason to make the change.

I think "user wants to control where UMH lives" is a pretty good motivation, but
it looks like you disagree. Anyhow, if you don't like the idea, I'll just drop
this patch, as I am not the one maintaining these distro patches anyway. I just
think it's the best if Kconfig can meet user demand and more people can run
unpatched kernels.

Best,
Gary

> Perhaps if the motivation-stimuli-solution type of logics gets carved
> crystal clear we can move forward. I.e. you need to work on this. I've
> given my feedback for this version, and it is not good enough, sorry.
>
> BR, Jarkko



^ permalink raw reply

* Re: [PATCH] keys: allow request-key path to be configured via Kconfig
From: Jarkko Sakkinen @ 2026-06-10 13:01 UTC (permalink / raw)
  To: Gary Guo
  Cc: David Howells, Paul Moore, James Morris, Serge E. Hallyn,
	keyrings, linux-security-module, linux-kernel
In-Reply-To: <ailfPUbn8gbUqB1D@kernel.org>

On Wed, Jun 10, 2026 at 03:57:37PM +0300, Jarkko Sakkinen wrote:
> On Mon, Jun 08, 2026 at 11:30:06AM +0100, Gary Guo wrote:
> > On Mon Jun 8, 2026 at 5:59 AM BST, Jarkko Sakkinen wrote:
> > > On Mon, Jun 08, 2026 at 07:50:03AM +0300, Jarkko Sakkinen wrote:
> > >> On Sun, Jun 07, 2026 at 02:49:27PM +0100, Gary Guo wrote:
> > >> > From: Gary Guo <gary@garyguo.net>
> > >> > 
> > >> > Some Linux distributions (e.g. NixOS) does not have /sbin present, and they
> > >> > currently carry patches to replace /sbin/request-key to some other path.
> > >> 
> > >> Sorry but no configuration for introducing API divergence.
> > 
> > What is the API divergence here? Distros can already patch the kernel or place a
> > different binary there, so I don't see what's being gained on not allowing to
> > change this with Kconfig.
> 
> There's lot of out-of-tree drivers too that distributions. I'm not
> finding anything usefel in this argument.
> 
> > 
> > Also to note, the actual binary being called can already be swapped out by
> > CONFIG_STATIC_USERMODEHELPER_PATH, although for the NixOS this is not the proper
> > mechanism as it affects coredump too which isn't a fixed path binary in /sbin.
> 
> I have not seen actual uses of CONFIG_STATIC_USERMODEHELPER_PATH. You
> could probably use it with busybox?
> 
> > 
> > This is really just for distros to be able to configure where /sbin is located.
> > Given usr merge and (some distros) bin/sbin merge, the canonical path of
> > request-key binary is very likely not /sbin/request-key anymore, so it seems to
> > make sense to me to allow this to be changed rather than always go through
> > compatibility symlinks.
> 
> I doubt there's a huge demand other than NixOS. Just basing this on that
> no other noise have been made so far.
> 
> > 
> > How about a something like CONFIG_DEFAULT_USERMODEHELPER_PATH which defaults to
> > /sbin, and then request-key uses that concatenated with "/request-key"?
> > 
> > >
> > > Not sure right now but one option might kernel command-line. Then it is
> > > known at run-time, can be signed etc. Compiled value has no identity in
> > > the same way.
> > >
> > > And I don't care if NixOS has such a problem as I've not have any stake
> > > making of those decisions.
> > >
> > > You really should explain why it makes sense to have such feature i.e.,
> > > why is it useful. And if NixOS considered, why is it useful for NixOS.
> > >
> > > This all should be in  the commit message.
> > 
> > Sure, if you need some more detailed explaination on how NixOS works.
> > 
> > NixOS intentionally not use FHS directory paths, so packages refers to their
> > dependencies via cryptographical hashes in rather than fixed paths for build-time
> > known dependencies, and themselves also live in a path with hashes in them (so
> > two different versions of the same package are in different paths). E.g.
> > /nix/store/wjzk0s5dwk0i7swh3rmh1pl10k6v1w6d-keyutils-1.6.3/bin/request-key
> > 
> > The full system is also built as a package with all installed binaries in
> > $pkg/sw/bin, configuration in $pkg/etc, etc.. The current system is symlinked to
> > /run/current-system, and when a new system is activated this symlink is swapped
> > out and therefore all paths are updated atomically. For request-key, this is
> > symlinked to
> > /run/current-system/sw/bin/request-key
> > 
> > NixOS carries a patch which uses this path instead of /sbin (which does not
> > exist on NixOS at all).
> > 
> > The motivation is really "be able to switch /sbin". I feel that all the above are
> > secondary motivations and is too verbose to include in the commit message.
> > 
> > I am not a maintainer for NixOS's kernel; I use NixOS and just want to develop
> > kernel and test out kernel on my machines without having to patch them.
> 
> I don't frankly care how NixOS works per se in details. Scope this into
> message to problem that it addresses.

Not 100% NAK but this does not have "universal logic" embedded into it"

"Distro's use it" is popularity opinion, which has no place over here.
Mastodon, Threads etc. work for that so much better.

Perhaps if the motivation-stimuli-solution type of logics gets carved
crystal clear we can move forward. I.e. you need to work on this. I've
given my feedback for this version, and it is not good enough, sorry.

BR, Jarkko

^ permalink raw reply

* Re: [PATCH] keys: allow request-key path to be configured via Kconfig
From: Jarkko Sakkinen @ 2026-06-10 12:57 UTC (permalink / raw)
  To: Gary Guo
  Cc: David Howells, Paul Moore, James Morris, Serge E. Hallyn,
	keyrings, linux-security-module, linux-kernel
In-Reply-To: <DJ3LJFFPMAOW.QA3EZSAB2S5A@garyguo.net>

On Mon, Jun 08, 2026 at 11:30:06AM +0100, Gary Guo wrote:
> On Mon Jun 8, 2026 at 5:59 AM BST, Jarkko Sakkinen wrote:
> > On Mon, Jun 08, 2026 at 07:50:03AM +0300, Jarkko Sakkinen wrote:
> >> On Sun, Jun 07, 2026 at 02:49:27PM +0100, Gary Guo wrote:
> >> > From: Gary Guo <gary@garyguo.net>
> >> > 
> >> > Some Linux distributions (e.g. NixOS) does not have /sbin present, and they
> >> > currently carry patches to replace /sbin/request-key to some other path.
> >> 
> >> Sorry but no configuration for introducing API divergence.
> 
> What is the API divergence here? Distros can already patch the kernel or place a
> different binary there, so I don't see what's being gained on not allowing to
> change this with Kconfig.

There's lot of out-of-tree drivers too that distributions. I'm not
finding anything usefel in this argument.

> 
> Also to note, the actual binary being called can already be swapped out by
> CONFIG_STATIC_USERMODEHELPER_PATH, although for the NixOS this is not the proper
> mechanism as it affects coredump too which isn't a fixed path binary in /sbin.

I have not seen actual uses of CONFIG_STATIC_USERMODEHELPER_PATH. You
could probably use it with busybox?

> 
> This is really just for distros to be able to configure where /sbin is located.
> Given usr merge and (some distros) bin/sbin merge, the canonical path of
> request-key binary is very likely not /sbin/request-key anymore, so it seems to
> make sense to me to allow this to be changed rather than always go through
> compatibility symlinks.

I doubt there's a huge demand other than NixOS. Just basing this on that
no other noise have been made so far.

> 
> How about a something like CONFIG_DEFAULT_USERMODEHELPER_PATH which defaults to
> /sbin, and then request-key uses that concatenated with "/request-key"?
> 
> >
> > Not sure right now but one option might kernel command-line. Then it is
> > known at run-time, can be signed etc. Compiled value has no identity in
> > the same way.
> >
> > And I don't care if NixOS has such a problem as I've not have any stake
> > making of those decisions.
> >
> > You really should explain why it makes sense to have such feature i.e.,
> > why is it useful. And if NixOS considered, why is it useful for NixOS.
> >
> > This all should be in  the commit message.
> 
> Sure, if you need some more detailed explaination on how NixOS works.
> 
> NixOS intentionally not use FHS directory paths, so packages refers to their
> dependencies via cryptographical hashes in rather than fixed paths for build-time
> known dependencies, and themselves also live in a path with hashes in them (so
> two different versions of the same package are in different paths). E.g.
> /nix/store/wjzk0s5dwk0i7swh3rmh1pl10k6v1w6d-keyutils-1.6.3/bin/request-key
> 
> The full system is also built as a package with all installed binaries in
> $pkg/sw/bin, configuration in $pkg/etc, etc.. The current system is symlinked to
> /run/current-system, and when a new system is activated this symlink is swapped
> out and therefore all paths are updated atomically. For request-key, this is
> symlinked to
> /run/current-system/sw/bin/request-key
> 
> NixOS carries a patch which uses this path instead of /sbin (which does not
> exist on NixOS at all).
> 
> The motivation is really "be able to switch /sbin". I feel that all the above are
> secondary motivations and is too verbose to include in the commit message.
> 
> I am not a maintainer for NixOS's kernel; I use NixOS and just want to develop
> kernel and test out kernel on my machines without having to patch them.

I don't frankly care how NixOS works per se in details. Scope this into
message to problem that it addresses.

> 
> Best,
> Gary

BR, Jarkko

^ permalink raw reply

* Re: [PATCH] keys: Pin request_key_auth payload in instantiate paths
From: Jarkko Sakkinen @ 2026-06-10 10:16 UTC (permalink / raw)
  To: Shaomin Chen
  Cc: keyrings, linux-security-module, linux-kernel, David Howells,
	Paul Moore, James Morris, Serge E. Hallyn
In-Reply-To: <aiZWPSJZyFq4nmxf@kernel.org>

On Mon, Jun 08, 2026 at 08:42:21AM +0300, Jarkko Sakkinen wrote:
> On Mon, Jun 08, 2026 at 08:29:11AM +0300, Jarkko Sakkinen wrote:
> > On Mon, Jun 08, 2026 at 06:10:23AM +0300, Jarkko Sakkinen wrote:
> > > On Mon, Jun 08, 2026 at 06:06:21AM +0300, Jarkko Sakkinen wrote:
> > > > On Tue, May 26, 2026 at 10:48:38AM +0800, Shaomin Chen wrote:
> > > > > keyctl_instantiate_key_common() reads request_key_auth from the assumed
> > > > > auth key before copying an instantiation payload from userspace.  The copy
> > > > > can fault and sleep.  If the request completes and revokes the auth key in
> > > > > that window, the auth payload can be detached and freed before the
> > > > > instantiate path uses it again.
> > > > > 
> > > > > A request-key helper reproducer can trigger this race.  One helper child
> > > > > blocks in KEYCTL_INSTANTIATE_IOV while the original helper instantiates the
> > > > > requested key and returns.  KASAN then reports a use-after-free from the
> > > > > stale request_key_auth payload in keyctl_instantiate_key_common().
> > > > > 
> > > > > Give request_key_auth payloads a refcount.  Take a payload reference while
> > > > 
> > > > Please, name concrete things accurately. I.e. 'usage' in this case. If
> > > > you have a name, use it instead of obfuscating generalizations.
> > > > 
> > > > > authkey->sem stabilizes the payload and revocation state.  Hold that
> > > > > reference across the instantiate and reject paths.  Drop the auth key
> > > > > owning reference from revoke and destroy.
> > > > > 
> > > > > Reported-by: Shaomin Chen <eeesssooo020@gmail.com>
> > > > > Closes: https://lore.kernel.org/r/20260519144403.436694-1-eeesssooo020@gmail.com
> > > > > Signed-off-by: Shaomin Chen <eeesssooo020@gmail.com>
> > > > > ---
> > > > >  include/keys/request_key_auth-type.h |  2 ++
> > > > >  security/keys/internal.h             |  2 ++
> > > > >  security/keys/keyctl.c               | 24 +++++++++++++++-----
> > > > >  security/keys/request_key_auth.c     | 33 ++++++++++++++++++++++++++--
> > > > >  4 files changed, 53 insertions(+), 8 deletions(-)
> > > > 
> > > > So first, couple of things.
> > > > 
> > > > I'm not going to test not that well documented involving OOT driver.
> > > 
> > > Oops, sorry typo. "not that well documented reproducer" :-)
> > > 
> > > But it is cool we just then need to draw the picture.
> > 
> > I think I got this:
> > 
> > A: request_key()       B: KEYCTL_INSTANTIATE_IOV
> > ----------------       -------------------------
> > create auth key
> > store rka in auth key
> > wait for helper
> >                        get auth key
> >                        load rka from auth key
> >                        copy user payload
> >                        sleep on #PF
> > helper completed
> > detach and free rka
> > destroy auth key
> >                        wake up
> >                        use rka->target_key
> >                        **USE-AFTER-FREE**
> > 
> > So nothing really complicated here, is there?
> 
> Send v2 with the code changes that I proposed as we want to the change
> as ergonomic as possible.
> 
> Use this as the commit message:
> 
>     keys: Pin request_key_auth payload in instantiate paths
> 
>     A: request_key()       B: KEYCTL_INSTANTIATE_IOV
>     ----------------       -------------------------
>     create auth key
>     store rka in auth key
>     wait for helper
>                            get auth key
>                            load rka from auth key
>                            copy user payload
>                            sleep on #PF
> 
>     helper completed
>     detach and free rka
>     destroy auth key
>                            wake up
>                            use rka->target_key
>                            **USE-AFTER-FREE**
> 
>     Give request_key_auth payloads a refcount.  Take a payload reference while
>     authkey->sem stabilizes the payload and revocation state.  Hold that
>     reference across the instantiate and reject paths.  Drop the auth key
>     owning reference from revoke and destroy.
> 
>     [jarkko: Replaced the first two paragraphs of text with a concurrency scenario.]
> 
> And it includes also the remark at the end.
> 
> BR, Jarkko


Nothing heard so I pushed:

https://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git/commit/?h=for-next-keys&id=9feb0bb3468e863b2b82a2eabfaeec4c7c44b90c

It has the commit message change.

BR, Jarkko

^ permalink raw reply

* Re: [PATCH v2] keys: prevent slab cache merging for key_jar
From: Jarkko Sakkinen @ 2026-06-10  9:57 UTC (permalink / raw)
  To: Mohammed EL Kadiri
  Cc: dhowells, paul, jmorris, serge, kees, vbabka, keyrings,
	linux-security-module, linux-hardening, linux-kernel
In-Reply-To: <20260610065052.9120-1-med08elkadiri@gmail.com>

On Wed, Jun 10, 2026 at 07:50:52AM +0100, Mohammed EL Kadiri wrote:
> Add SLAB_NO_MERGE to key_jar to prevent the allocator from merging it
> with other similarly-sized caches. This hardens struct key isolation by
> ensuring dedicated slab pages.
> 
> Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
> Signed-off-by: Mohammed EL Kadiri <med08elkadiri@gmail.com>
> ---
>  security/keys/key.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/security/keys/key.c b/security/keys/key.c
> index 3bbdde778631..592b65cf8539 100644
> --- a/security/keys/key.c
> +++ b/security/keys/key.c
> @@ -1275,7 +1275,7 @@ void __init key_init(void)
>  {
>  	/* allocate a slab in which we can store keys */
>  	key_jar = kmem_cache_create("key_jar", sizeof(struct key),
> -			0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
> +			0, SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_NO_MERGE, NULL);
>  
>  	/* add the special key types */
>  	list_add_tail(&key_type_keyring.link, &key_types_list);
> -- 
> 2.43.0
> 

I swapped the commit.

https://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git/log/?h=for-next-keys

BR, Jarkko

^ permalink raw reply

* Re: [PATCH v2 1/3] landlock: Require LANDLOCK_ACCESS_FS_MAKE_WHITEOUT for RENAME_WHITEOUT
From: Günther Noack @ 2026-06-10  9:29 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Christian Brauner, linux-security-module, Paul Moore,
	Amir Goldstein, Miklos Szeredi, Serge Hallyn, Stephen Smalley
In-Reply-To: <20260609.pait5oaTheHi@digikod.net>

On Tue, Jun 09, 2026 at 06:09:51PM +0200, Mickaël Salaün wrote:
> On Wed, May 13, 2026 at 06:05:50PM +0200, Günther Noack wrote:
> > diff --git a/security/landlock/fs.c b/security/landlock/fs.c
> > index c1ecfe239032..09de6ba5c3a3 100644
> > --- a/security/landlock/fs.c
> > +++ b/security/landlock/fs.c
> > @@ -1519,6 +1519,21 @@ static int hook_path_rename(const struct path *const old_dir,
> >  			    const unsigned int flags)
> >  {
> >  	/* old_dir refers to old_dentry->d_parent and new_dir->mnt */
> > +	if (flags & RENAME_WHITEOUT) {
> > +		int err;
> > +
> > +		/*
> > +		 * Rename with RENAME_WHITEOUT creates a whiteout object in the
> > +		 * old location, so we check the access right for creating that.
> > +		 *
> > +		 * See Documentation/filesystems/overlayfs.rst and renameat2(2).
> > +		 */
> > +		err = current_check_access_path(
> > +			old_dir, LANDLOCK_ACCESS_FS_MAKE_WHITEOUT);
> 
> We should not need a second path walk, even if whiteouts are rare.
> Please propose another way.

I sent a V3 with that implemented differently:
https://lore.kernel.org/all/20260610092318.3868884-1-gnoack@google.com/

The tradeoff is that it complicates the common current_check_refer_path() to
solve this fringe use case.  In my understanding, the only software using this
is the FUSE OverlayFS implementation.

See the "tradeoffs" section in the V2 cover letter:
https://lore.kernel.org/all/20260513160552.4022649-1-gnoack@google.com/

I slightly prefer V2, but am OK with either variant if needed.  Please pick
the one that makes more sense to you.

—Günther

^ permalink raw reply

* [PATCH v3 3/3] selftests/landlock: Test OverlayFS renames w/o LANDLOCK_ACCESS_FS_MAKE_WHITEOUT
From: Günther Noack @ 2026-06-10  9:23 UTC (permalink / raw)
  To: Mickaël Salaün, Christian Brauner
  Cc: linux-security-module, Paul Moore, Amir Goldstein, Miklos Szeredi,
	Serge Hallyn, Stephen Smalley, Günther Noack
In-Reply-To: <20260610092318.3868884-1-gnoack@google.com>

Even though OverlayFS uses vfs_rename() with RENAME_WHITEOUT, and even
though RENAME_WHITEOUT requires LANDLOCK_ACCESS_FS_MAKE_WHITEOUT, a process
that renames files in an OverlayFS can do so without having the
LANDLOCK_ACCESS_FS_MAKE_WHITEOUT right in that location.

This works, and is supposed to work, because OverlayFS uses the credentials
determined at mount time for the internal vfs_rename() operation. -- The
rename happens with the credentials of the user who mounted the OverlayFS.

Signed-off-by: Günther Noack <gnoack@google.com>
---
 tools/testing/selftests/landlock/fs_test.c | 31 ++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index bdad92195f62..0c29887278d0 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -6963,6 +6963,37 @@ TEST_F_FORK(layout2_overlay, same_content_different_file)
 	}
 }
 
+TEST_F_FORK(layout2_overlay, rename_in_overlay_without_make_whiteout)
+{
+	struct stat st;
+	const char *merge_fl1_renamed = MERGE_DATA "/fl1_renamed";
+
+	if (self->skip_test)
+		SKIP(return, "overlayfs is not supported (test)");
+
+	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_WHITEOUT, NULL);
+
+	/*
+	 * Execute a regular file rename within OverlayFS.
+	 * merge_fl1 originates from lower layer, so this triggers a copy-up
+	 * and creation of a whiteout in the upper layer.
+	 */
+	EXPECT_EQ(0, rename(merge_fl1, merge_fl1_renamed));
+
+	/* Check that the rename worked. */
+	EXPECT_EQ(0, stat(merge_fl1_renamed, &st));
+	EXPECT_EQ(-1, stat(merge_fl1, &st));
+	EXPECT_EQ(ENOENT, errno);
+
+	/*
+	 * Check that the whiteout object on the underlying "upper" filesystem
+	 * exists after the rename.  This is OK because it was done with the
+	 * credentials of the OverlayFS.
+	 */
+	EXPECT_EQ(0, stat(UPPER_DATA "/fl1", &st));
+	EXPECT_TRUE(S_ISCHR(st.st_mode));
+	EXPECT_EQ(0, st.st_rdev);
+}
 
 FIXTURE(layout3_fs)
 {
-- 
2.54.0.1099.g489fc7bff1-goog


^ permalink raw reply related

* [PATCH v3 2/3] selftests/landlock: Add test for RENAME_WHITEOUT denial
From: Günther Noack @ 2026-06-10  9:23 UTC (permalink / raw)
  To: Mickaël Salaün, Christian Brauner
  Cc: linux-security-module, Paul Moore, Amir Goldstein, Miklos Szeredi,
	Serge Hallyn, Stephen Smalley, Günther Noack
In-Reply-To: <20260610092318.3868884-1-gnoack@google.com>

Add a test to check that renames with RENAME_WHITEOUT are guarded by
LANDLOCK_ACCESS_FS_MAKE_WHITEOUT.

Signed-off-by: Günther Noack <gnoack@google.com>
---
 tools/testing/selftests/landlock/fs_test.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 53d1b659849f..bdad92195f62 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -2248,6 +2248,19 @@ TEST_F_FORK(layout1, rename_file)
 			       RENAME_EXCHANGE));
 }
 
+TEST_F_FORK(layout1, rename_whiteout_denied)
+{
+	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_WHITEOUT, NULL);
+
+	/*
+	 * Try to rename a file with RENAME_WHITEOUT.
+	 * file1_s3d3 is in dir_s3d2 (tmpfs), so it supports RENAME_WHITEOUT.
+	 */
+	EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
+				TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
+	EXPECT_EQ(EACCES, errno);
+}
+
 TEST_F_FORK(layout1, rename_dir)
 {
 	const struct rule rules[] = {
@@ -6950,6 +6963,7 @@ TEST_F_FORK(layout2_overlay, same_content_different_file)
 	}
 }
 
+
 FIXTURE(layout3_fs)
 {
 	bool has_created_dir;
-- 
2.54.0.1099.g489fc7bff1-goog


^ permalink raw reply related

* [PATCH v3 1/3] landlock: Require LANDLOCK_ACCESS_FS_MAKE_WHITEOUT for RENAME_WHITEOUT
From: Günther Noack @ 2026-06-10  9:23 UTC (permalink / raw)
  To: Mickaël Salaün, Christian Brauner
  Cc: linux-security-module, Paul Moore, Amir Goldstein, Miklos Szeredi,
	Serge Hallyn, Stephen Smalley, Günther Noack
In-Reply-To: <20260610092318.3868884-1-gnoack@google.com>

renameat2(2) with the RENAME_WHITEOUT flag places a whiteout character
device file in the source file location in place of the moved file.
This creates a directory entry even in cases where all
LANDLOCK_ACCESS_FS_MAKE_* rights are denied.

Introduce the LANDLOCK_ACCESS_FS_MAKE_WHITEOUT right, which is checked
for the origin directory if RENAME_WHITEOUT is passed.

This does not affect normal renames within layered OverlayFS mounts:
When OverlayFS invokes rename with RENAME_WHITEOUT as part of a
"normal" rename operation, it does so in ovl_rename() using the
credentials that were set at the time of mounting the OverlayFS.

Bump the Landlock ABI version to 10.

Suggested-by: Christian Brauner <brauner@kernel.org>
Suggested-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Günther Noack <gnoack@google.com>
---
 include/uapi/linux/landlock.h                |  3 +++
 security/landlock/audit.c                    |  1 +
 security/landlock/fs.c                       | 17 ++++++++++++++---
 security/landlock/limits.h                   |  2 +-
 security/landlock/syscalls.c                 |  2 +-
 tools/testing/selftests/landlock/base_test.c |  4 ++--
 tools/testing/selftests/landlock/fs_test.c   |  5 +++--
 7 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
index 10a346e55e95..1f8a1d6d25f1 100644
--- a/include/uapi/linux/landlock.h
+++ b/include/uapi/linux/landlock.h
@@ -328,6 +328,8 @@ struct landlock_net_port_attr {
  *
  *   If multiple requirements are not met, the ``EACCES`` error code takes
  *   precedence over ``EXDEV``.
+ * - %LANDLOCK_ACCESS_FS_MAKE_WHITEOUT: Create a whiteout object through
+ *   :manpage:`rename(2)` with ``RENAME_WHITEOUT``.
  *
  * .. warning::
  *
@@ -356,6 +358,7 @@ struct landlock_net_port_attr {
 #define LANDLOCK_ACCESS_FS_TRUNCATE			(1ULL << 14)
 #define LANDLOCK_ACCESS_FS_IOCTL_DEV			(1ULL << 15)
 #define LANDLOCK_ACCESS_FS_RESOLVE_UNIX			(1ULL << 16)
+#define LANDLOCK_ACCESS_FS_MAKE_WHITEOUT		(1ULL << 17)
 /* clang-format on */
 
 /**
diff --git a/security/landlock/audit.c b/security/landlock/audit.c
index 8d0edf94037d..09c97083f599 100644
--- a/security/landlock/audit.c
+++ b/security/landlock/audit.c
@@ -38,6 +38,7 @@ static const char *const fs_access_strings[] = {
 	[BIT_INDEX(LANDLOCK_ACCESS_FS_TRUNCATE)] = "fs.truncate",
 	[BIT_INDEX(LANDLOCK_ACCESS_FS_IOCTL_DEV)] = "fs.ioctl_dev",
 	[BIT_INDEX(LANDLOCK_ACCESS_FS_RESOLVE_UNIX)] = "fs.resolve_unix",
+	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_WHITEOUT)] = "fs.make_whiteout",
 };
 
 static_assert(ARRAY_SIZE(fs_access_strings) == LANDLOCK_NUM_ACCESS_FS);
diff --git a/security/landlock/fs.c b/security/landlock/fs.c
index c1ecfe239032..67810d5242b2 100644
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -1080,6 +1080,7 @@ static bool collect_domain_accesses(const struct landlock_ruleset *const domain,
  * @new_dentry: Destination file or directory.
  * @removable: Sets to true if it is a rename operation.
  * @exchange: Sets to true if it is a rename operation with RENAME_EXCHANGE.
+ * @whiteout: Sets to true if it is a rename operation with RENAME_WHITEOUT.
  *
  * Because of its unprivileged constraints, Landlock relies on file hierarchies
  * (and not only inodes) to tie access rights to files.  Being able to link or
@@ -1127,7 +1128,8 @@ static bool collect_domain_accesses(const struct landlock_ruleset *const domain,
 static int current_check_refer_path(struct dentry *const old_dentry,
 				    const struct path *const new_dir,
 				    struct dentry *const new_dentry,
-				    const bool removable, const bool exchange)
+				    const bool removable, const bool exchange,
+				    const bool whiteout)
 {
 	const struct landlock_cred_security *const subject =
 		landlock_get_applicable_subject(current_cred(), any_fs, NULL);
@@ -1159,6 +1161,14 @@ static int current_check_refer_path(struct dentry *const old_dentry,
 		access_request_parent2 |= maybe_remove(new_dentry);
 	}
 
+	/*
+	 * In case of renameat2(2) with RENAME_WHITEOUT, a whiteout object is
+	 * created in the source location, so we require an additional access
+	 * right there.
+	 */
+	if (whiteout)
+		access_request_parent1 |= LANDLOCK_ACCESS_FS_MAKE_WHITEOUT;
+
 	/* The mount points are the same for old and new paths, cf. EXDEV. */
 	if (old_dentry->d_parent == new_dir->dentry) {
 		/*
@@ -1509,7 +1519,7 @@ static int hook_path_link(struct dentry *const old_dentry,
 			  struct dentry *const new_dentry)
 {
 	return current_check_refer_path(old_dentry, new_dir, new_dentry, false,
-					false);
+					false, false);
 }
 
 static int hook_path_rename(const struct path *const old_dir,
@@ -1520,7 +1530,8 @@ static int hook_path_rename(const struct path *const old_dir,
 {
 	/* old_dir refers to old_dentry->d_parent and new_dir->mnt */
 	return current_check_refer_path(old_dentry, new_dir, new_dentry, true,
-					!!(flags & RENAME_EXCHANGE));
+					!!(flags & RENAME_EXCHANGE),
+					!!(flags & RENAME_WHITEOUT));
 }
 
 static int hook_path_mkdir(const struct path *const dir,
diff --git a/security/landlock/limits.h b/security/landlock/limits.h
index b454ad73b15e..e59378e8e897 100644
--- a/security/landlock/limits.h
+++ b/security/landlock/limits.h
@@ -19,7 +19,7 @@
 #define LANDLOCK_MAX_NUM_LAYERS		16
 #define LANDLOCK_MAX_NUM_RULES		U32_MAX
 
-#define LANDLOCK_LAST_ACCESS_FS		LANDLOCK_ACCESS_FS_RESOLVE_UNIX
+#define LANDLOCK_LAST_ACCESS_FS		LANDLOCK_ACCESS_FS_MAKE_WHITEOUT
 #define LANDLOCK_MASK_ACCESS_FS		((LANDLOCK_LAST_ACCESS_FS << 1) - 1)
 #define LANDLOCK_NUM_ACCESS_FS		__const_hweight64(LANDLOCK_MASK_ACCESS_FS)
 
diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
index accfd2e5a0cd..d45469d5d464 100644
--- a/security/landlock/syscalls.c
+++ b/security/landlock/syscalls.c
@@ -166,7 +166,7 @@ static const struct file_operations ruleset_fops = {
  * If the change involves a fix that requires userspace awareness, also update
  * the errata documentation in Documentation/userspace-api/landlock.rst .
  */
-const int landlock_abi_version = 9;
+const int landlock_abi_version = 10;
 
 /**
  * sys_landlock_create_ruleset - Create a new ruleset
diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c
index 30d37234086c..6c8113c2ded1 100644
--- a/tools/testing/selftests/landlock/base_test.c
+++ b/tools/testing/selftests/landlock/base_test.c
@@ -76,8 +76,8 @@ TEST(abi_version)
 	const struct landlock_ruleset_attr ruleset_attr = {
 		.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
 	};
-	ASSERT_EQ(9, landlock_create_ruleset(NULL, 0,
-					     LANDLOCK_CREATE_RULESET_VERSION));
+	ASSERT_EQ(10, landlock_create_ruleset(NULL, 0,
+					      LANDLOCK_CREATE_RULESET_VERSION));
 
 	ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0,
 					      LANDLOCK_CREATE_RULESET_VERSION));
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index cdb47fc1fc0a..53d1b659849f 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -579,7 +579,7 @@ TEST_F_FORK(layout1, inval)
 	LANDLOCK_ACCESS_FS_IOCTL_DEV | \
 	LANDLOCK_ACCESS_FS_RESOLVE_UNIX)
 
-#define ACCESS_LAST LANDLOCK_ACCESS_FS_RESOLVE_UNIX
+#define ACCESS_LAST LANDLOCK_ACCESS_FS_MAKE_WHITEOUT
 
 #define ACCESS_ALL ( \
 	ACCESS_FILE | \
@@ -593,7 +593,8 @@ TEST_F_FORK(layout1, inval)
 	LANDLOCK_ACCESS_FS_MAKE_FIFO | \
 	LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
 	LANDLOCK_ACCESS_FS_MAKE_SYM | \
-	LANDLOCK_ACCESS_FS_REFER)
+	LANDLOCK_ACCESS_FS_REFER | \
+	LANDLOCK_ACCESS_FS_MAKE_WHITEOUT)
 
 /* clang-format on */
 
-- 
2.54.0.1099.g489fc7bff1-goog


^ permalink raw reply related

* [PATCH v3 0/3] landlock: Restrict renameat2 with RENAME_WHITEOUT
From: Günther Noack @ 2026-06-10  9:23 UTC (permalink / raw)
  To: Mickaël Salaün, Christian Brauner
  Cc: linux-security-module, Paul Moore, Amir Goldstein, Miklos Szeredi,
	Serge Hallyn, Stephen Smalley, Günther Noack

Hello!

As discussed in [1], the renameat2() syscall's RENAME_WHITEOUT flag allows
the creation of chardev directory entries with major=minor=0 as "whiteout
objects" in the location of the rename source file [2].

This functionality is available even without having any OverlayFS mounted
and can be invoked with the regular renameat2(2) syscall [3].

In V1 [5], it was discussed that whiteout objects are not the same as
character devices, and should therefore be guarded with a separate access
right.  We are therefore guarding the operation with the new access right
LANDLOCK_ACCESS_FS_MAKE_WHITEOUT now.

By introducing a new access right, that change is also exposed by
incrementing the ABI level and does not require a Landlock erratum.

Motivation
==========

The RENAME_WHITEOUT flag side-steps all of the existing Landlock access
rights, which are designed to restrict the creation of directory entries.
It is desirable to restrict that.

This patch set fixes that by adding a check in Landlock's path_rename hook.


[1] https://lore.kernel.org/all/adUBCQXrt7kmgqJT@google.com/
[2] https://docs.kernel.org/filesystems/overlayfs.html#whiteouts-and-opaque-directories
[3] https://man7.org/linux/man-pages/man2/renameat2.2.html#DESCRIPTION
[4] https://codesearch.debian.net/search?q=rename.*RENAME_WHITEOUT&literal=0
[5] https://lore.kernel.org/all/20260411090944.3131168-2-gnoack@google.com/


Changelog
=========

v3:
 - Do LANDLOCK_ACCESS_FS_MAKE_WHITEOUT check as part of
   current_check_refer_path().

v2:
 - Introduce LANDLOCK_ACCESS_FS_MAKE_WHITEOUT access right
   and guard it with that.
 - Bump ABI version
 - https://lore.kernel.org/all/20260513160552.4022649-1-gnoack@google.com/

v1:
 - initial version
   https://lore.kernel.org/all/20260411090944.3131168-2-gnoack@google.com/


Günther Noack (3):
  landlock: Require LANDLOCK_ACCESS_FS_MAKE_WHITEOUT for RENAME_WHITEOUT
  selftests/landlock: Add test for RENAME_WHITEOUT denial
  selftests/landlock: Test OverlayFS renames w/o
    LANDLOCK_ACCESS_FS_MAKE_WHITEOUT

 include/uapi/linux/landlock.h                |  3 ++
 security/landlock/audit.c                    |  1 +
 security/landlock/fs.c                       | 17 +++++--
 security/landlock/limits.h                   |  2 +-
 security/landlock/syscalls.c                 |  2 +-
 tools/testing/selftests/landlock/base_test.c |  4 +-
 tools/testing/selftests/landlock/fs_test.c   | 50 +++++++++++++++++++-
 7 files changed, 70 insertions(+), 9 deletions(-)

Range-diff against v2:
1:  1f2b7f49b927 ! 1:  4a8c3fb9e707 landlock: Require LANDLOCK_ACCESS_FS_MAKE_WHITEOUT for RENAME_WHITEOUT
    @@ security/landlock/audit.c: static const char *const fs_access_strings[] = {
      static_assert(ARRAY_SIZE(fs_access_strings) == LANDLOCK_NUM_ACCESS_FS);
     
      ## security/landlock/fs.c ##
    +@@ security/landlock/fs.c: static bool collect_domain_accesses(const struct landlock_ruleset *const domain,
    +  * @new_dentry: Destination file or directory.
    +  * @removable: Sets to true if it is a rename operation.
    +  * @exchange: Sets to true if it is a rename operation with RENAME_EXCHANGE.
    ++ * @whiteout: Sets to true if it is a rename operation with RENAME_WHITEOUT.
    +  *
    +  * Because of its unprivileged constraints, Landlock relies on file hierarchies
    +  * (and not only inodes) to tie access rights to files.  Being able to link or
    +@@ security/landlock/fs.c: static bool collect_domain_accesses(const struct landlock_ruleset *const domain,
    + static int current_check_refer_path(struct dentry *const old_dentry,
    + 				    const struct path *const new_dir,
    + 				    struct dentry *const new_dentry,
    +-				    const bool removable, const bool exchange)
    ++				    const bool removable, const bool exchange,
    ++				    const bool whiteout)
    + {
    + 	const struct landlock_cred_security *const subject =
    + 		landlock_get_applicable_subject(current_cred(), any_fs, NULL);
    +@@ security/landlock/fs.c: static int current_check_refer_path(struct dentry *const old_dentry,
    + 		access_request_parent2 |= maybe_remove(new_dentry);
    + 	}
    + 
    ++	/*
    ++	 * In case of renameat2(2) with RENAME_WHITEOUT, a whiteout object is
    ++	 * created in the source location, so we require an additional access
    ++	 * right there.
    ++	 */
    ++	if (whiteout)
    ++		access_request_parent1 |= LANDLOCK_ACCESS_FS_MAKE_WHITEOUT;
    ++
    + 	/* The mount points are the same for old and new paths, cf. EXDEV. */
    + 	if (old_dentry->d_parent == new_dir->dentry) {
    + 		/*
    +@@ security/landlock/fs.c: static int hook_path_link(struct dentry *const old_dentry,
    + 			  struct dentry *const new_dentry)
    + {
    + 	return current_check_refer_path(old_dentry, new_dir, new_dentry, false,
    +-					false);
    ++					false, false);
    + }
    + 
    + static int hook_path_rename(const struct path *const old_dir,
     @@ security/landlock/fs.c: static int hook_path_rename(const struct path *const old_dir,
    - 			    const unsigned int flags)
      {
      	/* old_dir refers to old_dentry->d_parent and new_dir->mnt */
    -+	if (flags & RENAME_WHITEOUT) {
    -+		int err;
    -+
    -+		/*
    -+		 * Rename with RENAME_WHITEOUT creates a whiteout object in the
    -+		 * old location, so we check the access right for creating that.
    -+		 *
    -+		 * See Documentation/filesystems/overlayfs.rst and renameat2(2).
    -+		 */
    -+		err = current_check_access_path(
    -+			old_dir, LANDLOCK_ACCESS_FS_MAKE_WHITEOUT);
    -+		if (err)
    -+			return err;
    -+	}
    -+
      	return current_check_refer_path(old_dentry, new_dir, new_dentry, true,
    - 					!!(flags & RENAME_EXCHANGE));
    +-					!!(flags & RENAME_EXCHANGE));
    ++					!!(flags & RENAME_EXCHANGE),
    ++					!!(flags & RENAME_WHITEOUT));
      }
    + 
    + static int hook_path_mkdir(const struct path *const dir,
     
      ## security/landlock/limits.h ##
     @@
2:  aa4e4aeb5884 = 2:  063646822083 selftests/landlock: Add test for RENAME_WHITEOUT denial
3:  6660d70a1eda = 3:  5d4606bc1e84 selftests/landlock: Test OverlayFS renames w/o LANDLOCK_ACCESS_FS_MAKE_WHITEOUT
-- 
2.54.0.1099.g489fc7bff1-goog


^ permalink raw reply

* [PATCH v2] keys: prevent slab cache merging for key_jar
From: Mohammed EL Kadiri @ 2026-06-10  6:50 UTC (permalink / raw)
  To: dhowells, jarkko
  Cc: paul, jmorris, serge, kees, vbabka, keyrings,
	linux-security-module, linux-hardening, linux-kernel,
	Mohammed EL Kadiri

Add SLAB_NO_MERGE to key_jar to prevent the allocator from merging it
with other similarly-sized caches. This hardens struct key isolation by
ensuring dedicated slab pages.

Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Signed-off-by: Mohammed EL Kadiri <med08elkadiri@gmail.com>
---
 security/keys/key.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/keys/key.c b/security/keys/key.c
index 3bbdde778631..592b65cf8539 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1275,7 +1275,7 @@ void __init key_init(void)
 {
 	/* allocate a slab in which we can store keys */
 	key_jar = kmem_cache_create("key_jar", sizeof(struct key),
-			0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
+			0, SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_NO_MERGE, NULL);
 
 	/* add the special key types */
 	list_add_tail(&key_type_keyring.link, &key_types_list);
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v2 00/16] Bump minimum version of LLVM for building the kernel to 17.0.1
From: Nathan Chancellor @ 2026-06-09 23:28 UTC (permalink / raw)
  To: Nicolas Schier, Bill Wendling, Justin Stitt, Nick Desaulniers,
	Nathan Chancellor
  Cc: linux-kernel, llvm, linux-kbuild, Jonathan Corbet, Shuah Khan,
	linux-doc, Kees Cook, Gustavo A. R. Silva, linux-hardening,
	linux-security-module, Rong Xu, Han Shen, Russell King,
	Arnd Bergmann, linux-arm-kernel, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexandre Ghiti, linux-riscv, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
	Ard Biesheuvel, Peter Zijlstra
In-Reply-To: <20260517-bump-minimum-supported-llvm-version-to-17-v2-0-b3b8cda46bdd@kernel.org>

On Sun, 17 May 2026 13:05:03 -1000, Nathan Chancellor wrote:
> Bump minimum version of LLVM for building the kernel to 17.0.1
> 
> The current minimum version of LLVM for building the kernel is 15.0.0.
> However, there are two deficiencies compared to GCC that were fixed in
> LLVM 17 that are starting to become more noticeable.
> 
> The first was a bug in LLVM's scope checker [1], where all labels in a
> function were validated as potential targets of an asm goto statement,
> even if they were not listed in the asm goto statement as targets. This
> becomes particularly problematic when the cleanup attribute is used, as
> 
> [...]

Applied to

  https://git.kernel.org/pub/scm/linux/kernel/git/kbuild/linux.git kbuild-next

Thanks!

[01/16] kbuild: Bump minimum version of LLVM for building the kernel to 17.0.1
        https://git.kernel.org/kbuild/c/ce3267a39a92b
[02/16] security/Kconfig.hardening: Remove tautological condition from CC_HAS_ZERO_CALL_USED_REGS
        https://git.kernel.org/kbuild/c/813fe686e90b4
[03/16] security/Kconfig.hardening: Remove tautological condition from FORTIFY_SOURCE
        https://git.kernel.org/kbuild/c/8ad2017578c99
[04/16] security/Kconfig.hardening: Remove tautological condition from CC_HAS_RANDSTRUCT
        https://git.kernel.org/kbuild/c/9331258bc129a
[05/16] arch/Kconfig: Remove tautological conditions from HAS_LTO_CLANG
        https://git.kernel.org/kbuild/c/2189cb1a80f06
[06/16] arch/Kconfig: Remove tautological condition from AUTOFDO_CLANG
        https://git.kernel.org/kbuild/c/de0bf1e138fcd
[07/16] ARM: Drop tautological ld.lld conditions from ARCH_MULTI_V4{,T}
        https://git.kernel.org/kbuild/c/48d229b6a48ae
[08/16] riscv: Remove tautological condition from selection of ARCH_SUPPORTS_CFI
        https://git.kernel.org/kbuild/c/62c4af8689511
[09/16] riscv: Drop tautological condition from TOOLCHAIN_NEEDS_OLD_ISA_SPEC
        https://git.kernel.org/kbuild/c/7e279976cf2a2
[10/16] scripts/Makefile.warn: Drop -Wformat handling for clang < 16
        https://git.kernel.org/kbuild/c/2a35c63c6bc42
[11/16] x86/build: Drop unnecessary '-ffreestanding' addition to KBUILD_CFLAGS
        https://git.kernel.org/kbuild/c/7b3281fcb43c5
[12/16] x86/module: Revert "Deal with GOT based stack cookie load on Clang < 17"
        https://git.kernel.org/kbuild/c/12b7bf92bddd4
[13/16] x86/entry/vdso32: Remove conditional omission of '.cfi_offset eflags'
        https://git.kernel.org/kbuild/c/4e7af20d0d104
[14/16] kbuild: Remove check for broken scoping with clang < 17 in CC_HAS_ASM_GOTO_OUTPUT
        https://git.kernel.org/kbuild/c/f3de78cb19d12
[15/16] compiler-clang.h: Remove __cleanup -Wunused-variable workaround
        https://git.kernel.org/kbuild/c/c69eaa687667e
[16/16] compiler-clang.h: Drop explicit version number from "all" diagnostic macro
        https://git.kernel.org/kbuild/c/c919893eabb43

Please look out for regression or issue reports or other follow up
comments, as they may result in the patch/series getting dropped or
reverted. Patches applied to an "unstable" branch are accepted pending
wider testing in -next and any post-commit review; they will generally
be moved to the main branch in a week if no issues are found.

Best regards,
-- 
Cheers,
Nathan



^ permalink raw reply

* [PATCH 2/2] landlock: replace __sk_common struct sock field accesses
From: Matthieu Buffet @ 2026-06-09 21:15 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Matthieu Buffet, Günther Noack, Mikhail Ivanov, Tingmao Wang,
	konstantin.meskhidze, linux-security-module
In-Reply-To: <20260609211511.85630-1-matthieu@buffet.re>

Use the proper macro to access __sk_common.skc_family like everywhere
else.

Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
---
 security/landlock/net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/landlock/net.c b/security/landlock/net.c
index 111e58fd9325..fc2acf8bd898 100644
--- a/security/landlock/net.c
+++ b/security/landlock/net.c
@@ -71,7 +71,7 @@ static int current_check_access_socket(struct socket *const sock,
 	 * The socket is not locked, so sk_family can change concurrently
 	 * due to e.g. setsockopt(IPV6_ADDRFORM).
 	 */
-	sock_family = READ_ONCE(sock->sk->__sk_common.skc_family);
+	sock_family = READ_ONCE(sock->sk->sk_family);
 
 	switch (address->sa_family) {
 	case AF_UNSPEC:
-- 
2.47.3


^ permalink raw reply related

* [PATCH 1/2] landlock: Fix unmarked concurrent access to socket family
From: Matthieu Buffet @ 2026-06-09 21:15 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Matthieu Buffet, Günther Noack, Mikhail Ivanov, Tingmao Wang,
	konstantin.meskhidze, linux-security-module
In-Reply-To: <e561a8c3-de10-45ba-a931-27b9a5751dc9@buffet.re>

Socket family is read (twice) in a context where the socket is not
locked, so another thread can setsockopt(IPV6_ADDRFORM) to write it
concurrently. Add needed READ_ONCE() annotation.

Fixes: fff69fb03dde ("landlock: Support network rules with TCP bind and connect")
Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
---
 security/landlock/net.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/security/landlock/net.c b/security/landlock/net.c
index a38bdfcffc22..111e58fd9325 100644
--- a/security/landlock/net.c
+++ b/security/landlock/net.c
@@ -55,6 +55,7 @@ static int current_check_access_socket(struct socket *const sock,
 	const struct access_masks masks = {
 		.net = access_request,
 	};
+	unsigned short sock_family;
 	const struct landlock_cred_security *const subject =
 		landlock_get_applicable_subject(current_cred(), masks, NULL);
 	struct lsm_network_audit audit_net = {};
@@ -66,6 +67,12 @@ static int current_check_access_socket(struct socket *const sock,
 	if (addrlen < offsetofend(typeof(*address), sa_family))
 		return -EINVAL;
 
+	/*
+	 * The socket is not locked, so sk_family can change concurrently
+	 * due to e.g. setsockopt(IPV6_ADDRFORM).
+	 */
+	sock_family = READ_ONCE(sock->sk->__sk_common.skc_family);
+
 	switch (address->sa_family) {
 	case AF_UNSPEC:
 		if (access_request == LANDLOCK_ACCESS_NET_CONNECT_TCP) {
@@ -102,7 +109,7 @@ static int current_check_access_socket(struct socket *const sock,
 			 * these checks, but it is safer to return a proper
 			 * error and test consistency thanks to kselftest.
 			 */
-			if (sock->sk->__sk_common.skc_family == AF_INET) {
+			if (sock_family == AF_INET) {
 				const struct sockaddr_in *const sockaddr =
 					(struct sockaddr_in *)address;
 
@@ -180,7 +187,7 @@ static int current_check_access_socket(struct socket *const sock,
 	 * check, but it is safer to return a proper error and test
 	 * consistency thanks to kselftest.
 	 */
-	if (address->sa_family != sock->sk->__sk_common.skc_family &&
+	if (address->sa_family != sock_family &&
 	    address->sa_family != AF_UNSPEC)
 		return -EINVAL;
 

base-commit: 4c403b9ffc86358d5ae50e4121aaf541bdab04d8
-- 
2.47.3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox