You've already forked KernelSU-Next
mirror of
https://github.com/KernelSU-Next/KernelSU-Next.git
synced 2025-08-27 23:46:34 +00:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user