Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
From f51a39581f78a9f95314488409c719560e07233d Mon Sep 17 00:00:00 2001
From: Shikha Vyaghra <vyaghras@amazon.com>
Date: Wed, 14 Oct 2026 17:45:16 +0000
Subject: [PATCH] Revert "selinux: recheck intermediate backing files on
mprotect()"

This reverts commit d127c7e1f3e1231d8ac8b2738e3f00bea12afe74.
---
security/selinux/hooks.c | 141 ++++--------------------------
security/selinux/include/objsec.h | 8 --
2 files changed, 16 insertions(+), 133 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index eef75bde6..9c137b101 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1665,32 +1665,26 @@ static int cred_has_capability(const struct cred *cred,
return rc;
}

-/*
- * Check whether a SID has a particular permission to an inode. The 'adp'
- * parameter is optional and allows other audit data to be passed (e.g. the
- * dentry).
- */
-static int inode_sid_has_perm(u32 sid, struct inode *inode, u32 perms,
- struct common_audit_data *adp)
+/* Check whether a task has a particular permission to an inode.
+ The 'adp' parameter is optional and allows other audit
+ data to be passed (e.g. the dentry). */
+static int inode_has_perm(const struct cred *cred,
+ struct inode *inode,
+ u32 perms,
+ struct common_audit_data *adp)
{
struct inode_security_struct *isec;
+ u32 sid;

if (unlikely(IS_PRIVATE(inode)))
return 0;

+ sid = cred_sid(cred);
isec = selinux_inode(inode);

return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
}

-static int inode_has_perm(const struct cred *cred,
- struct inode *inode,
- u32 perms,
- struct common_audit_data *adp)
-{
- return inode_sid_has_perm(cred_sid(cred), inode, perms, adp);
-}
-
/* Same as inode_has_perm, but pass explicit audit data containing
the dentry to help the auditing code to more easily generate the
pathname if needed. */
@@ -3839,63 +3833,13 @@ static int selinux_backing_file_alloc(struct file *backing_file,
const struct file *user_file)
{
struct backing_file_security_struct *bfsec;
- const struct backing_file_security_struct *ubfsec;
- struct backing_file_security_layer *layer;
- u32 i;

bfsec = selinux_backing_file(backing_file);
bfsec->uf_sid = selinux_file_user_sid(user_file);
- if (!(user_file->f_mode & FMODE_BACKING))
- return 0;
-
- ubfsec = selinux_backing_file(user_file);
- /* a wrapped count would make kmalloc_array() return ZERO_SIZE_PTR */
- if (unlikely(ubfsec->layer_count == U32_MAX))
- return -EOVERFLOW;
-
- /*
- * The final VMA only retains the lowest backing file, so record the
- * whole chain here rather than in the mmap hook, where concurrent
- * mappings would have to be serialized. Size it dynamically: erofs
- * inode sharing adds a backing file without bumping s_stack_depth.
- */
- bfsec->layers = kmalloc_array(ubfsec->layer_count + 1,
- sizeof(*bfsec->layers), GFP_KERNEL);
- if (!bfsec->layers)
- return -ENOMEM;
-
- for (i = 0; i < ubfsec->layer_count; i++) {
- layer = &bfsec->layers[i];
- *layer = ubfsec->layers[i];
- path_get(&layer->path);
- }
-
- /* f_path, not file_user_path(): this layer, not the top-level file */
- layer = &bfsec->layers[i];
- layer->path = user_file->f_path;
- layer->mounter_sid = cred_sid(user_file->f_cred);
- layer->fd_sid = selinux_file(user_file)->sid;
- path_get(&layer->path);
- bfsec->layer_count = ubfsec->layer_count + 1;

return 0;
}

