From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Stephen Smalley <stephen.smalley.work@gmail.com>
Cc: selinux@vger.kernel.org, paul@paul-moore.com,
omosnacek@gmail.com, jannh@google.com, jack@suse.cz,
cgzones@googlemail.com, brauner@kernel.org
Subject: Re: [PATCH v3] selinux: mark status and policy inodes as immutable, drop status mmap write checks
Date: Mon, 14 Sep 2026 10:18:21 +0100 [thread overview]
Message-ID: <aqe6QA7Gn7B_7EhB@gremlin> (raw)
In-Reply-To: <20260911163734.22981-2-stephen.smalley.work@gmail.com>
On Fri, Sep 11, 2026 at 12:37:35PM -0400, Stephen Smalley wrote:
> The selinuxfs "status" and "policy" files are read-only interfaces
> that are also mmap'd by userspace. They are created 0444 by
> simple_fill_super() but a CAP_DAC_OVERRIDE caller can still open them
> O_WRONLY/O_RDWR, open(O_RDONLY|O_TRUNC) them, or truncate(2) them.
>
> Mark both inodes S_IMMUTABLE at fill_super time. inode_permission()
> tests IS_IMMUTABLE before the DAC / capability checks, so all of the
> above are rejected at the VFS layer without ever reaching the file
> operations. Since a writable file can no longer exist, do_mmap() clear
Micro nit: clear -> clears.
> VM_MAYWRITE for MAP_SHARED mappings on its own, and the
> sel_mmap_handle_status() write/mprotect guards are dead; drop them.
> MAP_PRIVATE writable mappings become permitted (they were previously
> -EPERM) and CoW harmlessly to a private page, matching how
> sel_mmap_policy() has always treated the private case.
>
> The sel_mmap_policy() VM_SHARED guard becomes redundant for the same
> reason; leave dropping it to the pending "selinux: reject writable
> opens of policy file, drop mmap shared/write check" patch so that the
> patches do not conflict.
>
> Link: https://lore.kernel.org/selinux/aqPUqU3eZeFrykj3@gremlin/
> cc: ljs@kernel.org
> cc: jannh@google.com
> cc: jack@suse.cz
> cc: cgzones@googlemail.com
> cc: brauner@kernel.org
> Suggested-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
With nits addressed, LGTM so:
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> v3 implements Jan's suggestion to mark the inodes immutable rather than
> implementing open-time checks.
>
> security/selinux/selinuxfs.c | 19 ++++++++++++++-----
> 1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index 292302eb60f3..0941ce79ea0b 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -247,11 +247,6 @@ static int sel_mmap_handle_status(struct file *filp,
> /* only allows one page from the head */
> if (vma->vm_pgoff > 0 || size != PAGE_SIZE)
> return -EIO;
> - /* disallow writable mapping */
> - if (vma->vm_flags & VM_WRITE)
> - return -EPERM;
> - /* disallow mprotect() turns it into writable */
> - vm_flags_clear(vma, VM_MAYWRITE);
>
> return remap_pfn_range(vma, vma->vm_start,
> page_to_pfn(status),
> @@ -1818,6 +1813,17 @@ static struct dentry *sel_make_swapover_dir(struct super_block *sb, u64 *ino)
>
> #define NULL_FILE_NAME "null"
>
> +static void sel_mark_immutable(struct dentry *root, const char *name)
> +{
> + struct qstr q = QSTR(name);
> + struct dentry *dentry = try_lookup_noperm(&q, root);
> +
> + if (!IS_ERR_OR_NULL(dentry)) {
> + d_inode(dentry)->i_flags |= S_IMMUTABLE;
> + dput(dentry);
> + }
> +}
Hmm, maybe worth returning an error here on lookup failure? I think probably it
can't happen in reality right now but that'd make it consistent with the other
functions here.
> +
> static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
> {
> struct selinux_fs_info *fsi;
> @@ -1857,6 +1863,9 @@ static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
> if (ret)
> goto err;
>
> + sel_mark_immutable(sb->s_root, "status");
> + sel_mark_immutable(sb->s_root, "policy");
> +
> fsi = sb->s_fs_info;
> fsi->bool_dir = sel_make_dir(sb->s_root, BOOL_DIR_NAME, &fsi->last_ino);
> if (IS_ERR(fsi->bool_dir)) {
> --
> 2.55.0
>
--
Cheers, Lorenzo
next prev parent reply other threads:[~2026-09-14 9:18 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 16:37 [PATCH v3] selinux: mark status and policy inodes as immutable, drop status mmap write checks Stephen Smalley
2026-09-11 16:57 ` sashiko-bot
2026-09-14 7:56 ` Jan Kara
2026-09-14 9:18 ` Lorenzo Stoakes (ARM) [this message]
2026-09-14 12:39 ` Stephen Smalley
2026-09-14 12:45 ` Lorenzo Stoakes (ARM)
2026-09-14 21:17 ` Paul Moore
2026-09-15 9:15 ` Jan Kara
2026-09-15 13:01 ` Christian Brauner
2026-09-15 21:28 ` Paul Moore
2026-09-15 12:41 ` Stephen Smalley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aqe6QA7Gn7B_7EhB@gremlin \
--to=ljs@kernel.org \
--cc=brauner@kernel.org \
--cc=cgzones@googlemail.com \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=omosnacek@gmail.com \
--cc=paul@paul-moore.com \
--cc=selinux@vger.kernel.org \
--cc=stephen.smalley.work@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.