* Re: [GIT PULL] selinux/selinux-pr-20260710
From: pr-tracker-bot @ 2026-07-11 3:07 UTC (permalink / raw)
To: Paul Moore; +Cc: Linus Torvalds, selinux, linux-security-module, linux-kernel
In-Reply-To: <44e0f55f936543053d657f0a86a53bd9@paul-moore.com>
The pull request you sent on Fri, 10 Jul 2026 15:13:45 -0400:
> https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git tags/selinux-pr-20260710
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/ccce5f6e7c86f103d76534e2d06d1c903dce551c
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [PATCH v2] NFSv4.2: fix nfs4_listxattr size accounting
From: Paul Moore @ 2026-07-10 22:20 UTC (permalink / raw)
To: Stephen Smalley
Cc: Anna Schumaker, Achilles Gaikwad, Trond Myklebust, linux-nfs,
linux-security-module, selinux
In-Reply-To: <CAHC9VhRq+Vth-4D4OHFAY_6hXqmj=MgTc_2G=3Ehr6bAQzp26Q@mail.gmail.com>
On Fri, Jul 10, 2026 at 5:55 PM Paul Moore <paul@paul-moore.com> wrote:
>
> On Fri, Jul 10, 2026 at 5:54 PM Paul Moore <paul@paul-moore.com> wrote:
> > On Thu, Jul 9, 2026 at 8:33 AM Stephen Smalley
> > <stephen.smalley.work@gmail.com> wrote:
> > > On Wed, Jul 8, 2026 at 4:11 PM Paul Moore <paul@paul-moore.com> wrote:
> > > > On Wed, Jul 8, 2026 at 2:54 PM Stephen Smalley
> > > > <stephen.smalley.work@gmail.com> wrote:
> > > > > On Tue, Jul 7, 2026 at 4:01 PM Paul Moore <paul@paul-moore.com> wrote:
> > > > > >
> > > > > > On Tue, Jul 7, 2026 at 3:12 PM Anna Schumaker <anna@kernel.org> wrote:
> > > > > > > On Tue, Jul 7, 2026, at 2:48 PM, Paul Moore wrote:
> > > > > > > > On Tue, Jul 7, 2026 at 11:24 AM Achilles Gaikwad
> > > > > > > > <achillesgaikwad@gmail.com> wrote:
> > > > > > > >>
> > > > > > > >> A call to listxattr() with a buffer size of 0 returns the actual
> > > > > > > >> size of the buffer needed for a subsequent call. On an NFSv4.2
> > > > > > > >> mount this triggers the following oops:
> > > > > > > >>
> > > > > > > >> [ 399.768687] BUG: kernel NULL pointer dereference, address: 0000000000000000
> > > > > > > >> [ 399.768705] RIP: 0010:_copy_from_pages+0x44/0xe0
> > > > > > > >> [ 399.768722] Call Trace:
> > > > > > > >> [ 399.768723] nfs4_xattr_alloc_entry+0x1bf/0x1e0
> > > > > > > >> [ 399.768730] nfs4_xattr_cache_set_list+0x43/0x1f0
> > > > > > > >> [ 399.768731] nfs4_listxattr+0x21f/0x250
> > > > > > > >> [ 399.768733] vfs_listxattr+0x55/0xa0
> > > > > > > >> [ 399.768736] listxattr+0x23/0x160
> > > > > > > >> [ 399.768737] path_listxattrat+0xba/0x1e0
> > > > > > > >> [ 399.768739] do_syscall_64+0xe2/0x680
> > > > > > > >>
> > > > > > > >> security_inode_listsecurity() (via the xattr_list_one() helper) now
> > > > > > > >> decrements the remaining size even when the buffer pointer is NULL, so
> > > > > > > >> in the size-query case, 'left' underflows to a huge size_t value. As a
> > > > > > > >> result, nfs4_listxattr_nfs4_user() treats the NULL buffer as a real one,
> > > > > > > >> leading to a NULL pointer dereference in _copy_from_pages().
> > > > > > > >>
> > > > > > > >> security_inode_listsecurity() does not return the number of bytes
> > > > > > > >> it added to the list, so the code derived it as
> > > > > > > >> 'size - error - left'. That is also wrong in the size-query case:
> > > > > > > >> the generic_listxattr() contribution is only subtracted from 'left'
> > > > > > > >> when a buffer is present. Thus, the query result comes up short by
> > > > > > > >> exactly that contribution (e.g., "system.nfs4_acl" on a mount with
> > > > > > > >> ACL support), and a caller that allocates the returned size gets
> > > > > > > >> -ERANGE on the subsequent call.
> > > > > > > >>
> > > > > > > >> Declare 'left' as ssize_t, use a scratch copy to measure security
> > > > > > > >> hook consumption, and only decrement 'left' if a buffer is present.
> > > > > > > >>
> > > > > > > >> Fixes: f71ece9712b7 ("security,fs,nfs,net: update security_inode_listsecurity() interface")
> > > > > > > >> Suggested-by: Paul Moore <paul@paul-moore.com>
> > > > > > > >> Signed-off-by: Achilles Gaikwad <achillesgaikwad@gmail.com>
> > > > > > > >> ---
> > > > > > > >> Changes in v2:
> > > > > > > >> - Use a scratch variable to track security label size directly,
> > > > > > > >> replacing the old formula that undercounted the size-query case.
> > > > > > > >> - Drop the now-unneeded NULL-buffer special case for
> > > > > > > >> nfs4_listxattr_nfs4_user().
> > > > > > > >> - Retitled from "fix nfs4_listxattr NULL pointer dereference"
> > > > > > > >> (the same accounting bug caused both the oops and the undercount).
> > > > > > > >> v1: https://lore.kernel.org/linux-nfs/20260703102759.9626-1-achillesgaikwad@gmail.com/
> > > > > > > >> fs/nfs/nfs4proc.c | 10 +++++++---
> > > > > > > >> 1 file changed, 7 insertions(+), 3 deletions(-)
> > > > > > > >
> > > > > > > > [CC'd the LSM and SELinux lists for visibility]
> > > > > > > >
> > > > > > > > Unfortunately my testing was unsuccessful due to an NFS problem that
> > > > > > > > started with the v7.2 merge window that I haven't had the time to
> > > > > > > > bisect yet. Assuming the NFS folks are okay with this change, I
> > > > > > > > figure they will want to send it up to Linus via their tree, if not
> > > > > > > > let me know and I can send this up via the LSM tree.
> > > > > > >
> > > > > > > Yeah, we'll send it through the NFS tree.
> > > > > >
> > > > > > Thanks Anna.
> > > > > >
> > > > > > > I'll be curious to hear
> > > > > > > what problem you're hitting, and what patch is the culprit once you
> > > > > > > do that bisect!
> > > > > >
> > > > > > Yes, me too :)
> > > > > >
> > > > > > I'm still working through a review backlog so it might be a bit before
> > > > > > I have a chance, but in case anyone wants to test it out, it's easily
> > > > > > reproduced using the selinux-testsuite and the NFS tests:
> > > > > >
> > > > > > https://github.com/SELinuxProject/selinux-testsuite#nfs
> > > > >
> > > > > They seem to pass for me with and without the patch (they don't
> > > > > exercise listxattr AFAIK).
> > > > > This was on the current selinux/dev branch, v7.2-rc1 based.
> > > >
> > > > They work for me on vanilla v7.1 and fail somewhere before vanilla
> > > > v7.2-rc1 (still bisecting).
> > > >
> > > > I wonder if there is an interaction problem with a recent userspace
> > > > update. What distro/userspace are you running for your tests? I'm
> > > > doing my testing on a relatively recent Rawhide.
> > >
> > > I was on F44, so yes, it could be a difference in e.g. coreutils or
> > > other userspace on rawhide that is tickling this particular bug.
> >
> > I haven't had a chance to look into this yet, but the git bisect just
> > produced the commit below as the offending commit:
> >
> > commit 01c2305795a3b6b164df48e72b12022a68fd60c1
> > Author: Jeff Layton <jlayton@kernel.org>
> > Date: Wed Mar 25 10:40:32 2026 -0400
>
> Ooops, nevermind, scratch that - I still have one more kernel to test.
... and scratch that, the offending commit was that one.
commit 01c2305795a3b6b164df48e72b12022a68fd60c1
Author: Jeff Layton <jlayton@kernel.org>
Date: Wed Mar 25 10:40:32 2026 -0400
nfsd: add netlink upcall for the nfsd.fh cache
Add netlink-based cache upcall support for the expkey (nfsd.fh) cache,
following the same pattern as the existing svc_export netlink support.
Add expkey to the cache-type enum, a new expkey attribute-set with
client, fsidtype, fsid, negative, expiry, and path fields, and the
expkey-get-reqs / expkey-set-reqs operations to the nfsd YAML spec
and generated headers.
Implement nfsd_nl_expkey_get_reqs_dumpit() which snapshots pending
expkey cache requests and sends each entry's seqno, client name,
fsidtype, and fsid over netlink.
Implement nfsd_nl_expkey_set_reqs_doit() which parses expkey cache
responses from userspace (client, fsidtype, fsid, expiry, and path
or negative flag) and updates the cache via svc_expkey_lookup() /
svc_expkey_update().
Wire up the expkey_notify() callback in svc_expkey_cache_template
so cache misses trigger NFSD_CMD_CACHE_NOTIFY multicast events with
NFSD_CACHE_TYPE_EXPKEY.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v2] NFSv4.2: fix nfs4_listxattr size accounting
From: Paul Moore @ 2026-07-10 21:55 UTC (permalink / raw)
To: Stephen Smalley
Cc: Anna Schumaker, Achilles Gaikwad, Trond Myklebust, linux-nfs,
linux-security-module, selinux
In-Reply-To: <CAHC9VhSxpAx+G35fbcMjJ1PfqJxDZYpTEu=qpO+0PQe=nkX5-g@mail.gmail.com>
On Fri, Jul 10, 2026 at 5:54 PM Paul Moore <paul@paul-moore.com> wrote:
> On Thu, Jul 9, 2026 at 8:33 AM Stephen Smalley
> <stephen.smalley.work@gmail.com> wrote:
> > On Wed, Jul 8, 2026 at 4:11 PM Paul Moore <paul@paul-moore.com> wrote:
> > > On Wed, Jul 8, 2026 at 2:54 PM Stephen Smalley
> > > <stephen.smalley.work@gmail.com> wrote:
> > > > On Tue, Jul 7, 2026 at 4:01 PM Paul Moore <paul@paul-moore.com> wrote:
> > > > >
> > > > > On Tue, Jul 7, 2026 at 3:12 PM Anna Schumaker <anna@kernel.org> wrote:
> > > > > > On Tue, Jul 7, 2026, at 2:48 PM, Paul Moore wrote:
> > > > > > > On Tue, Jul 7, 2026 at 11:24 AM Achilles Gaikwad
> > > > > > > <achillesgaikwad@gmail.com> wrote:
> > > > > > >>
> > > > > > >> A call to listxattr() with a buffer size of 0 returns the actual
> > > > > > >> size of the buffer needed for a subsequent call. On an NFSv4.2
> > > > > > >> mount this triggers the following oops:
> > > > > > >>
> > > > > > >> [ 399.768687] BUG: kernel NULL pointer dereference, address: 0000000000000000
> > > > > > >> [ 399.768705] RIP: 0010:_copy_from_pages+0x44/0xe0
> > > > > > >> [ 399.768722] Call Trace:
> > > > > > >> [ 399.768723] nfs4_xattr_alloc_entry+0x1bf/0x1e0
> > > > > > >> [ 399.768730] nfs4_xattr_cache_set_list+0x43/0x1f0
> > > > > > >> [ 399.768731] nfs4_listxattr+0x21f/0x250
> > > > > > >> [ 399.768733] vfs_listxattr+0x55/0xa0
> > > > > > >> [ 399.768736] listxattr+0x23/0x160
> > > > > > >> [ 399.768737] path_listxattrat+0xba/0x1e0
> > > > > > >> [ 399.768739] do_syscall_64+0xe2/0x680
> > > > > > >>
> > > > > > >> security_inode_listsecurity() (via the xattr_list_one() helper) now
> > > > > > >> decrements the remaining size even when the buffer pointer is NULL, so
> > > > > > >> in the size-query case, 'left' underflows to a huge size_t value. As a
> > > > > > >> result, nfs4_listxattr_nfs4_user() treats the NULL buffer as a real one,
> > > > > > >> leading to a NULL pointer dereference in _copy_from_pages().
> > > > > > >>
> > > > > > >> security_inode_listsecurity() does not return the number of bytes
> > > > > > >> it added to the list, so the code derived it as
> > > > > > >> 'size - error - left'. That is also wrong in the size-query case:
> > > > > > >> the generic_listxattr() contribution is only subtracted from 'left'
> > > > > > >> when a buffer is present. Thus, the query result comes up short by
> > > > > > >> exactly that contribution (e.g., "system.nfs4_acl" on a mount with
> > > > > > >> ACL support), and a caller that allocates the returned size gets
> > > > > > >> -ERANGE on the subsequent call.
> > > > > > >>
> > > > > > >> Declare 'left' as ssize_t, use a scratch copy to measure security
> > > > > > >> hook consumption, and only decrement 'left' if a buffer is present.
> > > > > > >>
> > > > > > >> Fixes: f71ece9712b7 ("security,fs,nfs,net: update security_inode_listsecurity() interface")
> > > > > > >> Suggested-by: Paul Moore <paul@paul-moore.com>
> > > > > > >> Signed-off-by: Achilles Gaikwad <achillesgaikwad@gmail.com>
> > > > > > >> ---
> > > > > > >> Changes in v2:
> > > > > > >> - Use a scratch variable to track security label size directly,
> > > > > > >> replacing the old formula that undercounted the size-query case.
> > > > > > >> - Drop the now-unneeded NULL-buffer special case for
> > > > > > >> nfs4_listxattr_nfs4_user().
> > > > > > >> - Retitled from "fix nfs4_listxattr NULL pointer dereference"
> > > > > > >> (the same accounting bug caused both the oops and the undercount).
> > > > > > >> v1: https://lore.kernel.org/linux-nfs/20260703102759.9626-1-achillesgaikwad@gmail.com/
> > > > > > >> fs/nfs/nfs4proc.c | 10 +++++++---
> > > > > > >> 1 file changed, 7 insertions(+), 3 deletions(-)
> > > > > > >
> > > > > > > [CC'd the LSM and SELinux lists for visibility]
> > > > > > >
> > > > > > > Unfortunately my testing was unsuccessful due to an NFS problem that
> > > > > > > started with the v7.2 merge window that I haven't had the time to
> > > > > > > bisect yet. Assuming the NFS folks are okay with this change, I
> > > > > > > figure they will want to send it up to Linus via their tree, if not
> > > > > > > let me know and I can send this up via the LSM tree.
> > > > > >
> > > > > > Yeah, we'll send it through the NFS tree.
> > > > >
> > > > > Thanks Anna.
> > > > >
> > > > > > I'll be curious to hear
> > > > > > what problem you're hitting, and what patch is the culprit once you
> > > > > > do that bisect!
> > > > >
> > > > > Yes, me too :)
> > > > >
> > > > > I'm still working through a review backlog so it might be a bit before
> > > > > I have a chance, but in case anyone wants to test it out, it's easily
> > > > > reproduced using the selinux-testsuite and the NFS tests:
> > > > >
> > > > > https://github.com/SELinuxProject/selinux-testsuite#nfs
> > > >
> > > > They seem to pass for me with and without the patch (they don't
> > > > exercise listxattr AFAIK).
> > > > This was on the current selinux/dev branch, v7.2-rc1 based.
> > >
> > > They work for me on vanilla v7.1 and fail somewhere before vanilla
> > > v7.2-rc1 (still bisecting).
> > >
> > > I wonder if there is an interaction problem with a recent userspace
> > > update. What distro/userspace are you running for your tests? I'm
> > > doing my testing on a relatively recent Rawhide.
> >
> > I was on F44, so yes, it could be a difference in e.g. coreutils or
> > other userspace on rawhide that is tickling this particular bug.
>
> I haven't had a chance to look into this yet, but the git bisect just
> produced the commit below as the offending commit:
>
> commit 01c2305795a3b6b164df48e72b12022a68fd60c1
> Author: Jeff Layton <jlayton@kernel.org>
> Date: Wed Mar 25 10:40:32 2026 -0400
Ooops, nevermind, scratch that - I still have one more kernel to test.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v2] NFSv4.2: fix nfs4_listxattr size accounting
From: Paul Moore @ 2026-07-10 21:54 UTC (permalink / raw)
To: Stephen Smalley
Cc: Anna Schumaker, Achilles Gaikwad, Trond Myklebust, linux-nfs,
linux-security-module, selinux
In-Reply-To: <CAEjxPJ4+wgUDY3YxajZ=2D3WLzgat_Mqvr05VtJ4KrXW7_kuXA@mail.gmail.com>
On Thu, Jul 9, 2026 at 8:33 AM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
> On Wed, Jul 8, 2026 at 4:11 PM Paul Moore <paul@paul-moore.com> wrote:
> > On Wed, Jul 8, 2026 at 2:54 PM Stephen Smalley
> > <stephen.smalley.work@gmail.com> wrote:
> > > On Tue, Jul 7, 2026 at 4:01 PM Paul Moore <paul@paul-moore.com> wrote:
> > > >
> > > > On Tue, Jul 7, 2026 at 3:12 PM Anna Schumaker <anna@kernel.org> wrote:
> > > > > On Tue, Jul 7, 2026, at 2:48 PM, Paul Moore wrote:
> > > > > > On Tue, Jul 7, 2026 at 11:24 AM Achilles Gaikwad
> > > > > > <achillesgaikwad@gmail.com> wrote:
> > > > > >>
> > > > > >> A call to listxattr() with a buffer size of 0 returns the actual
> > > > > >> size of the buffer needed for a subsequent call. On an NFSv4.2
> > > > > >> mount this triggers the following oops:
> > > > > >>
> > > > > >> [ 399.768687] BUG: kernel NULL pointer dereference, address: 0000000000000000
> > > > > >> [ 399.768705] RIP: 0010:_copy_from_pages+0x44/0xe0
> > > > > >> [ 399.768722] Call Trace:
> > > > > >> [ 399.768723] nfs4_xattr_alloc_entry+0x1bf/0x1e0
> > > > > >> [ 399.768730] nfs4_xattr_cache_set_list+0x43/0x1f0
> > > > > >> [ 399.768731] nfs4_listxattr+0x21f/0x250
> > > > > >> [ 399.768733] vfs_listxattr+0x55/0xa0
> > > > > >> [ 399.768736] listxattr+0x23/0x160
> > > > > >> [ 399.768737] path_listxattrat+0xba/0x1e0
> > > > > >> [ 399.768739] do_syscall_64+0xe2/0x680
> > > > > >>
> > > > > >> security_inode_listsecurity() (via the xattr_list_one() helper) now
> > > > > >> decrements the remaining size even when the buffer pointer is NULL, so
> > > > > >> in the size-query case, 'left' underflows to a huge size_t value. As a
> > > > > >> result, nfs4_listxattr_nfs4_user() treats the NULL buffer as a real one,
> > > > > >> leading to a NULL pointer dereference in _copy_from_pages().
> > > > > >>
> > > > > >> security_inode_listsecurity() does not return the number of bytes
> > > > > >> it added to the list, so the code derived it as
> > > > > >> 'size - error - left'. That is also wrong in the size-query case:
> > > > > >> the generic_listxattr() contribution is only subtracted from 'left'
> > > > > >> when a buffer is present. Thus, the query result comes up short by
> > > > > >> exactly that contribution (e.g., "system.nfs4_acl" on a mount with
> > > > > >> ACL support), and a caller that allocates the returned size gets
> > > > > >> -ERANGE on the subsequent call.
> > > > > >>
> > > > > >> Declare 'left' as ssize_t, use a scratch copy to measure security
> > > > > >> hook consumption, and only decrement 'left' if a buffer is present.
> > > > > >>
> > > > > >> Fixes: f71ece9712b7 ("security,fs,nfs,net: update security_inode_listsecurity() interface")
> > > > > >> Suggested-by: Paul Moore <paul@paul-moore.com>
> > > > > >> Signed-off-by: Achilles Gaikwad <achillesgaikwad@gmail.com>
> > > > > >> ---
> > > > > >> Changes in v2:
> > > > > >> - Use a scratch variable to track security label size directly,
> > > > > >> replacing the old formula that undercounted the size-query case.
> > > > > >> - Drop the now-unneeded NULL-buffer special case for
> > > > > >> nfs4_listxattr_nfs4_user().
> > > > > >> - Retitled from "fix nfs4_listxattr NULL pointer dereference"
> > > > > >> (the same accounting bug caused both the oops and the undercount).
> > > > > >> v1: https://lore.kernel.org/linux-nfs/20260703102759.9626-1-achillesgaikwad@gmail.com/
> > > > > >> fs/nfs/nfs4proc.c | 10 +++++++---
> > > > > >> 1 file changed, 7 insertions(+), 3 deletions(-)
> > > > > >
> > > > > > [CC'd the LSM and SELinux lists for visibility]
> > > > > >
> > > > > > Unfortunately my testing was unsuccessful due to an NFS problem that
> > > > > > started with the v7.2 merge window that I haven't had the time to
> > > > > > bisect yet. Assuming the NFS folks are okay with this change, I
> > > > > > figure they will want to send it up to Linus via their tree, if not
> > > > > > let me know and I can send this up via the LSM tree.
> > > > >
> > > > > Yeah, we'll send it through the NFS tree.
> > > >
> > > > Thanks Anna.
> > > >
> > > > > I'll be curious to hear
> > > > > what problem you're hitting, and what patch is the culprit once you
> > > > > do that bisect!
> > > >
> > > > Yes, me too :)
> > > >
> > > > I'm still working through a review backlog so it might be a bit before
> > > > I have a chance, but in case anyone wants to test it out, it's easily
> > > > reproduced using the selinux-testsuite and the NFS tests:
> > > >
> > > > https://github.com/SELinuxProject/selinux-testsuite#nfs
> > >
> > > They seem to pass for me with and without the patch (they don't
> > > exercise listxattr AFAIK).
> > > This was on the current selinux/dev branch, v7.2-rc1 based.
> >
> > They work for me on vanilla v7.1 and fail somewhere before vanilla
> > v7.2-rc1 (still bisecting).
> >
> > I wonder if there is an interaction problem with a recent userspace
> > update. What distro/userspace are you running for your tests? I'm
> > doing my testing on a relatively recent Rawhide.
>
> I was on F44, so yes, it could be a difference in e.g. coreutils or
> other userspace on rawhide that is tickling this particular bug.
I haven't had a chance to look into this yet, but the git bisect just
produced the commit below as the offending commit:
commit 01c2305795a3b6b164df48e72b12022a68fd60c1
Author: Jeff Layton <jlayton@kernel.org>
Date: Wed Mar 25 10:40:32 2026 -0400
nfsd: add netlink upcall for the nfsd.fh cache
Add netlink-based cache upcall support for the expkey (nfsd.fh) cache,
following the same pattern as the existing svc_export netlink support.
Add expkey to the cache-type enum, a new expkey attribute-set with
client, fsidtype, fsid, negative, expiry, and path fields, and the
expkey-get-reqs / expkey-set-reqs operations to the nfsd YAML spec
and generated headers.
Implement nfsd_nl_expkey_get_reqs_dumpit() which snapshots pending
expkey cache requests and sends each entry's seqno, client name,
fsidtype, and fsid over netlink.
Implement nfsd_nl_expkey_set_reqs_doit() which parses expkey cache
responses from userspace (client, fsidtype, fsid, expiry, and path
or negative flag) and updates the cache via svc_expkey_lookup() /
svc_expkey_update().
Wire up the expkey_notify() callback in svc_expkey_cache_template
so cache misses trigger NFSD_CMD_CACHE_NOTIFY multicast events with
NFSD_CACHE_TYPE_EXPKEY.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
--
paul-moore.com
^ permalink raw reply
* İlt: Re: [RESEND][RFC/discuss] memfd_secret(): opt-in visibility for security monitoring (eBPF/audit)
From: BoxStrikesTeam @ 2026-07-10 21:51 UTC (permalink / raw)
To: paul@paul-moore.com
Cc: akpm@linux-foundation.org, rppt@kernel.org, linux-mm@kvack.org,
linux-security-module@vger.kernel.org, serge@hallyn.com,
jmorris@namei.org
In-Reply-To: <CAHC9VhSWs4=-BN09XWUsJXh+9HB5zeYa0oiRsRNGb4s_sTW2HQ@mail.gmail.com>
Proton Mail güvenli e-posta ile gönderildi.
------- Forwarded Message -------
Kimden: Paul Moore <paul@paul-moore.com>
Tarih: 11 Temmuz 2026 Cumartesi saat 00:00
Konu: Re: [RESEND][RFC/discuss] memfd_secret(): opt-in visibility for security monitoring (eBPF/audit)
Kime: BoxStrikesTeam <BoxStrikesTeam@proton.me>
CC: rppt@kernel.org <rppt@kernel.org>, akpm@linux-foundation.org <akpm@linux-foundation.org>, linux-mm@kvack.org <linux-mm@kvack.org>, linux-security-module@vger.kernel.org <linux-security-module@vger.kernel.org>, jmorris@namei.org <jmorris@namei.org>, serge@hallyn.com <serge@hallyn.com>
> On Thu, Jul 9, 2026 at 1:14 AM BoxStrikesTeam <BoxStrikesTeam@proton.me> wrote:
> > Paul,
> >
> > Thanks - I found the Gottsche/inode_init_security_anon() thread and can see it landed. That answers (a) cleanly: labeling exists, policy can be layered on top via SELinux/AppArmor if a site wants alerting on memfd_secret() creation. Good to have that confirmed as already solved.
> >
> > On (b), let me push on it a bit further, because I think it's worth spelling out explicitly rather than dropping it.
> >
> > My concern: as it stands, an unprivileged process can populate a memfd_secret() region and mseal() the mapping, producing memory that is (a) unreadable by any kernel-side introspection path, including root-owned eBPF tracing programs, and (b) can't be coerced back into an inspectable state via mprotect/munmap. From a host-based detection standpoint that's a blind spot an attacker can use to park a payload where a CAP_BPF-privileged monitoring agent - something that in most other respects can inspect any process on the box - simply cannot look, no matter what capabilities it holds.
> >
> > I understand the objection this invites, and I want to address it directly rather than pretend it isn't there: the memfd_secret() man page is explicit that its ROP protection rests on the absence of any in-kernel primitive for reading this memory. If I'm reading that right, the objection to (b) is that adding any such primitive - however capability-gated - re-creates exactly the artifact a ROP chain would want to call, undermining the "no primitive exists" property regardless of who's nominally allowed to invoke it.
> >
> > I don't think that objection is wrong, but I'm not sure it's fully dispositive either, and I'd like to hear the maintainers' take on the tradeoff explicitly:
> >
> > - The ROP threat model assumes an attacker who already has arbitrary kernel code execution (they're calling kernel functions directly). If they have that, they can likely already walk page tables and reconstruct the mapping by hand - the primitive removal raises the bar, but per the design's own caveat ("no 100% guarantee"), it was never advertised as absolute.
> > - The (b) scenario I'm raising is a different actor: a legitimate, privileged, kernel-mediated monitoring agent (eBPF LSM/tracing program) operating through the normal verifier-checked helper path, not an attacker executing arbitrary kernel code via a ROP chain. Conflating "any code path that can read this memory" with "a gadget a ROP chain can call" may be overly conservative if the new path is narrowly scoped (e.g., a new bpf_probe_read_secretmem() helper, verifier-restricted to CAP_PERFMON|CAP_BPF programs, opt-in per region via a memfd_secret() flag the owning process must set at creation time).
> >
> > If that distinction doesn't hold up - if any additional kernel-callable read path is considered equally exploitable regardless of gating - I'd genuinely like to understand why, since it would mean the confidentiality guarantee is fundamentally incompatible with any form of authorized introspection, which seems worth stating plainly in the documentation for anyone building EDR/monitoring tooling around eBPF.
> >
> > Even if (b) is rejected, I believe explicitly documenting that memfd_secret()+mseal() creates an introspection-proof region would be valuable for the security community, so EDR vendors can adjust their threat models accordingly.
>
> To be very honest, I'm not too concerned about out-of-tree, security
> products; I'm focused on the in-tree kernel code. If you are
> concerned about userspace making use of memfd_secret(), you could
> block the operation on a per-process/domain basis using either seccomp
> or SELinux (other LSMs may have similar functionality, that's an
> exercise left to the reader).
>
> Also, it is important to note that if you find the kernel
> documentation lacking in a particular area, I would encourage you to
> submit a patch to address the shortcomings.
>
> --
> paul-moore.com
>
Paul,
Thanks for the discussion and for the pointer to secretmem_file_create() — that resolves (a) for me.
On (b), I've thought about it further and agree a kernel patch isn't the right answer here. A few closing observations for the record:
1. Dynamic detection isn't actually closed off by memfd_secret()+mseal(). Every syscall a payload makes traps through the normal syscall entry path, and pt_regs->ip at that point reflects the calling address regardless of whether that address sits inside a secretmem VMA. Cross-referencing that IP against /proc/pid/maps (or vma->vm_start/vm_end in-kernel) lets a tracer attribute syscalls to a secretmem-backed region without ever reading the region's contents. So the confidentiality guarantee holds, but it doesn't buy an attacker syscall-level anonymity — only content opacity.
2. That said, I recognize this is a bypassable heuristic on its own (an attacker can proxy syscalls through a separate, non-secretmem code path), which is why I don't think dynamic detection alone is a complete answer either.
3. The more durable idea, I think, is one that doesn't touch confidentiality at all: hooking the memfd_secret()/mmap()/mseal() call sites and building a signature purely from call metadata — arguments, region size, protection flags, and the sequence/timing of these calls — rather than from region contents. This gives EDR/eBPF tooling something for static/behavioral matching without requiring any new in-kernel read primitive, since none of that metadata is protected by secretmem's threat model. This is achievable entirely in userspace/eBPF today with existing hooks, so no kernel change is needed for it either.
Given that, I don't think there's a kernel patch to propose here. This looks like it's squarely a detection-engineering problem for security products to solve on top of existing tracepoints, not a kernel gap. I'll leave the follow-through on that side to the community.
Thanks again for engaging with this — appreciated the back and forth.
Best,
Eneshan Erdoğan Karaca
^ permalink raw reply
* Re: [RESEND][RFC/discuss] memfd_secret(): opt-in visibility for security monitoring (eBPF/audit)
From: Paul Moore @ 2026-07-10 21:00 UTC (permalink / raw)
To: BoxStrikesTeam
Cc: rppt@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org,
linux-security-module@vger.kernel.org, jmorris@namei.org,
serge@hallyn.com
In-Reply-To: <MZlCECz5s73hPgQxtqWZ2VbXNTCZnItnwMHu2iZQlRC6ba0B9GuqxT2EhvhwQ-uanBDsNn7Bg09nGVynBHdmSsiRjhyI1udkYbqOoPfpe6w=@proton.me>
On Thu, Jul 9, 2026 at 1:14 AM BoxStrikesTeam <BoxStrikesTeam@proton.me> wrote:
> Paul,
>
> Thanks - I found the Gottsche/inode_init_security_anon() thread and can see it landed. That answers (a) cleanly: labeling exists, policy can be layered on top via SELinux/AppArmor if a site wants alerting on memfd_secret() creation. Good to have that confirmed as already solved.
>
> On (b), let me push on it a bit further, because I think it's worth spelling out explicitly rather than dropping it.
>
> My concern: as it stands, an unprivileged process can populate a memfd_secret() region and mseal() the mapping, producing memory that is (a) unreadable by any kernel-side introspection path, including root-owned eBPF tracing programs, and (b) can't be coerced back into an inspectable state via mprotect/munmap. From a host-based detection standpoint that's a blind spot an attacker can use to park a payload where a CAP_BPF-privileged monitoring agent - something that in most other respects can inspect any process on the box - simply cannot look, no matter what capabilities it holds.
>
> I understand the objection this invites, and I want to address it directly rather than pretend it isn't there: the memfd_secret() man page is explicit that its ROP protection rests on the absence of any in-kernel primitive for reading this memory. If I'm reading that right, the objection to (b) is that adding any such primitive - however capability-gated - re-creates exactly the artifact a ROP chain would want to call, undermining the "no primitive exists" property regardless of who's nominally allowed to invoke it.
>
> I don't think that objection is wrong, but I'm not sure it's fully dispositive either, and I'd like to hear the maintainers' take on the tradeoff explicitly:
>
> - The ROP threat model assumes an attacker who already has arbitrary kernel code execution (they're calling kernel functions directly). If they have that, they can likely already walk page tables and reconstruct the mapping by hand - the primitive removal raises the bar, but per the design's own caveat ("no 100% guarantee"), it was never advertised as absolute.
> - The (b) scenario I'm raising is a different actor: a legitimate, privileged, kernel-mediated monitoring agent (eBPF LSM/tracing program) operating through the normal verifier-checked helper path, not an attacker executing arbitrary kernel code via a ROP chain. Conflating "any code path that can read this memory" with "a gadget a ROP chain can call" may be overly conservative if the new path is narrowly scoped (e.g., a new bpf_probe_read_secretmem() helper, verifier-restricted to CAP_PERFMON|CAP_BPF programs, opt-in per region via a memfd_secret() flag the owning process must set at creation time).
>
> If that distinction doesn't hold up - if any additional kernel-callable read path is considered equally exploitable regardless of gating - I'd genuinely like to understand why, since it would mean the confidentiality guarantee is fundamentally incompatible with any form of authorized introspection, which seems worth stating plainly in the documentation for anyone building EDR/monitoring tooling around eBPF.
>
> Even if (b) is rejected, I believe explicitly documenting that memfd_secret()+mseal() creates an introspection-proof region would be valuable for the security community, so EDR vendors can adjust their threat models accordingly.
To be very honest, I'm not too concerned about out-of-tree, security
products; I'm focused on the in-tree kernel code. If you are
concerned about userspace making use of memfd_secret(), you could
block the operation on a per-process/domain basis using either seccomp
or SELinux (other LSMs may have similar functionality, that's an
exercise left to the reader).
Also, it is important to note that if you find the kernel
documentation lacking in a particular area, I would encourage you to
submit a patch to address the shortcomings.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v2 1/9] security: add LSM blob and hooks for namespaces
From: Paul Moore @ 2026-07-10 20:42 UTC (permalink / raw)
To: Mickaël Salaün
Cc: Christian Brauner, Günther Noack, Serge E . Hallyn,
Daniel Durning, Jonathan Corbet, Justin Suess, Lennart Poettering,
Mikhail Ivanov, Nicolas Bouchinet, Shervin Oloumi, Tingmao Wang,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module
In-Reply-To: <20260709.paitheut7Ief@digikod.net>
On Thu, Jul 9, 2026 at 11:58 AM Mickaël Salaün <mic@digikod.net> wrote:
> On Thu, Jul 09, 2026 at 09:03:58AM -0400, Paul Moore wrote:
> > On Thu, Jul 9, 2026 at 5:12 AM Mickaël Salaün <mic@digikod.net> wrote:
> > > On Wed, Jul 08, 2026 at 11:22:17PM -0400, Paul Moore wrote:
> > > > On May 27, 2026 =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= <mic@digikod.net> wrote:
...
> > I'm aware of the new hook guidance, I was the one who documented it :)
>
> I know. I guess that means you're ok with that?
Yes.
Just a heads-up, and some of this depends on timing, but as we've got
multiple patchsets (there is a SELinux patchset that depends on these
hooks) I'll want to take this hook additions via the LSM tree. I can
take the associated Landlock patches too if you like, or you base the
Landlock tree off the LSM branch; no worries either way, we can sort
out the details once the patchset is ready for merging.
--
paul-moore.com
^ permalink raw reply
* [GIT PULL] selinux/selinux-pr-20260710
From: Paul Moore @ 2026-07-10 19:13 UTC (permalink / raw)
To: Linus Torvalds; +Cc: selinux, linux-security-module, linux-kernel
Linus,
Two small SELinux patches to fix a missing permission check for
TCP Fast Open operations and fix a socket lookup issue with SCTP ASCONF
operations.
Paul
--
The following changes since commit dc59e4fea9d83f03bad6bddf3fa2e52491777482:
Linux 7.2-rc1 (2026-06-28 12:01:31 -0700)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git
tags/selinux-pr-20260710
for you to fetch changes up to 56acfeb10019e200ab6787d01f8d7cbe0f01526f:
selinux: avoid sk_socket dereference in selinux_sctp_bind_connect()
(2026-07-01 18:22:22 -0400)
----------------------------------------------------------------
selinux/stable-7.2 PR 20260710
----------------------------------------------------------------
Stephen Smalley (1):
selinux: check connect-related permissions on TCP Fast Open
Tristan Madani (1):
selinux: avoid sk_socket dereference in
selinux_sctp_bind_connect()
security/selinux/hooks.c | 38 ++++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH 2/2] module: Bring includes in linux/kmod.h up to date
From: Aaron Tomlin @ 2026-07-10 13:57 UTC (permalink / raw)
To: Petr Pavlu
Cc: Tony Luck, Borislav Petkov, Thomas Gleixner, Ingo Molnar,
Dave Hansen, x86, H. Peter Anvin, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Johan Hovold, Alex Elder,
Greg Kroah-Hartman, Rafael J. Wysocki, Michal Januszewski,
Helge Deller, Alexander Viro, Christian Brauner, Jan Kara,
Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey, Mark Fasheh,
Joel Becker, Joseph Qi, Tejun Heo, Johannes Weiner,
Michal Koutný, Luis Chamberlain, Daniel Gomez, Sami Tolvanen,
Pavel Machek, Len Brown, Andrew Morton, Danilo Krummrich,
Nikolay Aleksandrov, Ido Schimmel, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, David Howells,
Jarkko Sakkinen, Paul Moore, James Morris, Serge E. Hallyn,
Kentaro Takeda, Tetsuo Handa, linux-edac, linux-kernel, drbd-dev,
linux-block, greybus-dev, linuxppc-dev, linux-acpi, linux-fbdev,
dri-devel, linux-fsdevel, linux-nfs, ocfs2-devel, cgroups,
linux-modules, linux-pm, driver-core, bridge, netdev, keyrings,
linux-security-module
In-Reply-To: <20260708154510.6794-3-petr.pavlu@suse.com>
On Wed, Jul 08, 2026 at 05:44:30PM +0200, Petr Pavlu wrote:
> Including linux/kmod.h alone results in 1.5 MB of preprocessed output, even
> though it provides only a few functions and macros.
>
> The header currently depends on:
>
> * __printf() -> linux/compiler_attributes.h,
> * ENOSYS -> linux/errno.h,
> * bool -> linux/types.h.
>
> Include only these files, reducing the preprocessed output to 10 kB.
>
> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
> ---
> include/linux/kmod.h | 12 ++----------
> 1 file changed, 2 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/kmod.h b/include/linux/kmod.h
> index 9a07c3215389..b9474a62a568 100644
> --- a/include/linux/kmod.h
> +++ b/include/linux/kmod.h
> @@ -2,17 +2,9 @@
> #ifndef __LINUX_KMOD_H__
> #define __LINUX_KMOD_H__
>
> -/*
> - * include/linux/kmod.h
> - */
> -
> -#include <linux/umh.h>
> -#include <linux/gfp.h>
> -#include <linux/stddef.h>
> +#include <linux/compiler_attributes.h>
> #include <linux/errno.h>
> -#include <linux/compiler.h>
> -#include <linux/workqueue.h>
> -#include <linux/sysctl.h>
> +#include <linux/types.h>
>
> #ifdef CONFIG_MODULES
> /* modprobe exit status on success, -ve on error. Return value
> --
> 2.54.0
>
LGTM. Thank you.
Reviewed-by: Aaron Tomlin <atomlin@atomlin.com>
--
Aaron Tomlin
^ permalink raw reply
* Re: [PATCH 0/3] Implement LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC
From: Justin Suess @ 2026-07-10 13:56 UTC (permalink / raw)
To: Mickaël Salaün; +Cc: linux-security-module, gnoack
In-Reply-To: <20260709.Eaphooyoh6sh@digikod.net>
On Thu, Jul 09, 2026 at 12:09:25PM +0200, Mickaël Salaün wrote:
> Hi Justin,
>
> Thanks for this patch series, I like the underlying idea, but I'm not
> convince we should mix NNP and ON_EXEC. Why not a
> LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS flag instead?
>
tldr I think your idea is better, see below.
> One issue with this NNP_ON_EXEC is that it might be confusing for one
> thread to set it and expect the next exec to be NNP, but if the exec is
> requested by another thread that would not happen. With a
> LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS flag, we could have an atomic
> Landlock and NNP enforcement, which can also be combined with the TSYNC
> flag, both useful cases.
>
> If we want an enforcement to happen at exec time, we could add a
> dedicated flag, similar to the TSYNC one, but I'm not sure it would be
> useful for now.
>
> On Wed, Jul 08, 2026 at 09:39:24AM -0400, Justin Suess wrote:
> > Good morning,
> >
> > This series adds a new landlock_restrict_self(2) flag:
> > LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC.
> >
> > This flag stages a bit in the Landlock credentials indicating that the
> > next successful execution will set the no_new_privs attribute while
> > committing its new credentials.
> >
> > Differences from prctl(PR_SET_NO_NEW_PRIVS):
> >
> > PR_SET_NO_NEW_PRIVS takes effect immediately: it prevents gaining
> > privileges through set-user-ID, set-group-ID and file capabilities
> > starting with the very next execve(2).
> >
> > LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC instead only sets the task's
> > no_new_privs attribute once the next execve(2) is guaranteed to succeed
> > (past its point of no return, in bprm_committing_creds), after any
> > privilege gain through set-user-ID, set-group-ID or file capabilities
> > has already taken place. The executed program then runs with
> > no_new_privs, so subsequent executions cannot gain privileges. A
> > failed execve(2) leaves no_new_privs untouched.
> >
> > Use cases:
> >
> > Enforcing a Landlock ruleset requires that the calling process either
> > already has no_new_privs set or possesses CAP_SYS_ADMIN. This series
> > does not grant any exception to this rule; for a caller that already
> > has no_new_privs set, the flag is effectively a no-op. It is therefore
> > mostly useful for CAP_SYS_ADMIN callers that need to execute programs
> > that legitimately escalate privileges (e.g. transition to another
> > user), while ensuring that further executions cannot gain privileges.
>
> That's a good point, but why not just set NNP for the whole process at
> landlock_restrict_self() call time? There is a partial answer below
> but...
>
Atomically with respect to the ruleset enforcement I presume?
I guess that makes this even easier... just run it at the end after all
possible errors in the landlock_restrict_self path.
In this case then, we must consider whether this would be sufficient to
serve as a substitute for NNP || cap_sys_admin check.
> >
> > Consider a sandbox launcher that depends on a set-user-ID helper, such
> > as launching applications through bubblewrap on distributions where
> > unprivileged user namespaces are disabled and bwrap is installed
> > set-user-ID root. The launcher cannot set PR_SET_NO_NEW_PRIVS before
> > the execution, as that would neuter the very helper it depends on:
> >
> > sandbox launcher (CAP_SYS_ADMIN)
> > |
> > | landlock_restrict_self(-1, LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC)
> > V
> > /usr/bin/bwrap (set-user-ID root: honored for this execution;
> > | no_new_privs set once the execution is past its
> > | point of no return)
>
> This should only be allowed if the launcher has CAP_SYS_ADMIN, otherwise
> it would be like changing the state of a more privileged process.
> Anyway, even with this safeguard, this approach looks risky.
>
Yes, and it does have CAP_SYS_ADMIN in this example. It "feels" risky
though to mess with further escalations. But if you are CAP_SYS_ADMIN,
you can load kernel modules, potentially write to any memory, etc.
So that is less the argument I would make.
I think the main argument that hasn't been highlighted yet against *my
proposal* (I like to red team my own proposals) is that this whole
thing has nothing to do with Landlock. My feature doesn't touch Landlock
rulesets, or anything Landlock specific, so if this were implemented,
why not just make it a prctl? Why tie it to an LSM at all?
So I like your proposal better (atomic nnp with Landlock) because it's
actually relevant to Landlock rulesets.
The last remaining questions:
1. Shall the NNP || cap_sys_admin check remain in place for the NNP Landlock flag?
2. Should we allow enforcement with ruleset_fd being -1 (would basically
be equivalent to the prctl version of set no new privs)?
Justin
> > V
> > sandboxed application (runs with no_new_privs; cannot gain
> > privileges through any further execution, and
> > may enforce its own Landlock ruleset without
> > CAP_SYS_ADMIN)
> >
> > This flag also closes a gap for CAP_SYS_ADMIN callers of
> > landlock_restrict_self(2) itself. The no_new_privs/CAP_SYS_ADMIN
> > requirement exists to keep set-user-ID programs from running confused
> > inside a sandbox they do not expect. However, a privileged process
> > that enforces a domain without setting no_new_privs leaves that hole
> > open for all of its descendants: anything running in the domain may
> > still execute a set-user-ID binary, which then runs privileged under a
> > restricted view of the system. A privileged process that needs one
> > legitimate set-user-ID/set-group-ID transition currently has to choose
> > between breaking that transition (setting no_new_privs first) or
> > leaving the hole open for the lifetime of the domain.
> > LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC allows the one intended transition
> > and then closes the hole.
>
> In a nutshell, not setting NNP might be risky, even when not strictly
> needed. We might want to update the Landlock doc with that.
>
Yes, I
> >
> > Design:
> >
> > This flag is implemented simply: a bit is stored in the Landlock
> > credential blob (struct landlock_cred_security) indicating whether the
> > next execution should set no_new_privs when it commits its new
> > credentials.
>
> Also, if we don't have the ON_EXEC part, there is no need to store
> anything in the cred.
>
> >
> > The bit is not coupled to any ruleset and, like
> > LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF, may be passed with no
> > ruleset (i.e. ruleset_fd = -1). It may also be combined with
> > LANDLOCK_RESTRICT_SELF_TSYNC to propagate the staged state to sibling
> > threads, each thread then setting no_new_privs at its own next
> > execve(2).
> >
> > The staged bit is inherited across fork(2) and persists in the
> > credentials until the next successful execution. To consume it,
> > Landlock handles the bprm_committing_creds hook, which runs while the
> > credentials of the new program are being committed: if the bit is set,
> > task_set_no_new_privs(current) is called and the bit is cleared.
> >
> > Again, this flag does not bypass the requirement to either have
> > CAP_SYS_ADMIN or no_new_privs already set to call
> > landlock_restrict_self(2).
> >
> > The Landlock ABI version is bumped to 11.
> >
> > Test coverage:
> >
> > The new nnp_on_exec fixture generates a shell script that reads the
> > NoNewPrivs value from /proc/self/status and exits with it. The
> > variants select the conditions under which the flag is tested (with
> > and without a ruleset, with and without CAP_SYS_ADMIN/no_new_privs
> > already set, with and without TSYNC, etc.), then compare no_new_privs
> > before the execution and in the executed script. The ruleset variants
> > also check that a ruleset passed along the flag is enforced
> > immediately, unlike the staged no_new_privs.
> >
> > Justin Suess (3):
> > landlock: Add LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC
> > selftests/landlock: Test LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC
> > landlock: Document LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC
> >
> > Documentation/userspace-api/landlock.rst | 21 +-
> > include/uapi/linux/landlock.h | 36 ++-
> > security/landlock/cred.c | 22 ++
> > security/landlock/cred.h | 8 +
> > security/landlock/limits.h | 2 +-
> > security/landlock/syscalls.c | 54 +++-
> > tools/testing/selftests/landlock/base_test.c | 259 ++++++++++++++++++-
> > 7 files changed, 382 insertions(+), 20 deletions(-)
> >
> > --
> > 2.54.0
> >
> >
^ permalink raw reply
* İlt: Re: [RFC/discuss] memfd_secret(): opt-in visibility for security monitoring (eBPF/audit)
From: BoxStrikesTeam @ 2026-07-10 13:40 UTC (permalink / raw)
To: paul@paul-moore.com
Cc: rppt@kernel.org, akpm@linux-foundation.org, linux-mm@kvack.org,
linux-security-module@vger.kernel.org, jmorris@namei.org,
serge@hallyn.com
In-Reply-To: <CAHC9VhRCo1nc2qLfq=Fk9Q26vjSOUBgfM8wV6U4S+Hv1KM9LNQ@mail.gmail.com>
Proton Mail güvenli e-posta ile gönderildi.
------- Forwarded Message -------
Kimden: Paul Moore paul@paul-moore.com
Tarih: 9 Temmuz 2026 Perşembe saat 05:21
Konu: Re: [RFC/discuss] memfd_secret(): opt-in visibility for security monitoring (eBPF/audit)
Kime: BoxStrikesTeam BoxStrikesTeam@proton.me
CC: rppt@kernel.org rppt@kernel.org, akpm@linux-foundation.org akpm@linux-foundation.org, linux-mm@kvack.org linux-mm@kvack.org, linux-security-module@vger.kernel.org linux-security-module@vger.kernel.org, jmorris@namei.org jmorris@namei.org, serge@hallyn.com serge@hallyn.com
> On Wed, Jul 8, 2026 at 8:09 AM BoxStrikesTeam BoxStrikesTeam@proton.me wrote:
>
> > Hi,
> >
> > While experimenting with mseal() and memfd_secret() together on a
> > recent kernel, I ran into what looks like a gap worth discussing:
> > content placed in memfd_secret()-backed memory is invisible not just
> > to other processes, but also to in-kernel tracing/observability
> > mechanisms such as eBPF's bpf_probe_read_user() (EFAULT, as expected,
> > since the region is removed from the direct map and kernel page
> > tables entirely).
> >
> > That's working as designed for the threat model memfd_secret targets
> > (protect secrets even from a compromised kernel / ROP-based
> > exfiltration). But it does mean a local, unprivileged process can
> > now allocate memory that:
> >
> > 1. Is invisible to kernel-side introspection (eBPF tracing,
> > /proc/<pid>/mem, ptrace-based tooling) once populated via
> > memfd_secret(), and
> > 2. Can additionally be sealed against mprotect()/munmap()/mremap()
> > via mseal() so its protection bits can't be relaxed either.
> >
> > Neither primitive alone is new or alarming - mseal() protects mapping
> > metadata, not confidentiality, and memfd_secret() is explicitly
> > opt-in and disabled by default. But combined, they let a process
> > carve out a region that a host-based EDR relying on eBPF
> > tracing/probe_read helpers cannot inspect, and cannot force back into
> > an inspectable state either. For userland security tooling that
> > assumes 'anything a tracing eBPF program can attach to, it can read',
> > this is a small blind spot.
> >
> > I want to be clear I'm not suggesting memfd_secret()'s core guarantee
> > should be weakened - the ability to keep data hidden from a
> > compromised kernel is the entire point, and forcibly exposing content
> > to tracing programs would undermine that model and create a new
> > attack surface via the eBPF verifier/helper path itself.
> >
> > What I'd like to raise for discussion instead is something closer to
> > what was already anticipated in the original series - Mike, your
> > commit message for memfd_secret() mentions: 'Once there will be a use
> > case that will require exposing secretmem to the kernel it will be an
> > opt-in request in the system call flags.' Two lighter-weight
> > directions that stay consistent with that opt-in philosophy:
> >
> > a) An LSM hook / audit event at memfd_secret() call time (this
> > echoes Christian Gottsche's 2022 RFC to label secretmem inodes
> > via inode_init_security_anon for SELinux). Even without content
> > visibility, logging 'process X created a N-byte kernel-invisible
> > mapping' gives EDR/audit systems a behavioral signal to alert on,
> > without touching the confidentiality guarantee at all.
> >
> > b) A distinct opt-in flag (as foreshadowed in the original commit)
> > that a process could set to allow a CAP_BPF/CAP_SYS_ADMIN-gated
> > tracing context to read the region for legitimate
> > monitoring/debugging - fully opt-in, off by default, and never
> > implicitly available to unprivileged tracers.
> >
> > Is (a) something that's been considered further since the 2022
> > secretmem-inode-labeling thread? And is there any existing tracking
> > issue for the kind of opt-in-visibility idea in (b), or was it
> > dropped as not worth the complexity?
>
> Modern kernels do allow LSM labeling of secretmem inodes, see
> secretmem_file_create().
>
> --
> paul-moore.com
Hello,
Option B caught my interest. Do you have any updates, disclosures, new ideas, or anything new to share?
By the way, I strengthened my finding with a proof of concept and have now disclosed it publicly.
Thank you.
https://github.com/BoxStrikesTeam/Counter-Attack-Injection-Method
https://boxstrikesteam.github.io/Bulgular/001/finding-001.html
^ permalink raw reply
* Re: [PATCH] PM: hibernate: Allow hibernation opt-in when locked down
From: Nicolas Bouchinet @ 2026-07-10 13:09 UTC (permalink / raw)
To: Sean Rhodes
Cc: rafael, lenb, pavel, corbet, skhan, paul, jmorris, serge,
xiujianfeng, keescook, linux-pm, linux-doc, linux-security-module,
linux-kernel, mjg59@srcf.ucam.org
In-Reply-To: <CABtds-1d8uYi5YbxgbL5MwZOXTUgBmeLQWiggVhBKtqct5VC-g@mail.gmail.com>
On Thu, Jul 09, 2026 at 04:33:38PM -0400, Sean Rhodes wrote:
> Please ignore this patch; the approach was wrong.
>
> I'll follow up with a v2.
>
> On Thu, 9 Jul 2026 12:23:11 -0700, Sean Rhodes <sean@starlabs.systems> wrote:
> > Kernel lockdown disables hibernation because the resume image cannot be
> > verified before it is restored. On systems where external platform or
> > storage policy protects the hibernation image from offline modification,
> > users may still need hibernation while lockdown is active.
> >
> > Add a hibernate=allow_locked_down command line option to make that opt-in
> > explicit. This only bypasses the LOCKDOWN_HIBERNATION gate; nohibernate,
> > secretmem and CXL memory restrictions still apply.
> >
> > The kernel does not validate the external policy or authenticate the image
> > with this option.
> >
> > Build-tested with Fedora config:
> > make O=../linux-lockdown-hibernate-build kernel/power/hibernate.o
Hi Sean, thanks for your contribution.
While I understand the frustration of Lockdown disabling hibernation, it really
is necessary in order to protect against the root user which is in Lockdown's
threat model. Similar discussions already happened in this patch set [1].
About Lockdown hibernation support, some work have started some time ago by
Matthew, it blog post [2] describe really well the security issue of hibernation.
This has then lead to a first implementation [3] that has been recently bumped
[4] but sadly no news have been given since.
Some interesting discussion also happened recently about this subject on
mastodon [5].
If a solution have to be implemented, it definitively should take a different
approach than just disabling Lockdown. If your interested by working on the
original patch, I'd gladly review it.
[1]: https://lore.kernel.org/all/20250728111517.134116-1-nik.borisov@suse.com/
[2]: https://mjg59.dreamwidth.org/55845.html
[3]: https://lore.kernel.org/lkml/20210220013255.1083202-1-matthewgarrett@google.com/
[4]: https://lore.kernel.org/all/IA1PR14MB62243E515C24AE8BF40E36BCB14BA@IA1PR14MB6224.namprd14.prod.outlook.com/
[5]: https://nondeterministic.computer/@mjg59/115491928573781876.
Best regards,
Nicolas
^ permalink raw reply
* Re: [PATCH] selftests/landlock: Skip scoped_signal subtest with MSG_OOB if not available
From: Mickaël Salaün @ 2026-07-10 11:10 UTC (permalink / raw)
To: Thomas Huth
Cc: Günther Noack, linux-security-module, Shuah Khan,
linux-kselftest, linux-kernel
In-Reply-To: <20260710081642.405916-1-thuth@redhat.com>
Applied (with a Fixes tag), thanks!
On Fri, Jul 10, 2026 at 10:16:42AM +0200, Thomas Huth wrote:
> From: Thomas Huth <thuth@redhat.com>
>
> MSG_OOB might be disabled in the kernel for unix sockets (by not
> selecting CONFIG_AF_UNIX_OOB), and in this case the related tests
> of the scoped_signal_test are currently failing. Add a runtime
> probe using socketpair() to detect MSG_OOB support and skip the
> test gracefully if it is unavailable.
>
> Signed-off-by: Thomas Huth <thuth@redhat.com>
> ---
> .../selftests/landlock/scoped_signal_test.c | 21 +++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/tools/testing/selftests/landlock/scoped_signal_test.c b/tools/testing/selftests/landlock/scoped_signal_test.c
> index 58d25157fe781..3cf20d769f2bc 100644
> --- a/tools/testing/selftests/landlock/scoped_signal_test.c
> +++ b/tools/testing/selftests/landlock/scoped_signal_test.c
> @@ -398,6 +398,24 @@ static int setup_signal_handler(int signal)
> return sigaction(SIGURG, &sa, NULL);
> }
>
> +/*
> + * MSG_OOB might be disabled in the kernel via the CONFIG_AF_UNIX_OOB
> + * switch, so this function can be used for probing for its availability.
> + */
> +static bool has_af_unix_oob(void)
> +{
> + bool available = false;
> + int sp[2];
> +
> + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0) {
> + available = (send(sp[0], ".", 1, MSG_OOB) == 1);
> + close(sp[0]);
> + close(sp[1]);
> + }
> +
> + return available;
> +}
> +
> /* clang-format off */
> FIXTURE(fown) {};
> /* clang-format on */
> @@ -460,6 +478,9 @@ TEST_F(fown, sigurg_socket)
> int pipe_parent[2], pipe_child[2];
> pid_t child;
>
> + if (!has_af_unix_oob())
> + SKIP(return, "CONFIG_AF_UNIX_OOB / MSG_OOB not available");
> +
> memset(&server_address, 0, sizeof(server_address));
> set_unix_address(&server_address, 0);
>
> --
> 2.55.0
>
>
^ permalink raw reply
* Re: [PATCH] selftests/landlock: Fix screwed up pointers in the scoped_signal_test
From: Mickaël Salaün @ 2026-07-10 11:09 UTC (permalink / raw)
To: Thomas Huth
Cc: Günther Noack, linux-security-module, Shuah Khan,
linux-kselftest, linux-kernel, rbriggs
In-Reply-To: <20260709164340.339656-1-thuth@redhat.com>
Applied (with a Fixes tag), thanks!
On Thu, Jul 09, 2026 at 06:43:40PM +0200, Thomas Huth wrote:
> From: Thomas Huth <thuth@redhat.com>
>
> The scoped_signal_test uses pthread_join(..., (void **)&ret)) in
> a couple of places, i.e. the return value of the thread is stored
> in the shape of a "void *" into the memory location of &ret.
> Pointers are 64-bit on modern computers, but the ret variable is
> declared as a simple "enum thread_return" which is only 32 bits.
> So the pthread_join() will overflow the ret variable by 4 byte.
>
> The problem is very visible on big endian systems like s390x
> where the test is failing: The least significant byte that carries
> the return code of the thread is not written into the ret variable
> here, but somewhere else in the stack frame, so the comparison
> for the right return code is failing here.
>
> Fix it by getting rid of the enum and defining the THREAD_* constants
> and "ret" variables as proper "void *" pointers. This way we can
> also get rid of some ugly (void *) castings in a couple of spots.
>
> Signed-off-by: Thomas Huth <thuth@redhat.com>
> ---
> .../selftests/landlock/scoped_signal_test.c | 44 +++++++++----------
> 1 file changed, 21 insertions(+), 23 deletions(-)
>
> diff --git a/tools/testing/selftests/landlock/scoped_signal_test.c b/tools/testing/selftests/landlock/scoped_signal_test.c
> index f24f2c28f62e5..58d25157fe781 100644
> --- a/tools/testing/selftests/landlock/scoped_signal_test.c
> +++ b/tools/testing/selftests/landlock/scoped_signal_test.c
> @@ -249,12 +249,10 @@ TEST_F(scoped_domains, check_access_signal)
> _metadata->exit_code = KSFT_FAIL;
> }
>
> -enum thread_return {
> - THREAD_INVALID = 0,
> - THREAD_SUCCESS = 1,
> - THREAD_ERROR = 2,
> - THREAD_TEST_FAILED = 3,
> -};
I just added clang-format markups.
> +#define THREAD_INVALID ((void *)0)
> +#define THREAD_SUCCESS ((void *)1)
> +#define THREAD_ERROR ((void *)2)
> +#define THREAD_TEST_FAILED ((void *)3)
>
> static void *thread_sync(void *arg)
> {
> @@ -262,15 +260,15 @@ static void *thread_sync(void *arg)
> char buf;
>
> if (read(pipe_read, &buf, 1) != 1)
> - return (void *)THREAD_ERROR;
> + return THREAD_ERROR;
>
> - return (void *)THREAD_SUCCESS;
> + return THREAD_SUCCESS;
> }
>
> TEST(signal_scoping_thread_before)
> {
> pthread_t no_sandbox_thread;
> - enum thread_return ret = THREAD_INVALID;
> + void *ret = THREAD_INVALID;
> int thread_pipe[2];
>
> drop_caps(_metadata);
> @@ -285,7 +283,7 @@ TEST(signal_scoping_thread_before)
> EXPECT_EQ(0, pthread_kill(no_sandbox_thread, 0));
> EXPECT_EQ(1, write(thread_pipe[1], ".", 1));
>
> - EXPECT_EQ(0, pthread_join(no_sandbox_thread, (void **)&ret));
> + EXPECT_EQ(0, pthread_join(no_sandbox_thread, &ret));
> EXPECT_EQ(THREAD_SUCCESS, ret);
>
> EXPECT_EQ(0, close(thread_pipe[0]));
> @@ -295,7 +293,7 @@ TEST(signal_scoping_thread_before)
> TEST(signal_scoping_thread_after)
> {
> pthread_t scoped_thread;
> - enum thread_return ret = THREAD_INVALID;
> + void *ret = THREAD_INVALID;
> int thread_pipe[2];
>
> drop_caps(_metadata);
> @@ -310,7 +308,7 @@ TEST(signal_scoping_thread_after)
> EXPECT_EQ(0, pthread_kill(scoped_thread, 0));
> EXPECT_EQ(1, write(thread_pipe[1], ".", 1));
>
> - EXPECT_EQ(0, pthread_join(scoped_thread, (void **)&ret));
> + EXPECT_EQ(0, pthread_join(scoped_thread, &ret));
> EXPECT_EQ(THREAD_SUCCESS, ret);
>
> EXPECT_EQ(0, close(thread_pipe[0]));
> @@ -327,20 +325,20 @@ void *thread_setuid(void *ptr)
> char buf;
>
> if (read(arg->pipe_read, &buf, 1) != 1)
> - return (void *)THREAD_ERROR;
> + return THREAD_ERROR;
>
> /* libc's setuid() should update all thread's credentials. */
> if (getuid() != arg->new_uid)
> - return (void *)THREAD_TEST_FAILED;
> + return THREAD_TEST_FAILED;
>
> - return (void *)THREAD_SUCCESS;
> + return THREAD_SUCCESS;
> }
>
> TEST(signal_scoping_thread_setuid)
> {
> struct thread_setuid_args arg;
> pthread_t no_sandbox_thread;
> - enum thread_return ret = THREAD_INVALID;
> + void *ret = THREAD_INVALID;
> int pipe_parent[2];
> int prev_uid;
>
> @@ -367,7 +365,7 @@ TEST(signal_scoping_thread_setuid)
> EXPECT_EQ(arg.new_uid, getuid());
> EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
>
> - EXPECT_EQ(0, pthread_join(no_sandbox_thread, (void **)&ret));
> + EXPECT_EQ(0, pthread_join(no_sandbox_thread, &ret));
> EXPECT_EQ(THREAD_SUCCESS, ret);
>
> clear_cap(_metadata, CAP_SETUID);
> @@ -667,20 +665,20 @@ static void *thread_setown_scoped(void *arg)
> ruleset_fd =
> landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
> if (ruleset_fd < 0)
> - return (void *)THREAD_ERROR;
> + return THREAD_ERROR;
> if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) ||
> landlock_restrict_self(ruleset_fd, 0)) {
> close(ruleset_fd);
> - return (void *)THREAD_ERROR;
> + return THREAD_ERROR;
> }
> close(ruleset_fd);
>
> /* Makes this process group own the SIGIO source. */
> if (fcntl(fd, F_SETSIG, SIGURG) || fcntl(fd, F_SETOWN, -getpgrp()) ||
> fcntl(fd, F_SETFL, O_ASYNC))
> - return (void *)THREAD_ERROR;
> + return THREAD_ERROR;
>
> - return (void *)THREAD_SUCCESS;
> + return THREAD_SUCCESS;
> }
>
> /*
> @@ -702,7 +700,7 @@ TEST(sigio_to_pgid_self)
> {
> int trigger[2];
> pthread_t thread;
> - enum thread_return ret = THREAD_INVALID;
> + void *ret = THREAD_INVALID;
> int i;
>
> drop_caps(_metadata);
> @@ -722,7 +720,7 @@ TEST(sigio_to_pgid_self)
> */
> ASSERT_EQ(0, pthread_create(&thread, NULL, thread_setown_scoped,
> &trigger[0]));
> - ASSERT_EQ(0, pthread_join(thread, (void **)&ret));
> + ASSERT_EQ(0, pthread_join(thread, &ret));
> ASSERT_EQ(THREAD_SUCCESS, ret);
>
> /* Fans SIGURG out to the process group. */
> --
> 2.55.0
>
>
^ permalink raw reply
* [PATCH] selftests/landlock: Skip scoped_signal subtest with MSG_OOB if not available
From: Thomas Huth @ 2026-07-10 8:16 UTC (permalink / raw)
To: Mickaël Salaün, Günther Noack,
linux-security-module
Cc: Shuah Khan, linux-kselftest, linux-kernel
From: Thomas Huth <thuth@redhat.com>
MSG_OOB might be disabled in the kernel for unix sockets (by not
selecting CONFIG_AF_UNIX_OOB), and in this case the related tests
of the scoped_signal_test are currently failing. Add a runtime
probe using socketpair() to detect MSG_OOB support and skip the
test gracefully if it is unavailable.
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
.../selftests/landlock/scoped_signal_test.c | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/tools/testing/selftests/landlock/scoped_signal_test.c b/tools/testing/selftests/landlock/scoped_signal_test.c
index 58d25157fe781..3cf20d769f2bc 100644
--- a/tools/testing/selftests/landlock/scoped_signal_test.c
+++ b/tools/testing/selftests/landlock/scoped_signal_test.c
@@ -398,6 +398,24 @@ static int setup_signal_handler(int signal)
return sigaction(SIGURG, &sa, NULL);
}
+/*
+ * MSG_OOB might be disabled in the kernel via the CONFIG_AF_UNIX_OOB
+ * switch, so this function can be used for probing for its availability.
+ */
+static bool has_af_unix_oob(void)
+{
+ bool available = false;
+ int sp[2];
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) == 0) {
+ available = (send(sp[0], ".", 1, MSG_OOB) == 1);
+ close(sp[0]);
+ close(sp[1]);
+ }
+
+ return available;
+}
+
/* clang-format off */
FIXTURE(fown) {};
/* clang-format on */
@@ -460,6 +478,9 @@ TEST_F(fown, sigurg_socket)
int pipe_parent[2], pipe_child[2];
pid_t child;
+ if (!has_af_unix_oob())
+ SKIP(return, "CONFIG_AF_UNIX_OOB / MSG_OOB not available");
+
memset(&server_address, 0, sizeof(server_address));
set_unix_address(&server_address, 0);
--
2.55.0
^ permalink raw reply related
* Re: [PATCH v2 1/9] security: add LSM blob and hooks for namespaces
From: Christian Brauner @ 2026-07-10 6:55 UTC (permalink / raw)
To: Mickaël Salaün
Cc: Paul Moore, Christian Brauner, Günther Noack,
Serge E . Hallyn, Daniel Durning, Jonathan Corbet, Justin Suess,
Lennart Poettering, Mikhail Ivanov, Nicolas Bouchinet,
Shervin Oloumi, Tingmao Wang, kernel-team, linux-fsdevel,
linux-kernel, linux-security-module
In-Reply-To: <20260709.paitheut7Ief@digikod.net>
On 2026-07-09 17:58 +0200, Mickaël Salaün wrote:
> On Thu, Jul 09, 2026 at 09:03:58AM -0400, Paul Moore wrote:
> > On Thu, Jul 9, 2026 at 5:12 AM Mickaël Salaün <mic@digikod.net> wrote:
> > > On Wed, Jul 08, 2026 at 11:22:17PM -0400, Paul Moore wrote:
> > > > On May 27, 2026 =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= <mic@digikod.net> wrote:
> > > > >
> > > > > All namespace types now share the same ns_common infrastructure. Extend
> > > > > this to include a security blob so LSMs can start managing namespaces
> > > > > uniformly without having to add one-off hooks or security fields to
> > > > > every individual namespace type.
> >
> > ...
> >
> > > > > @@ -91,7 +103,10 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
> > > > >
> > > > > void __ns_common_free(struct ns_common *ns)
> > > > > {
> > > > > - proc_free_inum(ns->inum);
> > > > > + security_namespace_free(ns);
> > > > > +
> > > > > + if (ns->inum > MNT_NS_INO_SPECIAL_MAX)
> > > > > + proc_free_inum(ns->inum);
> > > >
> > > > The ns->inum check in the if-conditional above isn't quite the same as
> > > > the is_anon_ns() check it replaces in free_mnt_ns(). You touch on this
> > > > a bit in the changelog, but that really should be explained in the
> > > > commit description.
> > > >
> > > > ... or honestly, should that change be a separate patch?
> > >
> > > I think it's fine, but it's Christian's patch, so I'll let him answer
> > > and propose a new commit description.
> >
> > I don't have a strong opinion on either approach, either a separate
> > patch or doc update, but one of the two needs to happen.
>
> Noted, I'll follow on this with Christian.
I think we should add this as a separate patch.
^ permalink raw reply
* Re: [PATCH] PM: hibernate: Allow hibernation opt-in when locked down
From: Sean Rhodes @ 2026-07-09 20:33 UTC (permalink / raw)
To: rafael
Cc: lenb, pavel, corbet, skhan, paul, jmorris, serge,
nicolas.bouchinet, xiujianfeng, keescook, linux-pm, linux-doc,
linux-security-module, linux-kernel
In-Reply-To: <CABtds-0AUr1jD2Sri6ViiFiqyBbjc3-6xeAOr12YLJA9ux-2BA@mail.gmail.com>
Please ignore this patch; the approach was wrong.
I'll follow up with a v2.
On Thu, 9 Jul 2026 12:23:11 -0700, Sean Rhodes <sean@starlabs.systems> wrote:
> Kernel lockdown disables hibernation because the resume image cannot be
> verified before it is restored. On systems where external platform or
> storage policy protects the hibernation image from offline modification,
> users may still need hibernation while lockdown is active.
>
> Add a hibernate=allow_locked_down command line option to make that opt-in
> explicit. This only bypasses the LOCKDOWN_HIBERNATION gate; nohibernate,
> secretmem and CXL memory restrictions still apply.
>
> The kernel does not validate the external policy or authenticate the image
> with this option.
>
> Build-tested with Fedora config:
> make O=../linux-lockdown-hibernate-build kernel/power/hibernate.o
>
> Signed-off-by: Sean Rhodes <sean@starlabs.systems>
> ---
> Documentation/admin-guide/kernel-parameters.txt | 5 +++++
> kernel/power/hibernate.c | 6 +++++-
> 2 files changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index b5493a7f8f22..0d20ad9c7d78 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1967,6 +1967,11 @@ Kernel parameters
> protect_image Turn on image protection during restoration
> (that will set all pages holding image data
> during restoration read-only).
> + allow_locked_down
> + Allow hibernation even when kernel lockdown would
> + otherwise disable it. The kernel does not verify
> + the hibernation image; only use this when external
> + policy protects the image from offline modification.
>
> hibernate.compressor= [HIBERNATION] Compression algorithm to be
> used with hibernation.
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index d2479c69d71a..71232eece9a3 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -41,6 +41,7 @@
> static int nocompress;
> static int noresume;
> static int nohibernate;
> +static bool allow_locked_down_hibernation;
> static int resume_wait;
> static unsigned int resume_delay;
> static char resume_file[256] = CONFIG_PM_STD_PARTITION;
> @@ -109,7 +110,8 @@ bool hibernation_in_progress(void)
> bool hibernation_available(void)
> {
> return nohibernate == 0 &&
> - !security_locked_down(LOCKDOWN_HIBERNATION) &&
> + (allow_locked_down_hibernation ||
> + !security_locked_down(LOCKDOWN_HIBERNATION)) &&
> !secretmem_active() && !cxl_mem_active();
> }
>
> @@ -1433,6 +1435,8 @@ static int __init hibernate_setup(char *str)
> } else if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)
> && !strncmp(str, "protect_image", 13)) {
> enable_restore_image_protection();
> + } else if (!strncmp(str, "allow_locked_down", 17)) {
> + allow_locked_down_hibernation = true;
> }
> return 1;
> }
> --
> 2.53.0
^ permalink raw reply
* [PATCH] PM: hibernate: Allow hibernation opt-in when locked down
From: Sean Rhodes @ 2026-07-09 19:23 UTC (permalink / raw)
To: rafael
Cc: lenb, pavel, corbet, skhan, paul, jmorris, serge,
nicolas.bouchinet, xiujianfeng, keescook, linux-pm, linux-doc,
linux-security-module, linux-kernel
Kernel lockdown disables hibernation because the resume image cannot be
verified before it is restored. On systems where external platform or
storage policy protects the hibernation image from offline modification,
users may still need hibernation while lockdown is active.
Add a hibernate=allow_locked_down command line option to make that opt-in
explicit. This only bypasses the LOCKDOWN_HIBERNATION gate; nohibernate,
secretmem and CXL memory restrictions still apply.
The kernel does not validate the external policy or authenticate the image
with this option.
Build-tested with Fedora config:
make O=../linux-lockdown-hibernate-build kernel/power/hibernate.o
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
---
Documentation/admin-guide/kernel-parameters.txt | 5 +++++
kernel/power/hibernate.c | 6 +++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt
b/Documentation/admin-guide/kernel-parameters.txt
index b5493a7f8f22..0d20ad9c7d78 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1967,6 +1967,11 @@ Kernel parameters
protect_image Turn on image protection during restoration
(that will set all pages holding image data
during restoration read-only).
+ allow_locked_down
+ Allow hibernation even when kernel lockdown would
+ otherwise disable it. The kernel does not verify
+ the hibernation image; only use this when external
+ policy protects the image from offline modification.
hibernate.compressor= [HIBERNATION] Compression algorithm to be
used with hibernation.
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index d2479c69d71a..71232eece9a3 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -41,6 +41,7 @@
static int nocompress;
static int noresume;
static int nohibernate;
+static bool allow_locked_down_hibernation;
static int resume_wait;
static unsigned int resume_delay;
static char resume_file[256] = CONFIG_PM_STD_PARTITION;
@@ -109,7 +110,8 @@ bool hibernation_in_progress(void)
bool hibernation_available(void)
{
return nohibernate == 0 &&
- !security_locked_down(LOCKDOWN_HIBERNATION) &&
+ (allow_locked_down_hibernation ||
+ !security_locked_down(LOCKDOWN_HIBERNATION)) &&
!secretmem_active() && !cxl_mem_active();
}
@@ -1433,6 +1435,8 @@ static int __init hibernate_setup(char *str)
} else if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)
&& !strncmp(str, "protect_image", 13)) {
enable_restore_image_protection();
+ } else if (!strncmp(str, "allow_locked_down", 17)) {
+ allow_locked_down_hibernation = true;
}
return 1;
}
--
2.53.0
^ permalink raw reply related
* [PATCH] selftests/landlock: Fix screwed up pointers in the scoped_signal_test
From: Thomas Huth @ 2026-07-09 16:43 UTC (permalink / raw)
To: Mickaël Salaün, Günther Noack,
linux-security-module
Cc: Shuah Khan, linux-kselftest, linux-kernel, rbriggs
From: Thomas Huth <thuth@redhat.com>
The scoped_signal_test uses pthread_join(..., (void **)&ret)) in
a couple of places, i.e. the return value of the thread is stored
in the shape of a "void *" into the memory location of &ret.
Pointers are 64-bit on modern computers, but the ret variable is
declared as a simple "enum thread_return" which is only 32 bits.
So the pthread_join() will overflow the ret variable by 4 byte.
The problem is very visible on big endian systems like s390x
where the test is failing: The least significant byte that carries
the return code of the thread is not written into the ret variable
here, but somewhere else in the stack frame, so the comparison
for the right return code is failing here.
Fix it by getting rid of the enum and defining the THREAD_* constants
and "ret" variables as proper "void *" pointers. This way we can
also get rid of some ugly (void *) castings in a couple of spots.
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
.../selftests/landlock/scoped_signal_test.c | 44 +++++++++----------
1 file changed, 21 insertions(+), 23 deletions(-)
diff --git a/tools/testing/selftests/landlock/scoped_signal_test.c b/tools/testing/selftests/landlock/scoped_signal_test.c
index f24f2c28f62e5..58d25157fe781 100644
--- a/tools/testing/selftests/landlock/scoped_signal_test.c
+++ b/tools/testing/selftests/landlock/scoped_signal_test.c
@@ -249,12 +249,10 @@ TEST_F(scoped_domains, check_access_signal)
_metadata->exit_code = KSFT_FAIL;
}
-enum thread_return {
- THREAD_INVALID = 0,
- THREAD_SUCCESS = 1,
- THREAD_ERROR = 2,
- THREAD_TEST_FAILED = 3,
-};
+#define THREAD_INVALID ((void *)0)
+#define THREAD_SUCCESS ((void *)1)
+#define THREAD_ERROR ((void *)2)
+#define THREAD_TEST_FAILED ((void *)3)
static void *thread_sync(void *arg)
{
@@ -262,15 +260,15 @@ static void *thread_sync(void *arg)
char buf;
if (read(pipe_read, &buf, 1) != 1)
- return (void *)THREAD_ERROR;
+ return THREAD_ERROR;
- return (void *)THREAD_SUCCESS;
+ return THREAD_SUCCESS;
}
TEST(signal_scoping_thread_before)
{
pthread_t no_sandbox_thread;
- enum thread_return ret = THREAD_INVALID;
+ void *ret = THREAD_INVALID;
int thread_pipe[2];
drop_caps(_metadata);
@@ -285,7 +283,7 @@ TEST(signal_scoping_thread_before)
EXPECT_EQ(0, pthread_kill(no_sandbox_thread, 0));
EXPECT_EQ(1, write(thread_pipe[1], ".", 1));
- EXPECT_EQ(0, pthread_join(no_sandbox_thread, (void **)&ret));
+ EXPECT_EQ(0, pthread_join(no_sandbox_thread, &ret));
EXPECT_EQ(THREAD_SUCCESS, ret);
EXPECT_EQ(0, close(thread_pipe[0]));
@@ -295,7 +293,7 @@ TEST(signal_scoping_thread_before)
TEST(signal_scoping_thread_after)
{
pthread_t scoped_thread;
- enum thread_return ret = THREAD_INVALID;
+ void *ret = THREAD_INVALID;
int thread_pipe[2];
drop_caps(_metadata);
@@ -310,7 +308,7 @@ TEST(signal_scoping_thread_after)
EXPECT_EQ(0, pthread_kill(scoped_thread, 0));
EXPECT_EQ(1, write(thread_pipe[1], ".", 1));
- EXPECT_EQ(0, pthread_join(scoped_thread, (void **)&ret));
+ EXPECT_EQ(0, pthread_join(scoped_thread, &ret));
EXPECT_EQ(THREAD_SUCCESS, ret);
EXPECT_EQ(0, close(thread_pipe[0]));
@@ -327,20 +325,20 @@ void *thread_setuid(void *ptr)
char buf;
if (read(arg->pipe_read, &buf, 1) != 1)
- return (void *)THREAD_ERROR;
+ return THREAD_ERROR;
/* libc's setuid() should update all thread's credentials. */
if (getuid() != arg->new_uid)
- return (void *)THREAD_TEST_FAILED;
+ return THREAD_TEST_FAILED;
- return (void *)THREAD_SUCCESS;
+ return THREAD_SUCCESS;
}
TEST(signal_scoping_thread_setuid)
{
struct thread_setuid_args arg;
pthread_t no_sandbox_thread;
- enum thread_return ret = THREAD_INVALID;
+ void *ret = THREAD_INVALID;
int pipe_parent[2];
int prev_uid;
@@ -367,7 +365,7 @@ TEST(signal_scoping_thread_setuid)
EXPECT_EQ(arg.new_uid, getuid());
EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
- EXPECT_EQ(0, pthread_join(no_sandbox_thread, (void **)&ret));
+ EXPECT_EQ(0, pthread_join(no_sandbox_thread, &ret));
EXPECT_EQ(THREAD_SUCCESS, ret);
clear_cap(_metadata, CAP_SETUID);
@@ -667,20 +665,20 @@ static void *thread_setown_scoped(void *arg)
ruleset_fd =
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
if (ruleset_fd < 0)
- return (void *)THREAD_ERROR;
+ return THREAD_ERROR;
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) ||
landlock_restrict_self(ruleset_fd, 0)) {
close(ruleset_fd);
- return (void *)THREAD_ERROR;
+ return THREAD_ERROR;
}
close(ruleset_fd);
/* Makes this process group own the SIGIO source. */
if (fcntl(fd, F_SETSIG, SIGURG) || fcntl(fd, F_SETOWN, -getpgrp()) ||
fcntl(fd, F_SETFL, O_ASYNC))
- return (void *)THREAD_ERROR;
+ return THREAD_ERROR;
- return (void *)THREAD_SUCCESS;
+ return THREAD_SUCCESS;
}
/*
@@ -702,7 +700,7 @@ TEST(sigio_to_pgid_self)
{
int trigger[2];
pthread_t thread;
- enum thread_return ret = THREAD_INVALID;
+ void *ret = THREAD_INVALID;
int i;
drop_caps(_metadata);
@@ -722,7 +720,7 @@ TEST(sigio_to_pgid_self)
*/
ASSERT_EQ(0, pthread_create(&thread, NULL, thread_setown_scoped,
&trigger[0]));
- ASSERT_EQ(0, pthread_join(thread, (void **)&ret));
+ ASSERT_EQ(0, pthread_join(thread, &ret));
ASSERT_EQ(THREAD_SUCCESS, ret);
/* Fans SIGURG out to the process group. */
--
2.55.0
^ permalink raw reply related
* Re: [PATCH v2 1/9] security: add LSM blob and hooks for namespaces
From: Mickaël Salaün @ 2026-07-09 15:58 UTC (permalink / raw)
To: Paul Moore
Cc: Christian Brauner, Günther Noack, Serge E . Hallyn,
Daniel Durning, Jonathan Corbet, Justin Suess, Lennart Poettering,
Mikhail Ivanov, Nicolas Bouchinet, Shervin Oloumi, Tingmao Wang,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module
In-Reply-To: <CAHC9VhSVQ0MLwU=C90FmohAThwaQj-mfB7L03fvkB5A0-J2jCg@mail.gmail.com>
On Thu, Jul 09, 2026 at 09:03:58AM -0400, Paul Moore wrote:
> On Thu, Jul 9, 2026 at 5:12 AM Mickaël Salaün <mic@digikod.net> wrote:
> > On Wed, Jul 08, 2026 at 11:22:17PM -0400, Paul Moore wrote:
> > > On May 27, 2026 =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= <mic@digikod.net> wrote:
> > > >
> > > > All namespace types now share the same ns_common infrastructure. Extend
> > > > this to include a security blob so LSMs can start managing namespaces
> > > > uniformly without having to add one-off hooks or security fields to
> > > > every individual namespace type.
>
> ...
>
> > > > @@ -91,7 +103,10 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
> > > >
> > > > void __ns_common_free(struct ns_common *ns)
> > > > {
> > > > - proc_free_inum(ns->inum);
> > > > + security_namespace_free(ns);
> > > > +
> > > > + if (ns->inum > MNT_NS_INO_SPECIAL_MAX)
> > > > + proc_free_inum(ns->inum);
> > >
> > > The ns->inum check in the if-conditional above isn't quite the same as
> > > the is_anon_ns() check it replaces in free_mnt_ns(). You touch on this
> > > a bit in the changelog, but that really should be explained in the
> > > commit description.
> > >
> > > ... or honestly, should that change be a separate patch?
> >
> > I think it's fine, but it's Christian's patch, so I'll let him answer
> > and propose a new commit description.
>
> I don't have a strong opinion on either approach, either a separate
> patch or doc update, but one of the two needs to happen.
Noted, I'll follow on this with Christian.
>
> > > > diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
> > > > index d9d3d5973bf5..0f1b208d8eef 100644
> > > > --- a/kernel/nsproxy.c
> > > > +++ b/kernel/nsproxy.c
> > > > @@ -385,6 +385,12 @@ static int prepare_nsset(unsigned flags, struct nsset *nsset)
> > > >
> > > > static inline int validate_ns(struct nsset *nsset, struct ns_common *ns)
> > > > {
> > > > + int ret;
> > > > +
> > > > + ret = security_namespace_install(nsset, ns);
> > > > + if (ret)
> > > > + return ret;
> > > > +
> > > > return ns->ops->install(nsset, ns);
> > > > }
> > >
> > > In the previous revision to the patchset I asked about a
> > > security_namespace_switch() hook as we don't know if a namespace is
> > > actually attached to a process until we get to switch_task_namespaces().
> > > Perhaps that was answered, but I don't recall reading any mail about that
> > > and I'm not able to uncover any responses on lore.
> >
> > From the cover letter:
> >
> > no security_namespace_switch() post-hook is
> > added in this series: such a hook would only serve LSMs that maintain
> > per-task state derived from the active namespace set (SELinux-style
> > state tracking), and no current LSM (including this series) needs that.
> > Landlock enforces at namespace_install() and namespace_init(), before
> > the task-to-nsproxy switch. The hook is left for a separate LSM
> > infrastructure proposal once a concrete user emerges.
> >
> > This follows the guidance of adding new hooks: there must be at least
> > one user.
>
> I'm aware of the new hook guidance, I was the one who documented it :)
I know. I guess that means you're ok with that?
>
> In the future, it's both helpful and polite to reply to the email
> asking the question with your response. Adding it to the cover letter
> is fine, but to be perfectly honest, once we get past v1 of a
> patchset, I don't often read the cover letter very closely unless
> there is a significant change. However, I do look back at the
> previous posting to ensure all the feedback from everyone has been
> either answered or incorporated into the current revision.
I forgot to reply to your email, I didn't mean to be impolite, sorry for
the inconvenience. It's useful to know that the cover letter is not
always part of your review process.
^ permalink raw reply
* Re: [PATCH v2 1/9] security: add LSM blob and hooks for namespaces
From: Paul Moore @ 2026-07-09 13:03 UTC (permalink / raw)
To: Mickaël Salaün
Cc: Christian Brauner, Günther Noack, Serge E . Hallyn,
Daniel Durning, Jonathan Corbet, Justin Suess, Lennart Poettering,
Mikhail Ivanov, Nicolas Bouchinet, Shervin Oloumi, Tingmao Wang,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module
In-Reply-To: <20260709.kaemaiTia6Li@digikod.net>
On Thu, Jul 9, 2026 at 5:12 AM Mickaël Salaün <mic@digikod.net> wrote:
> On Wed, Jul 08, 2026 at 11:22:17PM -0400, Paul Moore wrote:
> > On May 27, 2026 =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= <mic@digikod.net> wrote:
> > >
> > > All namespace types now share the same ns_common infrastructure. Extend
> > > this to include a security blob so LSMs can start managing namespaces
> > > uniformly without having to add one-off hooks or security fields to
> > > every individual namespace type.
...
> > > @@ -91,7 +103,10 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
> > >
> > > void __ns_common_free(struct ns_common *ns)
> > > {
> > > - proc_free_inum(ns->inum);
> > > + security_namespace_free(ns);
> > > +
> > > + if (ns->inum > MNT_NS_INO_SPECIAL_MAX)
> > > + proc_free_inum(ns->inum);
> >
> > The ns->inum check in the if-conditional above isn't quite the same as
> > the is_anon_ns() check it replaces in free_mnt_ns(). You touch on this
> > a bit in the changelog, but that really should be explained in the
> > commit description.
> >
> > ... or honestly, should that change be a separate patch?
>
> I think it's fine, but it's Christian's patch, so I'll let him answer
> and propose a new commit description.
I don't have a strong opinion on either approach, either a separate
patch or doc update, but one of the two needs to happen.
> > > diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
> > > index d9d3d5973bf5..0f1b208d8eef 100644
> > > --- a/kernel/nsproxy.c
> > > +++ b/kernel/nsproxy.c
> > > @@ -385,6 +385,12 @@ static int prepare_nsset(unsigned flags, struct nsset *nsset)
> > >
> > > static inline int validate_ns(struct nsset *nsset, struct ns_common *ns)
> > > {
> > > + int ret;
> > > +
> > > + ret = security_namespace_install(nsset, ns);
> > > + if (ret)
> > > + return ret;
> > > +
> > > return ns->ops->install(nsset, ns);
> > > }
> >
> > In the previous revision to the patchset I asked about a
> > security_namespace_switch() hook as we don't know if a namespace is
> > actually attached to a process until we get to switch_task_namespaces().
> > Perhaps that was answered, but I don't recall reading any mail about that
> > and I'm not able to uncover any responses on lore.
>
> From the cover letter:
>
> no security_namespace_switch() post-hook is
> added in this series: such a hook would only serve LSMs that maintain
> per-task state derived from the active namespace set (SELinux-style
> state tracking), and no current LSM (including this series) needs that.
> Landlock enforces at namespace_install() and namespace_init(), before
> the task-to-nsproxy switch. The hook is left for a separate LSM
> infrastructure proposal once a concrete user emerges.
>
> This follows the guidance of adding new hooks: there must be at least
> one user.
I'm aware of the new hook guidance, I was the one who documented it :)
In the future, it's both helpful and polite to reply to the email
asking the question with your response. Adding it to the cover letter
is fine, but to be perfectly honest, once we get past v1 of a
patchset, I don't often read the cover letter very closely unless
there is a significant change. However, I do look back at the
previous posting to ensure all the feedback from everyone has been
either answered or incorporated into the current revision.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v2] NFSv4.2: fix nfs4_listxattr size accounting
From: Stephen Smalley @ 2026-07-09 12:32 UTC (permalink / raw)
To: Paul Moore
Cc: Anna Schumaker, Achilles Gaikwad, Trond Myklebust, linux-nfs,
linux-security-module, selinux
In-Reply-To: <CAHC9VhSyCuiPBRWz_vUbx7+L5yLiXkjKX+7UyCLr82-_gAj2NQ@mail.gmail.com>
On Wed, Jul 8, 2026 at 4:11 PM Paul Moore <paul@paul-moore.com> wrote:
>
> On Wed, Jul 8, 2026 at 2:54 PM Stephen Smalley
> <stephen.smalley.work@gmail.com> wrote:
> > On Tue, Jul 7, 2026 at 4:01 PM Paul Moore <paul@paul-moore.com> wrote:
> > >
> > > On Tue, Jul 7, 2026 at 3:12 PM Anna Schumaker <anna@kernel.org> wrote:
> > > > On Tue, Jul 7, 2026, at 2:48 PM, Paul Moore wrote:
> > > > > On Tue, Jul 7, 2026 at 11:24 AM Achilles Gaikwad
> > > > > <achillesgaikwad@gmail.com> wrote:
> > > > >>
> > > > >> A call to listxattr() with a buffer size of 0 returns the actual
> > > > >> size of the buffer needed for a subsequent call. On an NFSv4.2
> > > > >> mount this triggers the following oops:
> > > > >>
> > > > >> [ 399.768687] BUG: kernel NULL pointer dereference, address: 0000000000000000
> > > > >> [ 399.768705] RIP: 0010:_copy_from_pages+0x44/0xe0
> > > > >> [ 399.768722] Call Trace:
> > > > >> [ 399.768723] nfs4_xattr_alloc_entry+0x1bf/0x1e0
> > > > >> [ 399.768730] nfs4_xattr_cache_set_list+0x43/0x1f0
> > > > >> [ 399.768731] nfs4_listxattr+0x21f/0x250
> > > > >> [ 399.768733] vfs_listxattr+0x55/0xa0
> > > > >> [ 399.768736] listxattr+0x23/0x160
> > > > >> [ 399.768737] path_listxattrat+0xba/0x1e0
> > > > >> [ 399.768739] do_syscall_64+0xe2/0x680
> > > > >>
> > > > >> security_inode_listsecurity() (via the xattr_list_one() helper) now
> > > > >> decrements the remaining size even when the buffer pointer is NULL, so
> > > > >> in the size-query case, 'left' underflows to a huge size_t value. As a
> > > > >> result, nfs4_listxattr_nfs4_user() treats the NULL buffer as a real one,
> > > > >> leading to a NULL pointer dereference in _copy_from_pages().
> > > > >>
> > > > >> security_inode_listsecurity() does not return the number of bytes
> > > > >> it added to the list, so the code derived it as
> > > > >> 'size - error - left'. That is also wrong in the size-query case:
> > > > >> the generic_listxattr() contribution is only subtracted from 'left'
> > > > >> when a buffer is present. Thus, the query result comes up short by
> > > > >> exactly that contribution (e.g., "system.nfs4_acl" on a mount with
> > > > >> ACL support), and a caller that allocates the returned size gets
> > > > >> -ERANGE on the subsequent call.
> > > > >>
> > > > >> Declare 'left' as ssize_t, use a scratch copy to measure security
> > > > >> hook consumption, and only decrement 'left' if a buffer is present.
> > > > >>
> > > > >> Fixes: f71ece9712b7 ("security,fs,nfs,net: update security_inode_listsecurity() interface")
> > > > >> Suggested-by: Paul Moore <paul@paul-moore.com>
> > > > >> Signed-off-by: Achilles Gaikwad <achillesgaikwad@gmail.com>
> > > > >> ---
> > > > >> Changes in v2:
> > > > >> - Use a scratch variable to track security label size directly,
> > > > >> replacing the old formula that undercounted the size-query case.
> > > > >> - Drop the now-unneeded NULL-buffer special case for
> > > > >> nfs4_listxattr_nfs4_user().
> > > > >> - Retitled from "fix nfs4_listxattr NULL pointer dereference"
> > > > >> (the same accounting bug caused both the oops and the undercount).
> > > > >> v1: https://lore.kernel.org/linux-nfs/20260703102759.9626-1-achillesgaikwad@gmail.com/
> > > > >> fs/nfs/nfs4proc.c | 10 +++++++---
> > > > >> 1 file changed, 7 insertions(+), 3 deletions(-)
> > > > >
> > > > > [CC'd the LSM and SELinux lists for visibility]
> > > > >
> > > > > Unfortunately my testing was unsuccessful due to an NFS problem that
> > > > > started with the v7.2 merge window that I haven't had the time to
> > > > > bisect yet. Assuming the NFS folks are okay with this change, I
> > > > > figure they will want to send it up to Linus via their tree, if not
> > > > > let me know and I can send this up via the LSM tree.
> > > >
> > > > Yeah, we'll send it through the NFS tree.
> > >
> > > Thanks Anna.
> > >
> > > > I'll be curious to hear
> > > > what problem you're hitting, and what patch is the culprit once you
> > > > do that bisect!
> > >
> > > Yes, me too :)
> > >
> > > I'm still working through a review backlog so it might be a bit before
> > > I have a chance, but in case anyone wants to test it out, it's easily
> > > reproduced using the selinux-testsuite and the NFS tests:
> > >
> > > https://github.com/SELinuxProject/selinux-testsuite#nfs
> >
> > They seem to pass for me with and without the patch (they don't
> > exercise listxattr AFAIK).
> > This was on the current selinux/dev branch, v7.2-rc1 based.
>
> They work for me on vanilla v7.1 and fail somewhere before vanilla
> v7.2-rc1 (still bisecting).
>
> I wonder if there is an interaction problem with a recent userspace
> update. What distro/userspace are you running for your tests? I'm
> doing my testing on a relatively recent Rawhide.
I was on F44, so yes, it could be a difference in e.g. coreutils or
other userspace on rawhide that is tickling this particular bug.
^ permalink raw reply
* Re: [PATCH 0/3] Implement LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC
From: Simon McVittie @ 2026-07-09 11:22 UTC (permalink / raw)
To: Mickaël Salaün; +Cc: Justin Suess, linux-security-module, gnoack
In-Reply-To: <20260709.Eaphooyoh6sh@digikod.net>
On Thu, 09 Jul 2026 at 12:09:25 +0200, Mickaël Salaün wrote:
> On Wed, Jul 08, 2026 at 09:39:24AM -0400, Justin Suess wrote:
> > Consider a sandbox launcher that depends on a set-user-ID helper, such
> > as launching applications through bubblewrap on distributions where
> > unprivileged user namespaces are disabled and bwrap is installed
> > set-user-ID root.
It's perhaps worth noting that the current version 0.11.2 of bubblewrap
deprecates this mode of use (it will refuse to run while setuid unless
that was explicitly enabled at compile-time), and the next release 0.12.0
will also remove the ability to enable it at compile-time.
When bubblewrap was first written, having it be setuid was a necessary
workaround for kernels/distros not letting it do its sandboxing job any
other way; but now that unprivileged user namespaces are more widespread,
its maintainers have come to the conclusion that when it's setuid,
the risk of vulnerabilities that allow a root privilege escalation
(CVE-2020-5291, CVE-2026-41163) is unacceptably high, so being able to
make it setuid is no longer a good trade-off.
> > This flag also closes a gap for CAP_SYS_ADMIN callers of
> > landlock_restrict_self(2) itself. The no_new_privs/CAP_SYS_ADMIN
> > requirement exists to keep set-user-ID programs from running confused
> > inside a sandbox they do not expect. However, a privileged process
> > that enforces a domain without setting no_new_privs leaves that hole
> > open for all of its descendants
>
> In a nutshell, not setting NNP might be risky, even when not strictly
> needed. We might want to update the Landlock doc with that.
If the CAP_SYS_ADMIN caller is setuid or setcap, then it has been
granted special privileges by the sysadmin or distro, and part of
the "contract" between the sysadmin/distro and the setuid program is
that setuid/setcap must only be set on executables that have taken
responsibility for ensuring that they can't create insecure situations
(for example bubblewrap always sets PR_SET_NO_NEW_PRIVS, unconditionally,
for this reason).
A large part of why bubblewrap no longer supports being setuid is that
its maintainers don't want it to have this heavy responsibility.
smcv
^ permalink raw reply
* Re: [PATCH 0/3] Implement LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC
From: Mickaël Salaün @ 2026-07-09 10:09 UTC (permalink / raw)
To: Justin Suess; +Cc: linux-security-module, gnoack
In-Reply-To: <20260708133928.852999-1-utilityemal77@gmail.com>
Hi Justin,
Thanks for this patch series, I like the underlying idea, but I'm not
convince we should mix NNP and ON_EXEC. Why not a
LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS flag instead?
One issue with this NNP_ON_EXEC is that it might be confusing for one
thread to set it and expect the next exec to be NNP, but if the exec is
requested by another thread that would not happen. With a
LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS flag, we could have an atomic
Landlock and NNP enforcement, which can also be combined with the TSYNC
flag, both useful cases.
If we want an enforcement to happen at exec time, we could add a
dedicated flag, similar to the TSYNC one, but I'm not sure it would be
useful for now.
On Wed, Jul 08, 2026 at 09:39:24AM -0400, Justin Suess wrote:
> Good morning,
>
> This series adds a new landlock_restrict_self(2) flag:
> LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC.
>
> This flag stages a bit in the Landlock credentials indicating that the
> next successful execution will set the no_new_privs attribute while
> committing its new credentials.
>
> Differences from prctl(PR_SET_NO_NEW_PRIVS):
>
> PR_SET_NO_NEW_PRIVS takes effect immediately: it prevents gaining
> privileges through set-user-ID, set-group-ID and file capabilities
> starting with the very next execve(2).
>
> LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC instead only sets the task's
> no_new_privs attribute once the next execve(2) is guaranteed to succeed
> (past its point of no return, in bprm_committing_creds), after any
> privilege gain through set-user-ID, set-group-ID or file capabilities
> has already taken place. The executed program then runs with
> no_new_privs, so subsequent executions cannot gain privileges. A
> failed execve(2) leaves no_new_privs untouched.
>
> Use cases:
>
> Enforcing a Landlock ruleset requires that the calling process either
> already has no_new_privs set or possesses CAP_SYS_ADMIN. This series
> does not grant any exception to this rule; for a caller that already
> has no_new_privs set, the flag is effectively a no-op. It is therefore
> mostly useful for CAP_SYS_ADMIN callers that need to execute programs
> that legitimately escalate privileges (e.g. transition to another
> user), while ensuring that further executions cannot gain privileges.
That's a good point, but why not just set NNP for the whole process at
landlock_restrict_self() call time? There is a partial answer below
but...
>
> Consider a sandbox launcher that depends on a set-user-ID helper, such
> as launching applications through bubblewrap on distributions where
> unprivileged user namespaces are disabled and bwrap is installed
> set-user-ID root. The launcher cannot set PR_SET_NO_NEW_PRIVS before
> the execution, as that would neuter the very helper it depends on:
>
> sandbox launcher (CAP_SYS_ADMIN)
> |
> | landlock_restrict_self(-1, LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC)
> V
> /usr/bin/bwrap (set-user-ID root: honored for this execution;
> | no_new_privs set once the execution is past its
> | point of no return)
This should only be allowed if the launcher has CAP_SYS_ADMIN, otherwise
it would be like changing the state of a more privileged process.
Anyway, even with this safeguard, this approach looks risky.
> V
> sandboxed application (runs with no_new_privs; cannot gain
> privileges through any further execution, and
> may enforce its own Landlock ruleset without
> CAP_SYS_ADMIN)
>
> This flag also closes a gap for CAP_SYS_ADMIN callers of
> landlock_restrict_self(2) itself. The no_new_privs/CAP_SYS_ADMIN
> requirement exists to keep set-user-ID programs from running confused
> inside a sandbox they do not expect. However, a privileged process
> that enforces a domain without setting no_new_privs leaves that hole
> open for all of its descendants: anything running in the domain may
> still execute a set-user-ID binary, which then runs privileged under a
> restricted view of the system. A privileged process that needs one
> legitimate set-user-ID/set-group-ID transition currently has to choose
> between breaking that transition (setting no_new_privs first) or
> leaving the hole open for the lifetime of the domain.
> LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC allows the one intended transition
> and then closes the hole.
In a nutshell, not setting NNP might be risky, even when not strictly
needed. We might want to update the Landlock doc with that.
>
> Design:
>
> This flag is implemented simply: a bit is stored in the Landlock
> credential blob (struct landlock_cred_security) indicating whether the
> next execution should set no_new_privs when it commits its new
> credentials.
Also, if we don't have the ON_EXEC part, there is no need to store
anything in the cred.
>
> The bit is not coupled to any ruleset and, like
> LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF, may be passed with no
> ruleset (i.e. ruleset_fd = -1). It may also be combined with
> LANDLOCK_RESTRICT_SELF_TSYNC to propagate the staged state to sibling
> threads, each thread then setting no_new_privs at its own next
> execve(2).
>
> The staged bit is inherited across fork(2) and persists in the
> credentials until the next successful execution. To consume it,
> Landlock handles the bprm_committing_creds hook, which runs while the
> credentials of the new program are being committed: if the bit is set,
> task_set_no_new_privs(current) is called and the bit is cleared.
>
> Again, this flag does not bypass the requirement to either have
> CAP_SYS_ADMIN or no_new_privs already set to call
> landlock_restrict_self(2).
>
> The Landlock ABI version is bumped to 11.
>
> Test coverage:
>
> The new nnp_on_exec fixture generates a shell script that reads the
> NoNewPrivs value from /proc/self/status and exits with it. The
> variants select the conditions under which the flag is tested (with
> and without a ruleset, with and without CAP_SYS_ADMIN/no_new_privs
> already set, with and without TSYNC, etc.), then compare no_new_privs
> before the execution and in the executed script. The ruleset variants
> also check that a ruleset passed along the flag is enforced
> immediately, unlike the staged no_new_privs.
>
> Justin Suess (3):
> landlock: Add LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC
> selftests/landlock: Test LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC
> landlock: Document LANDLOCK_RESTRICT_SELF_NNP_ON_EXEC
>
> Documentation/userspace-api/landlock.rst | 21 +-
> include/uapi/linux/landlock.h | 36 ++-
> security/landlock/cred.c | 22 ++
> security/landlock/cred.h | 8 +
> security/landlock/limits.h | 2 +-
> security/landlock/syscalls.c | 54 +++-
> tools/testing/selftests/landlock/base_test.c | 259 ++++++++++++++++++-
> 7 files changed, 382 insertions(+), 20 deletions(-)
>
> --
> 2.54.0
>
>
^ permalink raw reply
* Re: [PATCH 1/2] umh, treewide: Explicitly include linux/umh.h where needed
From: Petr Pavlu @ 2026-07-09 9:49 UTC (permalink / raw)
To: Michal Koutný
Cc: Tony Luck, Borislav Petkov, Thomas Gleixner, Ingo Molnar,
Dave Hansen, x86, H. Peter Anvin, Philipp Reisner, Lars Ellenberg,
Christoph Böhmwalder, Jens Axboe, Johan Hovold, Alex Elder,
Greg Kroah-Hartman, Rafael J. Wysocki, Michal Januszewski,
Helge Deller, Alexander Viro, Christian Brauner, Jan Kara,
Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey, Mark Fasheh,
Joel Becker, Joseph Qi, Tejun Heo, Johannes Weiner,
Luis Chamberlain, Daniel Gomez, Sami Tolvanen, Aaron Tomlin,
Pavel Machek, Len Brown, Andrew Morton, Danilo Krummrich,
Nikolay Aleksandrov, Ido Schimmel, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, David Howells,
Jarkko Sakkinen, Paul Moore, James Morris, Serge E. Hallyn,
Kentaro Takeda, Tetsuo Handa, linux-edac, linux-kernel, drbd-dev,
linux-block, greybus-dev, linuxppc-dev, linux-acpi, linux-fbdev,
dri-devel, linux-fsdevel, linux-nfs, ocfs2-devel, cgroups,
linux-modules, linux-pm, driver-core, bridge, netdev, keyrings,
linux-security-module
In-Reply-To: <ak6STbqZd-Q-c56v@localhost.localdomain>
On 7/8/26 8:13 PM, Michal Koutný wrote:
> Hi Petr.
>
> On Wed, Jul 08, 2026 at 05:44:29PM +0200, Petr Pavlu <petr.pavlu@suse.com> wrote:
>> diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c
>> index a4337c9b5287..60eb994c32ae 100644
>> --- a/kernel/cgroup/cgroup-v1.c
>> +++ b/kernel/cgroup/cgroup-v1.c
>> @@ -16,6 +16,7 @@
>> #include <linux/pid_namespace.h>
>> #include <linux/cgroupstats.h>
>> #include <linux/fs_parser.h>
>> +#include <linux/umh.h>
>>
>> #include <trace/events/cgroup.h>
>
> There is kmod.h in here too but it's unnecessary, no module lazy loading
> in this code.
You're right. I'll remove the kmod.h include from
kernel/cgroup/cgroup-v1.c. I went through all the files again and it
seems this was the only place I missed.
--
Thanks,
Petr
^ 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