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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox