From: sashiko-bot@kernel.org
To: "Cai Xinchen" <caixinchen1@huawei.com>
Cc: selinux@vger.kernel.org, bpf@vger.kernel.org
Subject: Re: [PATCH v3 stable/linux-6.12.y 3/3] selinux: fix overlayfs mmap() and mprotect() access checks
Date: Mon, 29 Jun 2026 07:09:37 +0000 [thread overview]
Message-ID: <20260629070944.1925F1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260629070338.578858-4-caixinchen1@huawei.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] The patch erroneously applies the process-centric `PROCESS__EXECMEM` and `FILE__EXECMOD` permission checks to the backing file's mounter credentials instead of the executing process.
Pre-existing issues:
- [High] The code incorrectly uses `vma->vm_file` as a proxy for file-backed VMA classification, which violates VMA handling rules and triggers incorrect SELinux `FILE__EXECMOD` checks on anonymous `/dev/zero` mappings.
--
commit 555f3d33101bb91626c5a624dddd21197775bb31
Author: Paul Moore <paul@paul-moore.com>
selinux: fix overlayfs mmap() and mprotect() access checks
This commit updates the SELinux security model for overlayfs by applying
access controls for mmap() and mprotect(). It introduces a new backing
file LSM hook and uses the backing file API to enforce mprotect() access
controls properly for stacked filesystems.
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 8e31d3b60fc62..1b89c8d5fa2fc 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
[ ... ]
> @@ -3821,36 +3868,80 @@ static int selinux_mmap_addr(unsigned long addr)
[ ... ]
> +static int selinux_mmap_backing_file(struct vm_area_struct *vma,
> + struct file *backing_file,
> + struct file *user_file __always_unused)
> +{
> + unsigned long prot = 0;
> +
> + /* translate vma->vm_flags perms into PROT perms */
> + if (vma->vm_flags & VM_READ)
> + prot |= PROT_READ;
> + if (vma->vm_flags & VM_WRITE)
> + prot |= PROT_WRITE;
> + if (vma->vm_flags & VM_EXEC)
> + prot |= PROT_EXEC;
> +
> + return selinux_mmap_file_common(backing_file->f_cred, backing_file,
> + prot, vma->vm_flags & VM_SHARED);
[Severity: High]
Does this apply the process-centric PROCESS__EXECMEM permission check
to the mounter's credentials instead of the executing process?
selinux_mmap_file_common() eventually calls __file_map_prot_check(), which
evaluates the PROCESS__EXECMEM permission against the credentials provided.
When passed the mounter's credentials here (backing_file->f_cred), it
seems to evaluate the mounter domain instead of the current task. This
could spuriously deny mapping W+X memory on overlayfs files, or allow an
unauthorized process to do so if the mounter has execmem.
> }
>
> static int selinux_file_mprotect(struct vm_area_struct *vma,
> unsigned long reqprot __always_unused,
> unsigned long prot)
> {
> + int rc;
> const struct cred *cred = current_cred();
> u32 sid = cred_sid(cred);
> + const struct file *file = vma->vm_file;
> + bool backing_file;
> + bool shared = vma->vm_flags & VM_SHARED;
> +
> + /* check if we need to trigger the "backing files are awful" mode */
> + backing_file = file && (file->f_mode & FMODE_BACKING);
>
> if (default_noexec &&
> (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
> - int rc = 0;
> /*
> * We don't use the vma_is_initial_heap() helper as it has
> * a history of problems and is currently broken on systems
> @@ -3864,11 +3955,15 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
> vma->vm_end <= vma->vm_mm->brk) {
> rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
> PROCESS__EXECHEAP, NULL);
> - } else if (!vma->vm_file && (vma_is_initial_stack(vma) ||
> + if (rc)
> + return rc;
> + } else if (!file && (vma_is_initial_stack(vma) ||
> vma_is_stack_for_current(vma))) {
[Severity: High]
This is a pre-existing issue, but does using !file correctly identify
anonymous VMAs?
According to the VMA guidelines, a VMA can have a valid vm_file but still
be anonymous, such as private mappings of /dev/zero. The canonical test for
an anonymous VMA is vma_is_anonymous(vma).
> rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
> PROCESS__EXECSTACK, NULL);
> - } else if (vma->vm_file && vma->anon_vma) {
> + if (rc)
> + return rc;
> + } else if (file && vma->anon_vma) {
[Severity: High]
This is a pre-existing issue, but checking for a non-null file and anon_vma
as a proxy for file-backed VMA classification seems incorrect.
Private mappings of /dev/zero have a vm_file and set anon_vma after a COW
fault, which would cause this code to erroneously check FILE__EXECMOD on
them. Should this use !vma_is_anonymous(vma) instead to safely handle these
cases?
> /*
> * We are making executable a file mapping that has
> * had some COW done. Since pages might have been
> @@ -3876,13 +3971,29 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
> * modified content. This typically should only
> * occur for text relocations.
> */
> - rc = file_has_perm(cred, vma->vm_file, FILE__EXECMOD);
> + rc = __file_has_perm(cred, file, FILE__EXECMOD,
> + backing_file);
> + if (rc)
> + return rc;
> + if (backing_file) {
> + rc = file_has_perm(file->f_cred, file,
> + FILE__EXECMOD);
[Severity: High]
Does this apply the process-centric FILE__EXECMOD permission check to the
mounter's credentials? Checking file->f_cred evaluates if the mounter can
execute modified file memory, rather than checking the executing process.
> + if (rc)
> + return rc;
> + }
> }
> + }
> +
> + rc = __file_map_prot_check(cred, file, prot, shared, backing_file);
> + if (rc)
> + return rc;
> + if (backing_file) {
> + rc = file_map_prot_check(file->f_cred, file, prot, shared);
[Severity: High]
Does this have the same issue of passing the mounter's credentials down to
the PROCESS__EXECMEM check?
By passing file->f_cred into file_map_prot_check(), the mounter is
evaluated for process-centric permissions instead of the current task.
> + if (rc)
> + return rc;
> }
>
> - return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
> + return 0;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260629070338.578858-1-caixinchen1@huawei.com?part=3
next prev parent reply other threads:[~2026-06-29 7:09 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-29 7:03 [PATCH v3 stable/linux-6.12.y 0/3] Backport Fix incorrect overlayfs mmap() and mprotect() LSM access controls Cai Xinchen
2026-06-29 7:03 ` [PATCH v3 stable/linux-6.12.y 1/3] fs: constify file ptr in backing_file accessor helpers Cai Xinchen
2026-06-29 7:01 ` sashiko-bot
2026-06-29 7:03 ` [PATCH v3 stable/linux-6.12.y 2/3] lsm: add backing_file LSM hooks Cai Xinchen
2026-06-29 7:06 ` sashiko-bot
2026-06-29 7:03 ` [PATCH v3 stable/linux-6.12.y 3/3] selinux: fix overlayfs mmap() and mprotect() access checks Cai Xinchen
2026-06-29 7:09 ` sashiko-bot [this message]
2026-06-30 22:23 ` [PATCH v3 stable/linux-6.12.y 0/3] Backport Fix incorrect overlayfs mmap() and mprotect() LSM access controls Sasha Levin
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=20260629070944.1925F1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=caixinchen1@huawei.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=selinux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is 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.