From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2A68047042E; Tue, 21 Jul 2026 19:52:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784663578; cv=none; b=YgAe+O/sP3BtcSH485UnHcDzvIU52nIkNi5gTNrXNrM6+b/bo3iR+esyCdYlKEZ38p7B1oLsMF8xamDNoNdkWM9xjL1ay7dmMx0HKuLoU42ahPuH21Y7DbXHZcvaTTmREJ8cY1/mrYlcUjbFxBWoiemljQpNlb4bMIq4gkVTYxc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784663578; c=relaxed/simple; bh=yoZtADSDiS5NCorB4YwAtWy3oBesAJlyxunb/a8pzcw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KOfHj6S8MMnVbejU0iwcsqg/SxLvFlXdwBsBOgMf5+/14F5iMpElflHsjYouNmv2TP76m2hwr26ZH3jIrHzoITqtZ1eN85AD4Q6OjyyayMfprSaR/88VYRKXiszhmOnDw1mdZc3DPn7nP9JpS0Mw29kuYrr10xjoDuEvqgEnakE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=Orelkghc; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="Orelkghc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 908A21F00A3F; Tue, 21 Jul 2026 19:52:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1784663576; bh=VwvUGXhC8g7fN8YgzXioz848QUxyhDn0Wyo02JnzVvQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=OrelkghcSsU8jHEqzkOTPnF8MZsiaikkQfHVNbLO66tvHjmUtHdSHSPKee/Iw2B7q Bymu8/na3/3WR0GwUd+a83G5gma8JAHzASKCNKmfz+nJtsdViN9YzCVSfFCleDa4LR qG+34xgojZFEwEq3kBxGKWRyMYDKqu4hWjJqgFJQ= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Ondrej Mosnacek , Stephen Smalley , Paul Moore Subject: [PATCH 6.12 0873/1276] selinux: fix incorrect execmem checks on overlayfs Date: Tue, 21 Jul 2026 17:21:56 +0200 Message-ID: <20260721152505.589193277@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260721152446.065700225@linuxfoundation.org> References: <20260721152446.065700225@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ondrej Mosnacek commit 9fe595fad54d4ac6a402edb3f60bec859d52cea6 upstream. The commit fixing the overlayfs mmap() and mprotect() access checks failed to skip the execmem check in __file_map_prot_check() for the case where the "mounter check" is being performed. This check should be performed only against the credentials of the task that is calling mmap()/mprotect(), since it doesn't pertain to the file itself, but rather just gates the ability of the calling task to get an executable memory mapping in general. The purpose of the "mounter check" is to guard against using an overlayfs mount to gain file access that would otherwise be denied to the mounter. For execmem this is not relevant, as there is no further file access granted based on it (notice that the file's context is not used as the target in the check), so checking it also against the mounter credentials would be incorrect. Fix this by passing a boolean to [__]file_map_prot_check() and selinux_mmap_file_common() that indicates if we are doing the "mounter check" and skiping the execmem check in that case. Since this boolean also indicates if we use current_cred() or the mounter cred as the subject, also remove the "cred" argument from these functions and determine it based on the boolean and the file struct. Cc: stable@vger.kernel.org Fixes: 82544d36b172 ("selinux: fix overlayfs mmap() and mprotect() access checks") Signed-off-by: Ondrej Mosnacek Reviewed-by: Stephen Smalley Signed-off-by: Paul Moore Signed-off-by: Greg Kroah-Hartman --- security/selinux/hooks.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3804,9 +3804,9 @@ static int selinux_file_ioctl_compat(str static int default_noexec __ro_after_init; -static int __file_map_prot_check(const struct cred *cred, - const struct file *file, unsigned long prot, - bool shared, bool bf_user_file) +static int __file_map_prot_check(const struct file *file, unsigned long prot, + bool shared, bool mounter_check, + bool bf_user_file) { struct inode *inode = NULL; bool prot_exec = prot & PROT_EXEC; @@ -3819,10 +3819,10 @@ static int __file_map_prot_check(const s inode = file_inode(file); } - if (default_noexec && prot_exec && + if (!mounter_check && default_noexec && prot_exec && (!file || IS_PRIVATE(inode) || (!shared && prot_write))) { int rc; - u32 sid = cred_sid(cred); + u32 sid = current_sid(); /* * We are making executable an anonymous mapping or a private @@ -3835,6 +3835,8 @@ static int __file_map_prot_check(const s } if (file) { + const struct cred *cred = mounter_check ? + file->f_cred : current_cred(); /* "read" always possible, "write" only if shared */ u32 av = FILE__READ; if (shared && prot_write) @@ -3848,11 +3850,11 @@ static int __file_map_prot_check(const s return 0; } -static inline int file_map_prot_check(const struct cred *cred, - const struct file *file, - unsigned long prot, bool shared) +static inline int file_map_prot_check(const struct file *file, + unsigned long prot, bool shared, + bool mounter_check) { - return __file_map_prot_check(cred, file, prot, shared, false); + return __file_map_prot_check(file, prot, shared, mounter_check, false); } static int selinux_mmap_addr(unsigned long addr) @@ -3868,12 +3870,14 @@ static int selinux_mmap_addr(unsigned lo return rc; } -static int selinux_mmap_file_common(const struct cred *cred, struct file *file, - unsigned long prot, bool shared) +static int selinux_mmap_file_common(struct file *file, unsigned long prot, + bool shared, bool mounter_check) { if (file) { int rc; struct common_audit_data ad; + const struct cred *cred = mounter_check ? + file->f_cred : current_cred(); ad.type = LSM_AUDIT_DATA_FILE; ad.u.file = file; @@ -3882,15 +3886,16 @@ static int selinux_mmap_file_common(cons return rc; } - return file_map_prot_check(cred, file, prot, shared); + return file_map_prot_check(file, prot, shared, mounter_check); } static int selinux_mmap_file(struct file *file, unsigned long reqprot __always_unused, unsigned long prot, unsigned long flags) { - return selinux_mmap_file_common(current_cred(), file, prot, - (flags & MAP_TYPE) == MAP_SHARED); + return selinux_mmap_file_common(file, prot, + (flags & MAP_TYPE) == MAP_SHARED, + false); } /** @@ -3922,8 +3927,9 @@ static int selinux_mmap_backing_file(str 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); + return selinux_mmap_file_common(backing_file, prot, + vma->vm_flags & VM_SHARED, + true); } static int selinux_file_mprotect(struct vm_area_struct *vma, @@ -3984,11 +3990,11 @@ static int selinux_file_mprotect(struct } } - rc = __file_map_prot_check(cred, file, prot, shared, backing_file); + rc = __file_map_prot_check(file, prot, shared, false, backing_file); if (rc) return rc; if (backing_file) { - rc = file_map_prot_check(file->f_cred, file, prot, shared); + rc = file_map_prot_check(file, prot, shared, true); if (rc) return rc; }