From b537b957bd6d8b1ce0aaf24e632d4a8b44e912c8 Mon Sep 17 00:00:00 2001 From: backslashxx <118538522+backslashxx@users.noreply.github.com> Date: Thu, 2 Oct 2025 15:53:11 +0700 Subject: [PATCH] kernel: harden prctl check Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com> Signed-off-by: rsuntk --- kernel/core_hook.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/kernel/core_hook.c b/kernel/core_hook.c index 22da1eb0..6bf11895 100644 --- a/kernel/core_hook.c +++ b/kernel/core_hook.c @@ -300,19 +300,37 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, u32 *result = (u32 *)arg5; u32 reply_ok = KERNEL_SU_OPTION; - if (KERNEL_SU_OPTION != option) { - return 0; - } + // we can skip this check when a manager is crowned already + if (likely(ksu_is_manager_uid_valid())) + goto skip_check; - // TODO: find it in throne tracker! + // this is mostly for that multiuser bs + // here we just let them suffer uid_t current_uid_val = current_uid().val; uid_t manager_uid = ksu_get_manager_uid(); - if (current_uid_val != manager_uid && - current_uid_val % 100000 == manager_uid) { - ksu_set_manager_uid(current_uid_val); + if (current_uid_val != manager_uid && + current_uid_val % 100000 == manager_uid) { + ksu_set_manager_uid(current_uid_val); + // make sure all cpus sees this change, next line will check + smp_mb(); } - bool from_root = 0 == current_uid().val; +skip_check: + // yes this causes delay, but this keeps the delay consistent, which is what we want + barrier(); + if (!is_allow_su()) + return 0; + + // we move it after uid check here so they cannot + // compare 0xdeadbeef call to a non-0xdeadbeef call + // with barriers around for safety as the compiler + // might try to do something smart. + barrier(); + if (KERNEL_SU_OPTION != option) + return 0; + + // just continue old logic + bool from_root = !current_uid().val; bool from_manager = is_manager(); if (!from_root && !from_manager) {