mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH] selinux: prevent truncation of status map
@ 2026-01-30 17:11 Christian Göttsche
  2026-01-30 20:46 ` [PATCH RFC] " Paul Moore
  2026-01-30 21:07 ` [RFC PATCH] " Stephen Smalley
  0 siblings, 2 replies; 8+ messages in thread
From: Christian Göttsche @ 2026-01-30 17:11 UTC (permalink / raw)
  To: selinux
  Cc: Christian Göttsche, Paul Moore, Stephen Smalley,
	Ondrej Mosnacek, linux-kernel

From: Christian Göttsche <cgzones@googlemail.com>

Currently the SELinux status map can be truncated, given the necessary
permissions, leading to foreign user space processes getting a bus error
(SIGBUS) while concurrently making use of the status map.
For example systemd can be killed that way, see [1].

Override the setattr inode handler and check for O_TRUNC in the open
handler to prevent truncations.

Link [1]: https://github.com/systemd/systemd/issues/37349
Closes: https://github.com/SELinuxProject/selinux/issues/475
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 security/selinux/selinuxfs.c | 43 ++++++++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 896acad1f5f7..df079a35a02d 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -214,10 +214,30 @@ static const struct file_operations sel_handle_unknown_ops = {
 	.llseek		= generic_file_llseek,
 };
 
+static int sel_setattr_handle_status(struct mnt_idmap *idmap,
+				     struct dentry *dentry,
+				     struct iattr *iattr)
+{
+	/* Prevent truncation to avoid raising SIGBUS */
+	if (iattr->ia_valid & ATTR_SIZE)
+		return -EINVAL;
+
+	return simple_setattr(idmap, dentry, iattr);
+}
+
+static const struct inode_operations sel_handle_status_iops = {
+	.setattr	= sel_setattr_handle_status,
+};
+
 static int sel_open_handle_status(struct inode *inode, struct file *filp)
 {
-	struct page    *status = selinux_kernel_status_page();
+	struct page *status;
 
+	/* Prevent truncation to avoid raising SIGBUS */
+	if (filp->f_flags & O_TRUNC)
+		return -EINVAL;
+
+	status = selinux_kernel_status_page();
 	if (!status)
 		return -ENOMEM;
 
@@ -1980,7 +2000,6 @@ static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
 		[SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
 		[SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
 		[SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
-		[SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
 		[SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
 		[SEL_VALIDATE_TRANS] = {"validatetrans", &sel_transition_ops,
 					S_IWUGO},
@@ -1995,6 +2014,26 @@ static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
 	if (ret)
 		goto err;
 
+	/* Create "status" separately to assign a custom inode_operations */
+	{
+		ret = -ENOMEM;
+
+		dentry = d_alloc_name(sb->s_root, "status");
+		if (!dentry)
+			goto err;
+		inode = new_inode(sb);
+		if (!inode) {
+			dput(dentry);
+			goto err;
+		}
+		inode->i_mode = S_IFREG | 0444;
+		simple_inode_init_ts(inode);
+		inode->i_fop = &sel_handle_status_ops;
+		inode->i_op = &sel_handle_status_iops;
+		inode->i_ino = SEL_STATUS;
+		d_add(dentry, inode);
+	}
+
 	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.51.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-02-20 23:13 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-30 17:11 [RFC PATCH] selinux: prevent truncation of status map Christian Göttsche
2026-01-30 20:46 ` [PATCH RFC] " Paul Moore
2026-01-31 17:18   ` Christian Göttsche
2026-02-20 23:13     ` Paul Moore
2026-01-30 21:07 ` [RFC PATCH] " Stephen Smalley
2026-01-30 21:47   ` Paul Moore
2026-01-31 17:20   ` Christian Göttsche
2026-02-12 13:59     ` Stephen Smalley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®