kernel: core_hook: add support for KernelNoSU ([#270](https://github.com/SukiSU-Ultra/SukiSU-Ultra/issues/270))

reorder ksu_handle_prctl checks a bit to allow non-manager to use CMD 15
this allows us to piggyback a small su to KernelSU's permission system after
disabling kernel sucompat

from:
Relax prctl perm check
- 95125c32f9
Allow prctl only for root or manager or su binary
- fa7af67d94
Refine prctl access check, allow /product/bin/su
- dd466dc1b6
Refine prctl check a little bit more
- e7c5b24efa

Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: nampud <nampud@users.noreply.github.com>
This commit is contained in:
ShirkNeko
2025-09-27 23:59:21 +08:00
parent 3140d9671f
commit 3f0f34e5b1

View File

@@ -353,6 +353,16 @@ static inline void nuke_ext4_sysfs(void)
}
#endif
static bool is_system_bin_su()
{
// YES in_execve becomes 0 when it succeeds.
if (!current->mm || current->in_execve)
return false;
// quick af check
return (current->mm->exe_file && !strcmp(current->mm->exe_file->f_path.dentry->d_name.name, "su"));
}
static void init_uid_scanner(void)
{
ksu_uid_init();
@@ -388,7 +398,8 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
bool from_root = 0 == current_uid().val;
bool from_manager = is_manager();
if (!from_root && !from_manager) {
if (!from_root && !from_manager
&& !(is_allow_su() && is_system_bin_su())) {
// only root or manager can access this interface
return 0;
}
@@ -621,6 +632,36 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
}
#endif
if (arg2 == CMD_ENABLE_SU) {
bool enabled = (arg3 != 0);
if (enabled == ksu_su_compat_enabled) {
pr_info("cmd enable su but no need to change.\n");
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {// return the reply_ok directly
pr_err("prctl reply error, cmd: %lu\n", arg2);
}
return 0;
}
if (enabled) {
#ifdef CONFIG_KSU_SUSFS_SUS_SU
// We disable all sus_su hook whenever user toggle on su_kps
susfs_is_sus_su_hooks_enabled = false;
ksu_devpts_hook = false;
susfs_sus_su_working_mode = SUS_SU_DISABLED;
#endif
ksu_sucompat_init();
} else {
ksu_sucompat_exit();
}
ksu_su_compat_enabled = enabled;
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %lu\n", arg2);
}
return 0;
}
// Check if kpm is enabled
if (arg2 == CMD_ENABLE_KPM) {
bool KPM_Enabled = IS_ENABLED(CONFIG_KPM);
@@ -1089,36 +1130,6 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0;
}
if (arg2 == CMD_ENABLE_SU) {
bool enabled = (arg3 != 0);
if (enabled == ksu_su_compat_enabled) {
pr_info("cmd enable su but no need to change.\n");
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {// return the reply_ok directly
pr_err("prctl reply error, cmd: %lu\n", arg2);
}
return 0;
}
if (enabled) {
#ifdef CONFIG_KSU_SUSFS_SUS_SU
// We disable all sus_su hook whenever user toggle on su_kps
susfs_is_sus_su_hooks_enabled = false;
ksu_devpts_hook = false;
susfs_sus_su_working_mode = SUS_SU_DISABLED;
#endif
ksu_sucompat_init();
} else {
ksu_sucompat_exit();
}
ksu_su_compat_enabled = enabled;
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("prctl reply error, cmd: %lu\n", arg2);
}
return 0;
}
// UID Scanner control command
if (arg2 == CMD_ENABLE_UID_SCANNER) {
if (arg3 == 0) {