From 0401fca5cb466a55f92fccaee3a8712ba34575a5 Mon Sep 17 00:00:00 2001 From: xeropresence <3128949+xeropresence@users.noreply.github.com> Date: Fri, 18 Sep 2026 19:41:56 -0400 Subject: [PATCH] android: redirect init rc paths without overwriting buffers --- kernel/patch/android/userd.c | 43 +++++++++++++++++------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/kernel/patch/android/userd.c b/kernel/patch/android/userd.c index d2b43b22..2781f55d 100644 --- a/kernel/patch/android/userd.c +++ b/kernel/patch/android/userd.c @@ -127,7 +127,6 @@ static const char user_rc_data[] = { // "on property:sys.boot_completed=1\n" " exec -- " SUPERCMD " su -Z " MAGISK_SCTX " exec " APD_PATH " -s %s boot-completed\n" " exec -- " SUPERCMD " su event boot-completed\n" - " exec -- " SUPERCMD " su -Z " MAGISK_SCTX " exec " APD_PATH " uid-listener &\n" " rm " REPLACE_RC_FILE "\n" " exec -- " SUPERCMD " su -Z " MAGISK_SCTX " -c \"mv -f " DEV_LOG_DIR " " AP_LOG_DIR "\"\n" "" @@ -1723,9 +1722,9 @@ static void after_execveat(hook_fargs5_t *args, void *udata) static void before_openat(hook_fargs4_t *args, void *udata) { - // cp len + // redirected flag args->local.data0 = 0; - // cp ptr + // original filename argument args->local.data1 = 0; // unhook flag args->local.data2 = 0; @@ -1739,7 +1738,7 @@ static void before_openat(hook_fargs4_t *args, void *udata) const char __user *filename = (typeof(filename))syscall_argn(args, 1); char buf[256]; long rc = compat_strncpy_from_user(buf, filename, sizeof(buf)); - if (rc <= 0) return; + if (rc <= 0 || rc >= sizeof(buf)) return; int file_count = sizeof(ORIGIN_RC_FILES) / sizeof(ORIGIN_RC_FILES[0]); for (int i = 0; i < file_count; i++) { @@ -1768,7 +1767,7 @@ static void before_openat(hook_fargs4_t *args, void *udata) loff_t off = 0; const char *ori_rc_data = kernel_read_file(origin_rc, &ori_len); - if (!ori_rc_data) goto out; + if (!ori_rc_data) goto free; kernel_write(newfp, ori_rc_data, ori_len, &off); if (off != ori_len) { log_boot("write replace rc error: %x\n", off); @@ -1789,17 +1788,20 @@ static void before_openat(hook_fargs4_t *args, void *udata) goto free; } - int cplen = 0; - cplen = compat_copy_to_user((void *)filename, REPLACE_RC_FILE, sizeof(REPLACE_RC_FILE)); - if (cplen > 0) { - args->local.data0 = cplen; - args->local.data1 = (uint64_t)args->arg1; - log_boot("redirect rc file: %x\n", args->local.data0); - } else { - void *__user up = copy_to_user_stack(REPLACE_RC_FILE, sizeof(REPLACE_RC_FILE)); - args->arg1 = (uint64_t)up; - log_boot("redirect rc file stack: %llx\n", up); + /* Never overwrite init's filename allocation: /init.rc is shorter than + * REPLACE_RC_FILE, and the 64-byte table entries are not buffer sizes. */ + uintptr_t sp = current_user_stack_pointer(); + if (sp < sizeof(REPLACE_RC_FILE)) goto free; + sp = (sp - sizeof(REPLACE_RC_FILE)) & ~(uintptr_t)15; + int cplen = compat_copy_to_user((void *__user)sp, REPLACE_RC_FILE, sizeof(REPLACE_RC_FILE)); + if (cplen != sizeof(REPLACE_RC_FILE)) { + log_boot("redirect rc file copy error: %d\n", cplen); + goto free; } + args->local.data0 = 1; + args->local.data1 = syscall_argn(args, 1); + set_syscall_argn(args, 1, sp); + log_boot("redirect rc file stack: %llx\n", sp); free: filp_close(newfp, 0); @@ -1812,14 +1814,9 @@ static void before_openat(hook_fargs4_t *args, void *udata) static void after_openat(hook_fargs4_t *args, void *udata) { - if (args->local.data0 && args->local.data3 > 0) { - - const char *origin_rc = ORIGIN_RC_FILES[args->local.data3 - 1]; - compat_copy_to_user( - (void *)args->local.data1, - origin_rc, - sizeof(ORIGIN_RC_FILES[args->local.data3 - 1])); - log_boot("restore rc file: %x\n", args->local.data0); + if (args->local.data0) { + set_syscall_argn(args, 1, args->local.data1); + log_boot("redirect rc file open result: %ld\n", (long)args->ret); } if (args->local.data2) { unhook_syscalln(__NR_openat, before_openat, after_openat);