kernel: allow only perms for /{system | vendor | product | system_ext}/bin/su path

kernel: guard kernelnosu perms if not using KSU_KPROBES_HOOK
This commit is contained in:
Rifat Azad
2025-07-24 01:24:20 +06:00
parent d69a72c658
commit 3f4c23a34f

View File

@@ -255,14 +255,32 @@ static void nuke_ext4_sysfs() {
path_put(&path); path_put(&path);
} }
static bool is_system_bin_su() static bool is_system_bin_su(void)
{ {
// YES in_execve becomes 0 when it succeeds. static const char *su_paths[] = {
if (!current->mm || current->in_execve) "/system/bin/su",
return false; "/vendor/bin/su",
"/product/bin/su",
"/system_ext/bin/su",
"/odm/bin/su",
"/system/xbin/su",
"/system_ext/xbin/su"
};
char path_buf[256];
char *pathname;
int i;
// quick af check struct mm_struct *mm = current->mm;
return (current->mm->exe_file && !strcmp(current->mm->exe_file->f_path.dentry->d_name.name, "su")); if (mm && mm->exe_file) {
pathname = d_path(&mm->exe_file->f_path, path_buf, sizeof(path_buf));
if (!IS_ERR(pathname)) {
for (i = 0; i < ARRAY_SIZE(su_paths); i++) {
if (strcmp(pathname, su_paths[i]) == 0)
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,
@@ -287,11 +305,18 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
bool from_root = 0 == current_uid().val; bool from_root = 0 == current_uid().val;
bool from_manager = is_manager(); bool from_manager = is_manager();
#ifdef CONFIG_KSU_KPROBES_HOOK
if (!from_root && !from_manager if (!from_root && !from_manager
&& !(is_allow_su() && is_system_bin_su())) { && !(is_allow_su() && is_system_bin_su())) {
// only root or manager can access this interface // only root or manager can access this interface
return 0; return 0;
} }
#else
if (!from_root && !from_manager) {
// only root or manager can access this interface
return 0;
}
#endif
#ifdef CONFIG_KSU_DEBUG #ifdef CONFIG_KSU_DEBUG
pr_info("option: 0x%x, cmd: %ld\n", option, arg2); pr_info("option: 0x%x, cmd: %ld\n", option, arg2);
@@ -457,6 +482,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0; return 0;
} }
#ifdef CONFIG_KSU_KPROBES_HOOK
if (arg2 == CMD_ENABLE_SU) { if (arg2 == CMD_ENABLE_SU) {
bool enabled = (arg3 != 0); bool enabled = (arg3 != 0);
if (enabled == ksu_su_compat_enabled) { if (enabled == ksu_su_compat_enabled) {
@@ -480,6 +506,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
return 0; return 0;
} }
#endif
// all other cmds are for 'root manager' // all other cmds are for 'root manager'
if (!from_manager) { if (!from_manager) {
@@ -534,6 +561,32 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
} }
return 0; return 0;
} }
#ifndef CONFIG_KSU_KPROBES_HOOK
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) {
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;
}
#endif
return 0; return 0;
} }