kernel: refine prctl harden

* I am not sure if this gonna defeats the main purpose or not,
but it fix prctl issue.

Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
This commit is contained in:
rsuntk
2025-10-04 09:00:29 +07:00
committed by ShirkNeko
parent f05b20dbce
commit 994999c8ce
2 changed files with 19 additions and 18 deletions

View File

@@ -295,36 +295,37 @@ static void init_uid_scanner(void)
} }
} }
static inline bool is_prctl_valid(int option)
{
// do uid checks first before compare to 0xdeadbeef
if (is_allow_su()) {
if (option == KERNEL_SU_OPTION)
return true;
}
return false;
}
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3, int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5) unsigned long arg4, unsigned long arg5)
{ {
// if success, we modify the arg5 as result! // if success, we modify the arg5 as result!
u32 *result = (u32 *)arg5; u32 *result = (u32 *)arg5;
u32 reply_ok = KERNEL_SU_OPTION; u32 reply_ok = KERNEL_SU_OPTION;
uid_t current_uid_val = current_uid().val;
// we can skip this check when a manager is crowned already // we can skip this check when a manager is crowned already
if (likely(ksu_is_manager_uid_valid())) if (likely(ksu_is_manager_uid_valid()))
goto skip_check; goto skip;
// 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(); uid_t manager_uid = ksu_get_manager_uid();
if (current_uid_val != manager_uid && if (current_uid_val != manager_uid &&
current_uid_val % 100000 == manager_uid) { current_uid_val % 100000 == manager_uid) {
ksu_set_manager_uid(current_uid_val); ksu_set_manager_uid(current_uid_val);
} }
skip_check: skip:
// yes this causes delay, but this keeps the delay consistent, which is what we want kcompat_barrier();
// with a proper barrier for safety as the compiler and cpu might try to do something smart. if (!is_prctl_valid(option))
KCOMPAT_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
if (KERNEL_SU_OPTION != option)
return 0; return 0;
bool from_root = 0 == current_uid().val; bool from_root = 0 == current_uid().val;

View File

@@ -8,11 +8,11 @@
#include "linux/key.h" #include "linux/key.h"
#if defined(CONFIG_X86) #if defined(CONFIG_X86)
#define KCOMPAT_BARRIER() barrier_nospec() #define kcompat_barrier() barrier_nospec()
#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64) #elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
#define KCOMPAT_BARRIER() isb() // arch/arm64/include/asm/barrier.h #define kcompat_barrier() isb() // arch/arm64/include/asm/barrier.h
#else #else
#define KCOMPAT_BARRIER() barrier() // well, compiler atleast. #define kcompat_barrier() barrier() // well, compiler atleast.
#endif #endif
/** /**