From 78a95ae82b9f4056c3f4dbecf2d57c55436ace04 Mon Sep 17 00:00:00 2001 From: rsuntk Date: Mon, 28 Jul 2025 22:31:16 +0700 Subject: [PATCH] kernel: selinux: replace rcu_read_{lock, unlock} to mutex_{lock, unlock} * We got a splat related to atomic sleep. * The trace is from strncpy_from_user and might_fault Same case: https://github.com/rsuntk/KernelSU/commit/e47115e00956a8b25df73f92b544783a9fdc2afe Signed-off-by: rsuntk --- kernel/selinux/rules.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/kernel/selinux/rules.c b/kernel/selinux/rules.c index caddefdb..8ef7b4bf 100644 --- a/kernel/selinux/rules.c +++ b/kernel/selinux/rules.c @@ -36,8 +36,7 @@ static struct policydb *get_policydb(void) return db; } -static DEFINE_MUTEX(ksu_rules); - +static DEFINE_MUTEX(apply_ksu_rules_mutex); void apply_kernelsu_rules() { struct policydb *db; @@ -46,7 +45,7 @@ void apply_kernelsu_rules() pr_info("SELinux permissive or disabled, apply rules!\n"); } - mutex_lock(&ksu_rules); + mutex_lock(&apply_ksu_rules_mutex); db = get_policydb(); @@ -140,7 +139,7 @@ void apply_kernelsu_rules() ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "getpgid"); ksu_allow(db, "system_server", KERNEL_SU_DOMAIN, "process", "sigkill"); - mutex_unlock(&ksu_rules); + mutex_unlock(&apply_ksu_rules_mutex); } #define MAX_SEPOL_LEN 128 @@ -224,6 +223,7 @@ static void reset_avc_cache() selinux_xfrm_notify_policyload(); } +static DEFINE_MUTEX(ksu_handle_sepolicy_mutex); int handle_sepolicy(unsigned long arg3, void __user *arg4) { if (!arg4) { @@ -270,9 +270,11 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4) subcmd = data.subcmd; } - rcu_read_lock(); + struct policydb *db; - struct policydb *db = get_policydb(); + mutex_lock(&ksu_handle_sepolicy_mutex); + + db = get_policydb(); int ret = -1; if (cmd == CMD_NORMAL_PERM) { @@ -522,7 +524,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4) } exit: - rcu_read_unlock(); + mutex_unlock(&ksu_handle_sepolicy_mutex); // only allow and xallow needs to reset avc cache, but we cannot do that because // we are in atomic context. so we just reset it every time.