-static void selinux_backing_file_free(struct file *backing_file)
-{
- struct backing_file_security_struct *bfsec;
-
- /* security_backing_file_free() may be called twice after an error */
- if (!backing_file_security(backing_file))
- return;
-
- bfsec = selinux_backing_file(backing_file);
- while (bfsec->layer_count)
- path_put(&bfsec->layers[--bfsec->layer_count].path);
- kfree(bfsec->layers);
- bfsec->layers = NULL;
-}
-
/*
* Check whether a task has the ioctl permission and cmd
* operation to an inode.
@@ -4013,53 +3957,6 @@ static int selinux_file_ioctl_compat(struct file *file, unsigned int cmd,

static int default_noexec __ro_after_init;

-static u32 file_map_prot_to_av(unsigned long prot, bool shared)
-{
- u32 av = FILE__READ;
-
- if (shared && (prot & PROT_WRITE))
- av |= FILE__WRITE;
- if (prot & PROT_EXEC)
- av |= FILE__EXECUTE;
-
- return av;
-}
-
-static int backing_mounters_has_perm(const struct file *file, u32 av)
-{
- const struct backing_file_security_struct *bfsec;
- const struct backing_file_security_layer *layer;
- struct common_audit_data ad;
- struct inode *inode;
- u32 i;
- int rc;
-
- if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)))
- return -EIO;
-
- bfsec = selinux_backing_file(file);
- for (i = 0; i < bfsec->layer_count; i++) {
- layer = &bfsec->layers[i];
- inode = d_inode(layer->path.dentry);
-
- ad.type = LSM_AUDIT_DATA_PATH;
- ad.u.path = layer->path;
-
- if (layer->mounter_sid != layer->fd_sid) {
- rc = avc_has_perm(layer->mounter_sid, layer->fd_sid,
- SECCLASS_FD, FD__USE, &ad);
- if (rc)
- return rc;
- }
-
- rc = inode_sid_has_perm(layer->mounter_sid, inode, av, &ad);
- if (rc)
- return rc;
- }
-
- return 0;
-}
-
static int __file_map_prot_check(const struct file *file, unsigned long prot,
bool shared, bool mounter_check,
bool bf_user_file)
@@ -4093,10 +3990,14 @@ static int __file_map_prot_check(const struct file *file, unsigned long prot,
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)
+ av |= FILE__WRITE;
+ if (prot_exec)
+ av |= FILE__EXECUTE;

- return __file_has_perm(cred, file,
- file_map_prot_to_av(prot, shared),
- bf_user_file);
+ return __file_has_perm(cred, file, av, bf_user_file);
}

return 0;
@@ -4191,7 +4092,6 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
int rc;
const struct cred *cred = current_cred();
u32 sid = cred_sid(cred);
- u32 av;
const struct file *file = vma->vm_file;
bool backing_file;
bool shared = vma->vm_flags & VM_SHARED;
@@ -4235,10 +4135,6 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
if (rc)
return rc;
if (backing_file) {
- rc = backing_mounters_has_perm(file,
- FILE__EXECMOD);
- if (rc)
- return rc;
rc = file_has_perm(file->f_cred, file,
FILE__EXECMOD);
if (rc)
@@ -4251,10 +4147,6 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
if (rc)
return rc;
if (backing_file) {
- av = file_map_prot_to_av(prot, shared);
- rc = backing_mounters_has_perm(file, av);
- if (rc)
- return rc;
rc = file_map_prot_check(file, prot, shared, true);
if (rc)
return rc;
@@ -7615,7 +7507,6 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
LSM_HOOK_INIT(file_permission, selinux_file_permission),
LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
LSM_HOOK_INIT(backing_file_alloc, selinux_backing_file_alloc),
- LSM_HOOK_INIT(backing_file_free, selinux_backing_file_free),
LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
LSM_HOOK_INIT(file_ioctl_compat, selinux_file_ioctl_compat),
LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index bbb04f26b..eb3a1effe 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -86,16 +86,8 @@ struct file_security_struct {
u32 pseqno; /* Policy seqno at the time of file open */
};

-struct backing_file_security_layer {
- struct path path; /* this layer's real path */
- u32 mounter_sid; /* SID of the mounter that opened it */
- u32 fd_sid; /* SID of its open file description */
-};
-
struct backing_file_security_struct {
u32 uf_sid; /* top-level user file fsec->sid */
- u32 layer_count; /* number of intermediate backing files */
- struct backing_file_security_layer *layers;
};

struct superblock_security_struct {
--
2.50.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
From 4dda1dfbab29cfc25dc00d8815ce6cec24d4d4f1 Mon Sep 17 00:00:00 2001
From: Shikha Vyaghra <vyaghras@amazon.com>
Date: Wed, 14 Oct 2026 17:48:58 +0000
Subject: [PATCH] Revert "selinux: preserve user SID across nested backing
files"

This reverts commit 9d99b770e7b67b00bdef9005b928aad13e1d679b.
---
security/selinux/hooks.c | 9 +--------
security/selinux/include/objsec.h | 2 +-
2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9c137b101..af188e19c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3822,20 +3822,13 @@ static int selinux_file_alloc_security(struct file *file)
return 0;
}

-static inline u32 selinux_file_user_sid(const struct file *file)
-{
- if (unlikely(file->f_mode & FMODE_BACKING))
- return selinux_backing_file(file)->uf_sid;
- return selinux_file(file)->sid;
-}
-
static int selinux_backing_file_alloc(struct file *backing_file,
const struct file *user_file)
{
struct backing_file_security_struct *bfsec;

bfsec = selinux_backing_file(backing_file);
- bfsec->uf_sid = selinux_file_user_sid(user_file);
+ bfsec->uf_sid = selinux_file(user_file)->sid;

return 0;
}
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index eb3a1effe..fcb467938 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -87,7 +87,7 @@ struct file_security_struct {
};

struct backing_file_security_struct {
- u32 uf_sid; /* top-level user file fsec->sid */
+ u32 uf_sid; /* associated user file fsec->sid */
};

struct superblock_security_struct {
--
2.50.1

Loading
Loading