diff --git a/kernel/linux/include/linux/err.h b/kernel/linux/include/linux/err.h index df1ea597..9f50c920 100644 --- a/kernel/linux/include/linux/err.h +++ b/kernel/linux/include/linux/err.h @@ -18,11 +18,16 @@ static inline long __must_check PTR_ERR(__force const void *ptr) return (long)ptr; } -static inline int __must_check IS_ERR(__force const void *ptr) +static inline bool __must_check IS_ERR(__force const void *ptr) { return IS_ERR_VALUE((unsigned long)ptr); } +static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) +{ + return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr); +} + static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) { if (IS_ERR(ptr)) diff --git a/kernel/patch/android/userd.c b/kernel/patch/android/userd.c index 3ebb758e..1d251385 100644 --- a/kernel/patch/android/userd.c +++ b/kernel/patch/android/userd.c @@ -33,6 +33,54 @@ #include #include +#define ORIGIN_RC_FILE "/system/etc/init/atrace.rc" +#define REPLACE_RC_FILE "/dev/anduser.rc" + +#define ADB_FLODER "/data/adb/" +#define AP_DIR "/data/adb/ap/" +#define AP_BIN_DIR AP_DIR "bin/" +#define AP_LOG_DIR AP_DIR "log/" + +#define KPM_LOAD_SH "/dev/load_module.sh" + +static const char user_rc_data[] = { // + "\n" + "on post-fs-data\n" + " exec -- " SUPERCMD " su exec " KPM_LOAD_SH " %s post-fs-data\n" + " exec -- " SUPERCMD " su exec " APD_PATH " -s %s post-fs-data\n" + "on nonencrypted\n" + " exec -- " SUPERCMD " su exec " APD_PATH " -s %s services\n" + "on property:vold.decrypt=trigger_restart_framework\n" + " exec -- " SUPERCMD " su exec " APD_PATH " -s %s services\n" + "on property:sys.boot_completed=1\n" + " exec -- " SUPERCMD " su exec " APD_PATH " -s %s boot-completed\n" + " exec -- " SUPERCMD " su exec /system/bin/rm " REPLACE_RC_FILE "\n" + " exec -- " SUPERCMD " su exec /system/bin/rm " KPM_LOAD_SH "\n" + "" +}; + +static const char load_module_sh[] = // + "#!/bin/sh\n" + "mods_dir=\"/data/adb/ap/kpmods/\"\n" + "if [ ! -d \"$mods_dir\" ]; then \n" + " echo \"Error: no modules\"\n" + " exit 0\n" + "fi\n" + "for dir in \"$mods_dir/*\"; do\n" + " if [ ! -d \"$dir\" ]; then continue; fi\n" + " if [ -e \"$dir/disable\" ]; then continue; fi\n" + " main_sh=\"$dir/main.sh\"\n" + " if [ -e \"$main_sh\" ]; then\n" + " touch \"$dir/disable\"\n" + " echo \"loading $dir/main.sh ...\"\n" + " . \"$main_sh\"\n" + " rm -f \"$dir/disable\"\n" + " else\n" + " echo \"Error: $main_sh not found in $dir\"\n" + " fi\n" + "done\n"; +; + static const void *kernel_read_file(const char *path, loff_t *len) { set_priv_sel_allow(current, true); @@ -55,33 +103,34 @@ static const void *kernel_read_file(const char *path, loff_t *len) return data; } -// static loff_t kernel_write_file(const char *path, const void *data, loff_t len, umode_t mode) -// { -// loff_t off = 0; -// set_priv_sel_allow(current, true); - -// struct file *fp = filp_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode); -// if (!fp || IS_ERR(fp)) { -// log_boot("create file %s error: %d\n", path, PTR_ERR(fp)); -// goto out; -// } -// kernel_write(fp, data, len, &off); -// if (off != len) { -// log_boot("write file %s error: %x\n", path, off); -// goto free; -// } - -// free: -// filp_close(fp, 0); - -// out: -// set_priv_sel_allow(current, false); -// return off; -// } +static loff_t kernel_write_file(const char *path, const void *data, loff_t len, umode_t mode) +{ + loff_t off = 0; + set_priv_sel_allow(current, true); + + struct file *fp = filp_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode); + if (!fp || IS_ERR(fp)) { + log_boot("create file %s error: %d\n", path, PTR_ERR(fp)); + goto out; + } + kernel_write(fp, data, len, &off); + if (off != len) { + log_boot("write file %s error: %x\n", path, off); + goto free; + } + +free: + filp_close(fp, 0); + +out: + set_priv_sel_allow(current, false); + return off; +} static void pre_user_exec_init() { log_boot("event: %s\n", EXTRA_EVENT_PRE_EXEC_INIT); + kernel_write_file(KPM_LOAD_SH, load_module_sh, sizeof(load_module_sh), 0700); } static void pre_init_second_stage() @@ -215,28 +264,6 @@ static void after_execveat(hook_fargs5_t *args, void *udata) handle_after_execve(&args->local); } -#define ORIGIN_RC_FILE "/system/etc/init/atrace.rc" -#define REPLACE_RC_FILE "/dev/anduser.rc" - -#define ADB_FLODER "/data/adb/" -#define AP_DIR "/data/adb/ap/" -#define AP_BIN_DIR AP_DIR "bin/" -#define AP_LOG_DIR AP_DIR "log/" - -static const char user_rc_data[] = { // - "\n" - "on post-fs-data\n" - " exec -- " SUPERCMD " su exec " APD_PATH " -s %s post-fs-data\n" - "on nonencrypted\n" - " exec -- " SUPERCMD " su exec " APD_PATH " -s %s services\n" - "on property:vold.decrypt=trigger_restart_framework\n" - " exec -- " SUPERCMD " su exec " APD_PATH " -s %s services\n" - "on property:sys.boot_completed=1\n" - " exec -- " SUPERCMD " su exec " APD_PATH " -s %s boot-completed\n" - "\n" - "" -}; - // https://elixir.bootlin.com/linux/v6.1/source/fs/open.c#L1337 // SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, umode_t, mode) static void before_openat(hook_fargs4_t *args, void *udata) @@ -277,7 +304,7 @@ static void before_openat(hook_fargs4_t *args, void *udata) char added_rc_data[2048]; const char *sk = get_superkey(); - sprintf(added_rc_data, user_rc_data, sk, sk, sk, sk); + sprintf(added_rc_data, user_rc_data, sk, sk, sk, sk, sk); kernel_write(newfp, added_rc_data, strlen(added_rc_data), &off); if (off != strlen(added_rc_data) + ori_len) { diff --git a/kernel/patch/common/supercmd.c b/kernel/patch/common/supercmd.c index a3bfa0ce..b7f4eca7 100644 --- a/kernel/patch/common/supercmd.c +++ b/kernel/patch/common/supercmd.c @@ -94,7 +94,7 @@ static const char supercmd_help[] = " key [...]: Superkey manager\n" " SubCommand:\n" " key [SUPERKEY]: Get or Reset current superkey\n" - " hash [enable|disable]: Whether to use hash to verify the root superkey.\n" + " hash : Whether to use hash to verify the root superkey.\n" ""; void handle_supercmd(char **__user u_filename_p, char **__user uargv) @@ -322,17 +322,19 @@ void handle_supercmd(char **__user u_filename_p, char **__user uargv) reset_superkey(key); } else if (!strcmp("hash", sub_cmd)) { const char *able = carr[2]; - if (!strcmp("enable", able) || !strcmp("disable", able)) { + if (able && !strcmp("enable", able)) { msg = able; enable_auth_root_key(true); - } else if (!strcmp("disable", able)) { + } else if (able && !strcmp("disable", able)) { msg = able; enable_auth_root_key(false); } else { - err_msg = "enable or disable"; + err_msg = "invalid enable or disable"; + goto echo; } } else { err_msg = "invalid subcommand"; + goto echo; } } else if (!strcmp("module", cmd)) { if (!is_key_auth) { @@ -392,9 +394,11 @@ void handle_supercmd(char **__user u_filename_p, char **__user uargv) msg = buffer; } else { err_msg = "invalid subcommand"; + goto echo; } } else { err_msg = "invalid command"; + goto echo; } } diff --git a/kernel/patch/common/taskob.c b/kernel/patch/common/taskob.c index e82fa8e4..5f731658 100644 --- a/kernel/patch/common/taskob.c +++ b/kernel/patch/common/taskob.c @@ -37,7 +37,7 @@ static void prepare_task_ext(struct task_struct *new, struct task_struct *old) { struct task_ext *old_ext = get_task_ext(old); if (unlikely(!task_ext_valid(old_ext))) { - logkfe("dirty task_ext, pid(maybe dirty): %d\n", old_ext->pid); + logkfe("dirty task_ext, pid(maybe dirty): %d\n", old_ext->pid); return; } struct task_ext *new_ext = get_task_ext(new); @@ -54,7 +54,7 @@ static void prepare_task_ext(struct task_struct *new, struct task_struct *old) dsb(ish); } -int task_ext_size = (sizeof(struct task_ext) - sizeof(int)); +int task_ext_size = offsetof(struct task_ext, _magic); KP_EXPORT_SYMBOL(task_ext_size); static void after_copy_process(hook_fargs8_t *args, void *udata)