[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250826172330.44006-1-mittalyugansh1@gmail.com>
Date: Tue, 26 Aug 2025 22:53:20 +0530
From: Yugansh Mittal <mittalyugansh1@...il.com>
To: paul@...l-moore.com,
selinux@...r.kernel.org,
stephen.smalley.work@...il.com,
omosnace@...hat.com,
linux-kernel@...r.kernel.org
Cc: Yugansh Mittal <mittalyugansh1@...il.com>
Subject: [PATCH v2] [V2] selinux: restore sleepable revalidation; keep fast no-sleep check
The prior change made __inode_security_revalidate() always return
-ECHILD when the inode label appears invalid, avoiding the potential
sleep in inode_doinit_with_dentry(). However, not all callers can
propagate -ECHILD; only RCU path walk reliably can. This caused
cases where the inode could be left with a stale/unlabeled context.
Fix by:
* Keeping an RCU-safe, non-blocking validity check fast path.
* Returning -ECHILD only when may_sleep == false.
* When may_sleep == true, performing the blocking revalidation via
inode_doinit_with_dentry() as before.
This preserves non-sleeping behavior in atomic/RCU contexts while
maintaining correct reload semantics elsewhere.
Signed-off-by: Yugansh Mittal <mittalyugansh1@...il.com>
---
security/selinux/hooks.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c95a5874b..170ae6d65 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -279,20 +279,34 @@ static int __inode_security_revalidate(struct inode *inode,
struct dentry *dentry,
bool may_sleep)
{
+ struct inode_security_struct *isec;
+
if (!selinux_initialized())
return 0;
- if (may_sleep)
- might_sleep();
- else
- return -ECHILD;
+ /* Fast, non-blocking validity check first */
+ rcu_read_lock();
+ isec = selinux_inode(inode);
+ if (likely(isec && !is_label_invalid(isec))) {
+ rcu_read_unlock();
+ return 0; /* valid and no sleeping done */
+ }
+ rcu_read_unlock();
/*
- * Check to ensure that an inode's SELinux state is valid and try
- * reloading the inode security label if necessary. This will fail if
- * @dentry is NULL and no dentry for this inode can be found; in that
- * case, continue using the old label.
- */
+ * Label looks invalid. If we can't sleep, signal caller that a
+ * retry in a sleepable context is required. Only contexts like
+ * RCU path walk are expected to propagate -ECHILD.
+ */
+ if (!may_sleep)
+ return -ECHILD;
+
+ /*
+ * Sleepable context: reload the label. This may block.
+ * If @dentry is NULL and no dentry can be found we'll continue
+ * using the old label, consistent with prior behavior.
+ */
+ might_sleep();
inode_doinit_with_dentry(inode, dentry);
return 0;
}
--
2.43.0
Powered by blists - more mailing lists