Skip to content

Commit 3f4c23a

Browse files
committed
kernel: allow only perms for /{system | vendor | product | system_ext}/bin/su path
kernel: guard kernelnosu perms if not using KSU_KPROBES_HOOK
1 parent d69a72c commit 3f4c23a

File tree

1 file changed

+60
-7
lines changed

1 file changed

+60
-7
lines changed

kernel/core_hook.c

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,14 +255,32 @@ static void nuke_ext4_sysfs() {
255255
path_put(&path);
256256
}
257257

258-
static bool is_system_bin_su()
258+
static bool is_system_bin_su(void)
259259
{
260-
// YES in_execve becomes 0 when it succeeds.
261-
if (!current->mm || current->in_execve)
262-
return false;
263-
264-
// quick af check
265-
return (current->mm->exe_file && !strcmp(current->mm->exe_file->f_path.dentry->d_name.name, "su"));
260+
static const char *su_paths[] = {
261+
"/system/bin/su",
262+
"/vendor/bin/su",
263+
"/product/bin/su",
264+
"/system_ext/bin/su",
265+
"/odm/bin/su",
266+
"/system/xbin/su",
267+
"/system_ext/xbin/su"
268+
};
269+
char path_buf[256];
270+
char *pathname;
271+
int i;
272+
273+
struct mm_struct *mm = current->mm;
274+
if (mm && mm->exe_file) {
275+
pathname = d_path(&mm->exe_file->f_path, path_buf, sizeof(path_buf));
276+
if (!IS_ERR(pathname)) {
277+
for (i = 0; i < ARRAY_SIZE(su_paths); i++) {
278+
if (strcmp(pathname, su_paths[i]) == 0)
279+
return true;
280+
}
281+
}
282+
}
283+
return false;
266284
}
267285

268286
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,
287305
bool from_root = 0 == current_uid().val;
288306
bool from_manager = is_manager();
289307

308+
#ifdef CONFIG_KSU_KPROBES_HOOK
290309
if (!from_root && !from_manager
291310
&& !(is_allow_su() && is_system_bin_su())) {
292311
// only root or manager can access this interface
293312
return 0;
294313
}
314+
#else
315+
if (!from_root && !from_manager) {
316+
// only root or manager can access this interface
317+
return 0;
318+
}
319+
#endif
295320

296321
#ifdef CONFIG_KSU_DEBUG
297322
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,
457482
return 0;
458483
}
459484

485+
#ifdef CONFIG_KSU_KPROBES_HOOK
460486
if (arg2 == CMD_ENABLE_SU) {
461487
bool enabled = (arg3 != 0);
462488
if (enabled == ksu_su_compat_enabled) {
@@ -480,6 +506,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
480506

481507
return 0;
482508
}
509+
#endif
483510

484511
// all other cmds are for 'root manager'
485512
if (!from_manager) {
@@ -534,6 +561,32 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
534561
}
535562
return 0;
536563
}
564+
#ifndef CONFIG_KSU_KPROBES_HOOK
565+
if (arg2 == CMD_ENABLE_SU) {
566+
bool enabled = (arg3 != 0);
567+
if (enabled == ksu_su_compat_enabled) {
568+
pr_info("cmd enable su but no need to change.\n");
569+
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {// return the reply_ok directly
570+
pr_err("prctl reply error, cmd: %lu\n", arg2);
571+
}
572+
return 0;
573+
}
574+
575+
if (enabled) {
576+
ksu_sucompat_init();
577+
} else {
578+
ksu_sucompat_exit();
579+
}
580+
ksu_su_compat_enabled = enabled;
581+
582+
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
583+
pr_err("prctl reply error, cmd: %lu\n", arg2);
584+
}
585+
586+
return 0;
587+
}
588+
#endif
589+
537590

538591
return 0;
539592
}

0 commit comments

Comments
 (0)