From 9d7e33ef89f21197c4192bc3e8bf23f756560f19 Mon Sep 17 00:00:00 2001 From: bmax Date: Mon, 29 Jan 2024 15:56:33 +0800 Subject: [PATCH 01/51] feat: support detach embeded kpm --- doc/module.md | 20 +++++- kpm-demo/hello/hello.c | 23 ++++++- tools/kptools.c | 4 +- tools/patch.c | 149 ++++++++++++++++++++++++++++------------- tools/patch.h | 2 +- version | 2 +- 6 files changed, 143 insertions(+), 57 deletions(-) diff --git a/doc/module.md b/doc/module.md index 2c533a30..e73f34d3 100644 --- a/doc/module.md +++ b/doc/module.md @@ -1,5 +1,21 @@ # KernelPatch Module -todo +## What is KernelPatch Module (KPM) -[demo here](/kpm-demo/) \ No newline at end of file + **KPM is an ELF file that can be loaded and run within the kernel space by KernelPatch.** + + KPM in principle and implementation is quite similar to LKM. There is no doubt about this, as much of the implementation code in KPM is derived from LKM. However, this does not imply a seamless transition from LKM to KPM, as there may be numerous compatibility issues. + + **The design purpose of KPM is not to replace LKM; rather, KPM is intended to accomplish specific, small, and elegant tasks, such as monitoring and hiding. Of course, if you want to develop a complex module, you can do that too.** + +## How to write a KPM + + Here are a few examples that you can use to quickly understand. + +1. A simple hello world KPM: [hello-world](/kpm-demo/hello) +2. How to do kernel function inline-hook via KPM: [inline-hook](/kpm-demo/inlinehook) +3. How to hook system call via KPM: [syscallhook](/kpm-demo/syscallhook) + +### Working without Kernel source tree + +### Working with Kernel soruce tree diff --git a/kpm-demo/hello/hello.c b/kpm-demo/hello/hello.c index 22fba354..990016b6 100644 --- a/kpm-demo/hello/hello.c +++ b/kpm-demo/hello/hello.c @@ -9,20 +9,37 @@ #include #include +///< The name of the module, each KPM must has a unique name. KPM_NAME("kpm-hello-demo"); + +///< The version of the module. KPM_VERSION("1.0.0"); + +///< The license type. KPM_LICENSE("GPL v2"); + +///< The author. KPM_AUTHOR("bmax121"); + +///< The description. KPM_DESCRIPTION("KernelPatch Module Example"); -int hello_init(const char *args, void *__user reserved) +/** + * @brief hello world initialization + * @details + * + * @param args + * @param reserved + * @return int + */ +static int hello_init(const char *args, void *__user reserved) { pr_info("kpm hello init, args: %s\n", args); pr_info("kernelpatch version: %x\n", kpver); return 0; } -int hello_control(const char *args, char *__user out_msg, int outlen) +static int hello_control(const char *args, char *__user out_msg, int outlen) { pr_info("kpm hello control, args: %s\n", args); char echo[] = "hello kpm\n"; @@ -30,7 +47,7 @@ int hello_control(const char *args, char *__user out_msg, int outlen) return 0; } -int hello_exit(void *__user reserved) +static int hello_exit(void *__user reserved) { pr_info("kpm hello exit\n"); return 0; diff --git a/tools/kptools.c b/tools/kptools.c index 6b895a8f..f22fefb2 100644 --- a/tools/kptools.c +++ b/tools/kptools.c @@ -54,7 +54,7 @@ void print_usage(char **argv) " -E, --embed-kpm PATH Embed KPM into patches.\n" " -A, --embed-kpm-args ARGS KPM args will be passed to previous KPM(-E).\n" - " -D, --detach-kpm NAME (not implemented) Detach embeded KPM from patches.\n" + " -D, --detach-kpm NAME Detach embeded KPM from patches.\n" " -M, --kpm PATH Specify KPM path.\n" "\n"; fprintf(stdout, c, version, program_name); @@ -164,7 +164,7 @@ int main(int argc, char *argv[]) } else if (cmd == 'l') { if (kimg_path) print_image_patch_info_path(kimg_path); if (alone_kpm_path) print_kpm_info_path(alone_kpm_path); - if (kpimg_path) print_kp_image_info(kpimg_path); + if (kpimg_path) print_kp_image_info_path(kpimg_path); } else { diff --git a/tools/patch.c b/tools/patch.c index 6708887e..d5a33ac0 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -53,7 +53,7 @@ void print_preset_info(preset_t *preset) fprintf(stdout, "config=%s,%s\n", is_debug ? "debug" : "release", is_android ? "android" : "linux"); } -void print_kp_image_info(const char *kpimg_path) +void print_kp_image_info_path(const char *kpimg_path) { fprintf(stdout, "path=%s\n", kpimg_path); char *kpimg; @@ -81,18 +81,15 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) if (!old_preset) { tools_logi("new kernel image ...\n"); pimg->ori_kimg_len = pimg->kimg_len; - // free((void *)kimg); return 0; } tools_logi("patched kernel image ...\n"); int saved_kimg_len = old_preset->setup.kimg_size; int align_kimg_len = (char *)old_preset - kimg; - if (align_kimg_len == (int)align_ceil(saved_kimg_len, SZ_4K)) { - pimg->ori_kimg_len = saved_kimg_len; - } else { - pimg->ori_kimg_len = align_kimg_len; - } + if (align_kimg_len != (int)align_ceil(saved_kimg_len, SZ_4K)) tools_error_exit("saved kernel image size error\n"); + pimg->ori_kimg_len = saved_kimg_len; + memcpy((char *)kimg, old_preset->setup.header_backup, sizeof(old_preset->setup.header_backup)); int extra_offset = align_kimg_len + old_preset->setup.kpimg_size; @@ -109,7 +106,6 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) item_addr += item->con_size; } - // free(kimg); return 0; } @@ -120,7 +116,9 @@ int parse_image_patch_info_path(const char *kimg_path, patched_kimg_t *pimg) char *kimg; int kimg_len; read_file(kimg_path, &kimg, &kimg_len); - return parse_image_patch_info(kimg, kimg_len, pimg); + int rc = parse_image_patch_info(kimg, kimg_len, pimg); + free(kimg); + return rc; } void print_image_patch_info(patched_kimg_t *pimg) @@ -155,15 +153,18 @@ void print_image_patch_info(patched_kimg_t *pimg) } } } - // free((void *)pimg.kimg); } void print_image_patch_info_path(const char *kimg_path) { fprintf(stdout, "path=%s\n", kimg_path); patched_kimg_t pimg = { 0 }; - parse_image_patch_info_path(kimg_path, &pimg); + char *kimg; + int kimg_len; + read_file(kimg_path, &kimg, &kimg_len); + int rc = parse_image_patch_info(kimg, kimg_len, &pimg); print_image_patch_info(&pimg); + free(kimg); } // todo: opt @@ -178,7 +179,11 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * if (!superkey) tools_error_exit("empty superkey\n"); patched_kimg_t pimg = { 0 }; - parse_image_patch_info_path(kimg_path, &pimg); + char *kimg; + int kimg_len; + read_file(kimg_path, &kimg, &kimg_len); + int rc = parse_image_patch_info(kimg, kimg_len, &pimg); + if (rc) tools_error_exit("parse kernel image error\n"); // print_image_patch_info(&pimg); // kimg base info @@ -205,9 +210,11 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * struct extra_items_wrap { patch_extra_item_t item; + extra_item_type type; const char *data; const char *args; - int len; + int data_len; + int args_len; union { const char *name; @@ -216,9 +223,11 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * memset(extra_items, 0, sizeof(struct extra_items_wrap) * EXTRA_ITEM_MAX_NUM); + // new extra for (int i = 0; i < embed_kpm_num && extra_num < EXTRA_ITEM_MAX_NUM; i++) { char *kpm_data; - int kpm_len; + int kpm_len = 0; + int args_len = 0; read_file_align(embed_kpm_path[i], &kpm_data, &kpm_len, EXTRA_ALIGN); kpm_info_t kpm_info = { 0 }; @@ -226,39 +235,86 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * if (rc) tools_error_exit("can get infomation of kpm, path: %s\n", embed_kpm_path[i]); struct extra_items_wrap *item_wrap = extra_items + extra_num; - patch_extra_item_t *kpm_item = &item_wrap->item; + patch_extra_item_t *item = &item_wrap->item; - kpm_item->type = EXTRA_TYPE_KPM; - kpm_item->con_size = kpm_len; + // set wrap const char *args = embed_kpm_args[i]; - if (args) { - item_wrap->args = args; - kpm_item->args_size = align_ceil(strlen(args), EXTRA_ALIGN); - } - // todo: - kpm_item->priority = 0; - + if (args) args_len = align_ceil(strlen(args), EXTRA_ALIGN); + item_wrap->type = EXTRA_TYPE_KPM; item_wrap->data = kpm_data; - item_wrap->len = kpm_len; + item_wrap->data_len = kpm_len; + item_wrap->args = args; + item_wrap->args_len = args_len; item_wrap->name = kpm_info.name; + // set runtime item + item->priority = 0; + item->type = EXTRA_TYPE_KPM; + item->con_size = kpm_len; + item->args_size = args_len; if ((is_be() ^ kinfo->is_be)) { - kpm_item->priority = i32swp(kpm_item->priority); - kpm_item->type = i32swp(kpm_item->type); - kpm_item->con_size = i32swp(kpm_item->con_size); - kpm_item->args_size = i32swp(kpm_item->args_size); + item->priority = i32swp(item->priority); + item->type = i32swp(item->type); + item->con_size = i32swp(item->con_size); + item->args_size = i32swp(item->args_size); } - extra_size += sizeof(patch_extra_item_t); - extra_size += kpm_len; - extra_size += kpm_item->args_size; + + extra_size += (kpm_len + args_len + sizeof(patch_extra_item_t)); extra_num++; } + + // reserved pre-patched extra + for (int i = 0; i < pimg.embed_item_num; i++) { + struct extra_items_wrap *item_wrap = extra_items + extra_num; + patch_extra_item_t *item = pimg.embed_item[i]; + + item_wrap->type = item->type; + if ((is_be() ^ kinfo->is_be)) item_wrap->type = i32swp(item_wrap->type); + + bool detach = false; + + if (item_wrap->type == EXTRA_TYPE_KPM) { + kpm_info_t kpm_info = { 0 }; + void *kpm = (kpm_info_t *)((uintptr_t)item + sizeof(patch_extra_item_t) + item->args_size); + get_kpm_info(kpm, item->con_size, &kpm_info); + for (int j = 0; j < detach_kpm_num; j++) { + if (!strcmp(detach_kpm_names[j], kpm_info.name)) { + detach = true; + break; + } + } + if (!detach) { + memcpy(&item_wrap->item, item, sizeof(*item)); + item_wrap->data = (const char *)kpm; + item_wrap->args = (const char *)item + sizeof(*item); + item_wrap->data_len = item->con_size; + item_wrap->args_len = item->args_size; + if ((is_be() ^ kinfo->is_be)) { + item_wrap->data_len = i32swp(item_wrap->data_len); + item_wrap->args_len = i32swp(item_wrap->args_len); + } + item_wrap->name = kpm_info.name; + + extra_size += sizeof(*item) + item_wrap->data_len + item_wrap->args_len; + extra_num++; + tools_logi("reserved embeded kpm: %s\n", kpm_info.name); + } else { + tools_logi("detact embeded kpm: %s\n", kpm_info.name); + } + } else { + // todo + } + } + extra_size += sizeof(patch_extra_item_t); // copy to out image int ori_kimg_len = pimg.ori_kimg_len; - int align_kimg_len = align_ceil(pimg.kimg_len, SZ_4K); + int align_kimg_len = align_ceil(ori_kimg_len, SZ_4K); int out_img_len = align_kimg_len + kpimg_len; + tools_logi("layout kimg: 0x0-0x%x, kpimg: 0x%x-0x%x, extra: 0x%x-0x%x\n", ori_kimg_len, align_kimg_len, kpimg_len, + align_kimg_len + kpimg_len, extra_size); + char *out_img = (char *)malloc(out_img_len); memcpy(out_img, pimg.kimg, ori_kimg_len); memset(out_img + ori_kimg_len, 0, align_kimg_len - ori_kimg_len); @@ -337,11 +393,11 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * // write out write_file(out_path, out_img, out_img_len, false); - // extra + // write extra for (int i = 0; i < extra_num; i++) { struct extra_items_wrap *item_wrap = &extra_items[i]; const char *type = EXTRA_TYPE_NONE; - switch (item_wrap->item.type) { + switch (item_wrap->type) { case EXTRA_TYPE_KPM: type = "kpm"; break; @@ -351,21 +407,17 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * default: break; } - tools_logi("embedding %s, name: %s, size: 0x%x, args: %s\n", type, item_wrap->name, item_wrap->len, - item_wrap->args); - - write_file(out_path, (void *)&item_wrap->item, sizeof(item_wrap->item), true); - int args_size = item_wrap->item.args_size; - if (args_size > 0) { - char *args = (char *)malloc(args_size); - memset(args + args_size - EXTRA_ALIGN, 0, EXTRA_ALIGN); - strcpy(args, item_wrap->args); - write_file(out_path, (void *)item_wrap->args, args_size, true); - free(args); - } - write_file(out_path, (void *)item_wrap->data, item_wrap->len, true); + + patch_extra_item_t *item = &item_wrap->item; + tools_logi("embedding %s, name: %s, size: 0x%x + 0x%x + 0x%x\n", type, item_wrap->name, (int)sizeof(*item), + item_wrap->data_len, item_wrap->args_len); + + write_file(out_path, (void *)item, sizeof(*item), true); + if (item_wrap->args_len > 0) write_file(out_path, (void *)item_wrap->args, item_wrap->args_len, true); + write_file(out_path, (void *)item_wrap->data, item_wrap->data_len, true); } + // guard extra patch_extra_item_t empty_item = { .type = EXTRA_TYPE_NONE, .priority = 0, @@ -378,6 +430,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * free(kallsym_kimg); free(kpimg); free(out_img); + free(kimg); tools_logi("patch done: %s\n", out_path); diff --git a/tools/patch.h b/tools/patch.h index f5babba0..5d628bcb 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -34,7 +34,7 @@ int unpatch_img(const char *kimg_path, const char *out_path); int reset_key(const char *kimg_path, const char *out_path, const char *key); int dump_kallsym(const char *kimg_path); -void print_kp_image_info(const char *kpimg_path); +void print_kp_image_info_path(const char *kpimg_path); void print_image_patch_info(patched_kimg_t *pimg); void print_image_patch_info_path(const char *kimg_path); diff --git a/version b/version index 0e4068f1..20e59d60 100644 --- a/version +++ b/version @@ -1,3 +1,3 @@ #define MAJOR 0 #define MINOR 9 -#define PATCH 0 +#define PATCH 1 From f1694095feaa00de7f672c25a89fc46dfc387d4f Mon Sep 17 00:00:00 2001 From: bmax Date: Mon, 29 Jan 2024 17:13:09 +0800 Subject: [PATCH 02/51] fix: kpatch xxx -v --- user/main.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/user/main.c b/user/main.c index 6974676b..0d9c7d81 100644 --- a/user/main.c +++ b/user/main.c @@ -95,11 +95,15 @@ int main(int argc, char **argv) { "kver", SUPERCALL_KERNEL_VER }, { "su", 's' }, { "kpm", 'k' }, + { "bootlog", 'l' }, { "panic", '.' }, { "test", 't' }, + { "--help", 'h' }, { "-h", 'h' }, + { "--version", 'v' }, + { "-v", 'v' }, #ifdef ANDROID { "sumgr", 'm' }, { "android_user", 'a' }, @@ -130,9 +134,7 @@ int main(int argc, char **argv) case 'k': strcat(program_name, " kpm"); return kpm_main(argc - 2, argv + 2); - case 'm': - strcat(program_name, " sumgr"); - return sumgr_main(argc - 2, argv + 2); + case 'l': bootlog(key); break; @@ -142,11 +144,22 @@ int main(int argc, char **argv) case 't': __test(key); break; + case 'h': usage(EXIT_SUCCESS); break; + case 'v': + fprintf(stdout, "%x\n", version()); + break; + +#ifdef ANDROID + case 'm': + strcat(program_name, " sumgr"); + return sumgr_main(argc - 2, argv + 2); case 'a': return android_user(argc - 2, argv + 2); +#endif + default: fprintf(stderr, "Invalid command: %s!\n", scmd); return -EINVAL; From a38e2ec911d1ef2c722b5dab5afd463367a2a255 Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 30 Jan 2024 10:49:59 +0800 Subject: [PATCH 03/51] a --- kernel/patch/module/module.c | 1 - kpm-demo/hello/hello.c | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/kernel/patch/module/module.c b/kernel/patch/module/module.c index 6f21bd54..6368e1d0 100644 --- a/kernel/patch/module/module.c +++ b/kernel/patch/module/module.c @@ -580,7 +580,6 @@ int control_module(const char *name, const char *ctl_args, char *__user out_msg, if (mod->ctl_args) { kvfree(mod->ctl_args); - mod->ctl_args = NULL; } mod->ctl_args = vmalloc(args_len + 1); diff --git a/kpm-demo/hello/hello.c b/kpm-demo/hello/hello.c index 990016b6..2123111f 100644 --- a/kpm-demo/hello/hello.c +++ b/kpm-demo/hello/hello.c @@ -8,6 +8,7 @@ #include #include #include +#include ///< The name of the module, each KPM must has a unique name. KPM_NAME("kpm-hello-demo"); @@ -42,7 +43,8 @@ static int hello_init(const char *args, void *__user reserved) static int hello_control(const char *args, char *__user out_msg, int outlen) { pr_info("kpm hello control, args: %s\n", args); - char echo[] = "hello kpm\n"; + char echo[64] = "echo: "; + strncat(echo, args, 32); seq_copy_to_user(out_msg, echo, sizeof(echo)); return 0; } From 2ddcaaa10dfa2858aa0eaeb98192dffde80c84d2 Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 30 Jan 2024 22:20:04 +0800 Subject: [PATCH 04/51] a --- kpm-demo/hello/hello.c | 2 +- tools/kallsym.c | 2 +- tools/patch.c | 19 +++++++++++++++++++ tools/patch.h | 1 + 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/kpm-demo/hello/hello.c b/kpm-demo/hello/hello.c index 2123111f..392e4d6c 100644 --- a/kpm-demo/hello/hello.c +++ b/kpm-demo/hello/hello.c @@ -44,7 +44,7 @@ static int hello_control(const char *args, char *__user out_msg, int outlen) { pr_info("kpm hello control, args: %s\n", args); char echo[64] = "echo: "; - strncat(echo, args, 32); + strncat(echo, args, 48); seq_copy_to_user(out_msg, echo, sizeof(echo)); return 0; } diff --git a/tools/kallsym.c b/tools/kallsym.c index 9b411ac2..4b7f1737 100644 --- a/tools/kallsym.c +++ b/tools/kallsym.c @@ -49,7 +49,7 @@ static int find_linux_banner(kallsym_t *info, char *img, int32_t imglen) char *space = strchr(banner + prefix_len, ' '); char *dot = NULL; - // todo: + // VERSION info->version.major = (uint8_t)strtoul(uts_release_start, &dot, 10); // PATCHLEVEL diff --git a/tools/patch.c b/tools/patch.c index d5a33ac0..0c454acf 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -9,6 +9,7 @@ #include #include #include +#include #define _GNU_SOURCE #define __USE_GNU @@ -74,6 +75,19 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) kernel_info_t *kinfo = &pimg->kinfo; if (get_kernel_info(kinfo, kimg, kimg_len)) tools_error_exit("get_kernel_info error\n"); + // find banner + char linux_banner_prefix[] = "Linux version "; + size_t prefix_len = strlen(linux_banner_prefix); + const char *imgend = pimg->kimg + pimg->kimg_len; + const char *banner = (char *)pimg->kimg; + while ((banner = (char *)memmem(banner + 1, imgend - banner, linux_banner_prefix, prefix_len)) != NULL) { + if (isdigit(*(banner + prefix_len)) && *(banner + prefix_len + 1) == '.') { + pimg->banner = banner; + break; + } + } + if (!pimg->banner) tools_error_exit("can't find linux banner\n"); + // patched or new preset_t *old_preset = get_preset(kimg, kimg_len); pimg->preset = old_preset; @@ -92,6 +106,7 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) memcpy((char *)kimg, old_preset->setup.header_backup, sizeof(old_preset->setup.header_backup)); + // extra int extra_offset = align_kimg_len + old_preset->setup.kpimg_size; int extra_size = old_preset->setup.extra_size; @@ -124,6 +139,10 @@ int parse_image_patch_info_path(const char *kimg_path, patched_kimg_t *pimg) void print_image_patch_info(patched_kimg_t *pimg) { preset_t *preset = pimg->preset; + + fprintf(stdout, "linux_banner=%s", pimg->banner); + if (pimg->banner[strlen(pimg->banner) - 1] != '\n') fprintf(stdout, "\n"); + fprintf(stdout, "patched=%s\n", preset ? "true" : "false"); if (preset) { diff --git a/tools/patch.h b/tools/patch.h index 5d628bcb..2fc812e6 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -18,6 +18,7 @@ typedef struct { const char *kimg; int kimg_len; + const char *banner; int ori_kimg_len; kernel_info_t kinfo; preset_t *preset; From b93a034cbf992fd80b906f4433377a7c7f2f86da Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 31 Jan 2024 10:24:47 +0800 Subject: [PATCH 05/51] x --- README.md | 4 +- kernel/include/preset.h | 4 + kernel/patch/old/hooksysc.h | 111 -- kernel/patch/old/lsmhook.c | 2794 ----------------------------------- kernel/patch/old/security.c | 589 -------- kernel/patch/old/selinux.c | 136 -- tools/common.h | 14 +- tools/kallsym.c | 6 +- tools/kpm.c | 2 - tools/patch.c | 27 +- tools/patch.h | 5 + 11 files changed, 37 insertions(+), 3655 deletions(-) delete mode 100644 kernel/patch/old/hooksysc.h delete mode 100644 kernel/patch/old/lsmhook.c delete mode 100644 kernel/patch/old/security.c delete mode 100644 kernel/patch/old/selinux.c diff --git a/README.md b/README.md index e8008d46..0d310c36 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,9 @@ Currently only supports arm64 architecture. Linux 3.18 - 6.2 (theoretically) Linux 6.3+ (not yet adapted) -## Get Help - ## Get Involved -## Community Discussion +Please submit your pull request in **dev** branch ## More Information diff --git a/kernel/include/preset.h b/kernel/include/preset.h index 4401eac3..41d2c0d0 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -135,12 +135,15 @@ _Static_assert(sizeof(patch_symbol_t) == PATCH_SYMBOL_LEN, "sizeof patch_symbol_ #ifndef __ASSEMBLY__ #define EXTRA_ALIGN 0x10 +#define EXTRA_NAME_LEN 0x20 typedef int32_t extra_item_type; #define EXTRA_TYPE_NONE 0 #define EXTRA_TYPE_KPM 1 #define EXTRA_TYPE_SHELL 2 +#define EXTRA_TYPE_EXEC 3 +#define EXTRA_TYPE_RAW 4 struct _patch_extra_item { @@ -148,6 +151,7 @@ struct _patch_extra_item { struct { + char name[EXTRA_NAME_LEN]; extra_item_type type; int32_t priority; int32_t con_size; diff --git a/kernel/patch/old/hooksysc.h b/kernel/patch/old/hooksysc.h deleted file mode 100644 index b04aa387..00000000 --- a/kernel/patch/old/hooksysc.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef _KP_SYSCALL_H_ -#define _KP_SYSCALL_H_ - -#include -#include -#include -#include -#include - -#define __MAP0(m, ...) -#define __MAP1(m, t, a, ...) m(t, a) -#define __MAP2(m, t, a, ...) m(t, a), __MAP1(m, __VA_ARGS__) -#define __MAP3(m, t, a, ...) m(t, a), __MAP2(m, __VA_ARGS__) -#define __MAP4(m, t, a, ...) m(t, a), __MAP3(m, __VA_ARGS__) -#define __MAP5(m, t, a, ...) m(t, a), __MAP4(m, __VA_ARGS__) -#define __MAP6(m, t, a, ...) m(t, a), __MAP5(m, __VA_ARGS__) -#define __MAP(n, ...) __MAP##n(__VA_ARGS__) - -#define __SC_DECL(t, a) t a -#define __SC_ARGS(t, a) a -#define __SC_EMPTY(t, a) 0 - -#define ARM64_REGS_TO_ARGS(x, ...) \ - __MAP(x, __SC_ARGS, , regs->regs[0], , regs->regs[1], , regs->regs[2], , regs->regs[3], , regs->regs[4], , \ - regs->regs[5]) - -#define __REGS_ASSIGN0(n, ...) -#define __REGS_ASSIGN1(n, t, a, ...) \ - a = (t)(regs->regs[n - 1]); \ - __REGS_ASSIGN0(n, __VA_ARGS__) -#define __REGS_ASSIGN2(n, t, a, ...) \ - a = (t)(regs->regs[n - 2]); \ - __REGS_ASSIGN1(n, __VA_ARGS__) -#define __REGS_ASSIGN3(n, t, a, ...) \ - a = (t)(regs->regs[n - 3]); \ - __REGS_ASSIGN2(n, __VA_ARGS__) -#define __REGS_ASSIGN4(n, t, a, ...) \ - a = (t)(regs->regs[n - 4]); \ - __REGS_ASSIGN3(n, __VA_ARGS__) -#define __REGS_ASSIGN5(n, t, a, ...) \ - a = (t)(regs->regs[n - 5]); \ - __REGS_ASSIGN4(n, __VA_ARGS__) -#define __REGS_ASSIGN6(n, t, a, ...) \ - a = (t)(regs->regs[n - 6]); \ - __REGS_ASSIGN5(n, __VA_ARGS__) -#define __REGS_ASSIGN(n, ...) __REGS_ASSIGN##n(n, __VA_ARGS__) - -#define HOOK_SYSCALL_DEFINE(x, nr, ...) \ - static long (*__hook_sys_backup_##nr)(__MAP(x, __SC_DECL, __VA_ARGS__)) = 0; \ - static long (*__hook_sys_wrap_backup_##nr)(const struct pt_regs *regs) = 0; \ - static long __hook_sys_bridge_##nr(const struct pt_regs *regs, __MAP(x, __SC_DECL, __VA_ARGS__)); \ - static long __hook_sys_common_##nr(const struct pt_regs *regs, __MAP(x, __SC_DECL, __VA_ARGS__)); \ - long __attribute__((__noinline__)) __hook_sys_##nr(__MAP(x, __SC_DECL, __VA_ARGS__)) \ - { \ - return __hook_sys_bridge_##nr(0, __MAP(x, __SC_ARGS, __VA_ARGS__)); \ - } \ - long __attribute__((__noinline__)) __hook_sys_wrap_##nr(const struct pt_regs *regs) \ - { \ - return __hook_sys_bridge_##nr(regs, __MAP(x, __SC_EMPTY, __VA_ARGS__)); \ - } \ - static long inline __hook_sys_bridge_##nr(const struct pt_regs *regs, __MAP(x, __SC_DECL, __VA_ARGS__)) \ - { \ - if (regs) { \ - __REGS_ASSIGN(x, __VA_ARGS__); \ - } \ - return __hook_sys_common_##nr(regs, __MAP(x, __SC_ARGS, __VA_ARGS__)); \ - } \ - static long inline __hook_sys_common_##nr(const struct pt_regs *regs, __MAP(x, __SC_DECL, __VA_ARGS__)) - -#define HOOK_SYSCALL_DEFINE0(nr, ...) HOOK_SYSCALL_DEFINE(0, nr, __VA_ARGS__) -#define HOOK_SYSCALL_DEFINE1(nr, ...) HOOK_SYSCALL_DEFINE(1, nr, __VA_ARGS__) -#define HOOK_SYSCALL_DEFINE2(nr, ...) HOOK_SYSCALL_DEFINE(2, nr, __VA_ARGS__) -#define HOOK_SYSCALL_DEFINE3(nr, ...) HOOK_SYSCALL_DEFINE(3, nr, __VA_ARGS__) -#define HOOK_SYSCALL_DEFINE4(nr, ...) HOOK_SYSCALL_DEFINE(4, nr, __VA_ARGS__) -#define HOOK_SYSCALL_DEFINE5(nr, ...) HOOK_SYSCALL_DEFINE(5, nr, __VA_ARGS__) -#define HOOK_SYSCALL_DEFINE6(nr, ...) HOOK_SYSCALL_DEFINE(6, nr, __VA_ARGS__) - -#define __HOOK_SYSCALL_CALL_ORIGIN(nr, ...) \ - (has_syscall_wrapper ? __hook_sys_wrap_backup_##nr(regs) : __hook_sys_backup_##nr(__VA_ARGS__)); - -#define HOOK_SYSCALL_CALL_ORIGIN(nr, ...) __HOOK_SYSCALL_CALL_ORIGIN(nr, __VA_ARGS__) - -#define __REPLACE_SYSCALL_INSTALL(nr) \ - if (has_syscall_wrapper) { \ - replace_syscall_with(nr, (uintptr_t *)&__hook_sys_wrap_backup_##nr, (uintptr_t)__hook_sys_wrap_##nr); \ - } else { \ - replace_syscall_with(nr, (uintptr_t *)&__hook_sys_backup_##nr, (uintptr_t)__hook_sys_##nr); \ - } -#define REPLACE_SYSCALL_INSTALL(nr) __REPLACE_SYSCALL_INSTALL(nr) - -#define __INLINE_SYSCALL_INSTALL(nr) \ - if (has_syscall_wrapper) { \ - inline_syscall_with(nr, (uintptr_t *)&__hook_sys_wrap_backup_##nr, (uintptr_t)__hook_sys_wrap_##nr); \ - } else { \ - inline_syscall_with(nr, (uintptr_t *)&__hook_sys_backup_##nr, (uintptr_t)__hook_sys_##nr); \ - } -#define INLINE_SYSCALL_INSTALL(nr) __INLINE_SYSCALL_INSTALL(nr) - -#define _ARGS_TO_REGS(regs, idx, val, ...) \ - do { \ - regs.regs[idx] = val; \ - ARGS_TO_REGS(regs, idx + 1, __VA_ARGS__); \ - } while (0) - -#define ARGS_TO_REGS(regs, ...) _ARGS_TO_REGS(regs, 0, __VA_ARGS__) - -extern bool has_syscall_wrapper; -extern uintptr_t syscall_table_addr; -extern uintptr_t compat_syscall_table_addr; - -#endif \ No newline at end of file diff --git a/kernel/patch/old/lsmhook.c b/kernel/patch/old/lsmhook.c deleted file mode 100644 index 666916a7..00000000 --- a/kernel/patch/old/lsmhook.c +++ /dev/null @@ -1,2794 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define lsm_backup(func) hook_backup(func) -#define lsm_replace(func) hook_replace(func) -#define lsm_hook(func) hook_kfunc(func) -#define lsm_call_backup(func, ...) hook_call_backup(func, __VA_ARGS__) - -#define lsm_int_hook_before(type, ret) - -#define lsm_int_hook_after(type, ret) - -#define lsm_void_hook_before(type) - -#define lsm_void_hook_after(type) - -/* Security operations */ -int lsm_backup(security_binder_set_context_mgr)(const struct cred *mgr); -int lsm_backup(security_binder_transaction)(const struct cred *from, const struct cred *to); -int lsm_backup(security_binder_transfer_binder)(const struct cred *from, const struct cred *to); -int lsm_backup(security_binder_transfer_file)(const struct cred *from, const struct cred *to, struct file *file); -int lsm_backup(security_ptrace_access_check)(struct task_struct *child, unsigned int mode); -int lsm_backup(security_ptrace_traceme)(struct task_struct *parent); -int lsm_backup(security_capget)(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, - kernel_cap_t *permitted); -int lsm_backup(security_capset)(struct cred *new, const struct cred *old, const kernel_cap_t *effective, - const kernel_cap_t *inheritable, const kernel_cap_t *permitted); -int lsm_backup(security_capable)(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); -int lsm_backup(security_quotactl)(int cmds, int type, int id, struct super_block *sb); -int lsm_backup(security_quota_on)(struct dentry *dentry); -int lsm_backup(security_syslog)(int type); -int lsm_backup(security_settime64)(const struct timespec64 *ts, const struct timezone *tz); -int lsm_backup(security_vm_enough_memory_mm)(struct mm_struct *mm, long pages); -int lsm_backup(security_bprm_creds_for_exec)(struct linux_binprm *bprm); -int lsm_backup(security_bprm_creds_from_file)(struct linux_binprm *bprm, struct file *file); -int lsm_backup(security_bprm_check)(struct linux_binprm *bprm); -void lsm_backup(security_bprm_committing_creds)(struct linux_binprm *bprm); -void lsm_backup(security_bprm_committed_creds)(struct linux_binprm *bprm); -int lsm_backup(security_fs_context_dup)(struct fs_context *fc, struct fs_context *src_fc); -int lsm_backup(security_fs_context_parse_param)(struct fs_context *fc, struct fs_parameter *param); -int lsm_backup(security_sb_alloc)(struct super_block *sb); -void lsm_backup(security_sb_delete)(struct super_block *sb); -void lsm_backup(security_sb_free)(struct super_block *sb); -void lsm_backup(security_free_mnt_opts)(void **mnt_opts); -int lsm_backup(security_sb_eat_lsm_opts)(char *options, void **mnt_opts); -int lsm_backup(security_sb_remount)(struct super_block *sb, void *mnt_opts); -int lsm_backup(security_sb_kern_mount)(struct super_block *sb); -int lsm_backup(security_sb_show_options)(struct seq_file *m, struct super_block *sb); -int lsm_backup(security_sb_statfs)(struct dentry *dentry); -int lsm_backup(security_sb_mount)(const char *dev_name, const struct path *path, const char *type, unsigned long flags, - void *data); -int lsm_backup(security_sb_umount)(struct vfsmount *mnt, int flags); -int lsm_backup(security_sb_pivotroot)(const struct path *old_path, const struct path *new_path); -int lsm_backup(security_sb_set_mnt_opts)(struct super_block *sb, void *mnt_opts, unsigned long kern_flags, - unsigned long *set_kern_flags); -int lsm_backup(security_sb_clone_mnt_opts)(const struct super_block *oldsb, struct super_block *newsb, - unsigned long kern_flags, unsigned long *set_kern_flags); -int lsm_backup(security_add_mnt_opt)(const char *option, const char *val, int len, void **mnt_opts); -int lsm_backup(security_move_mount)(const struct path *from_path, const struct path *to_path); -int lsm_backup(security_dentry_init_security)(struct dentry *dentry, int mode, const struct qstr *name, void **ctx, - u32 *ctxlen); -int lsm_backup(security_dentry_create_files_as)(struct dentry *dentry, int mode, struct qstr *name, - const struct cred *old, struct cred *new); - -//CONFIG_SECURITY_PATH -int lsm_backup(security_path_unlink)(const struct path *dir, struct dentry *dentry); -int lsm_backup(security_path_mkdir)(const struct path *dir, struct dentry *dentry, umode_t mode); -int lsm_backup(security_path_rmdir)(const struct path *dir, struct dentry *dentry); -int lsm_backup(security_path_mknod)(const struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev); -int lsm_backup(security_path_truncate)(const struct path *path); -int lsm_backup(security_path_symlink)(const struct path *dir, struct dentry *dentry, const char *old_name); -int lsm_backup(security_path_link)(struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry); -int lsm_backup(security_path_rename)(const struct path *old_dir, struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry, unsigned int flags); -int lsm_backup(security_path_chmod)(const struct path *path, umode_t mode); -int lsm_backup(security_path_chown)(const struct path *path, kuid_t uid, kgid_t gid); -int lsm_backup(security_path_chroot)(const struct path *path); -/* CONFIG_SECURITY_PATH */ - -/* Needed for inode based security check */ -int lsm_backup(security_path_notify)(const struct path *path, u64 mask, unsigned int obj_type); -int lsm_backup(security_inode_alloc)(struct inode *inode); -void lsm_backup(security_inode_free)(struct inode *inode); -int lsm_backup(security_inode_init_security)(struct inode *inode, struct inode *dir, const struct qstr *qstr, - initxattrs initxattrs, void *fs_data); -int lsm_backup(security_old_inode_init_security)(struct inode *inode, struct inode *dir, const struct qstr *qstr, - const char **name, void **value, size_t *len); -int lsm_backup(security_inode_create)(struct inode *dir, struct dentry *dentry, umode_t mode); -int lsm_backup(security_inode_link)(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); -int lsm_backup(security_inode_unlink)(struct inode *dir, struct dentry *dentry); -int lsm_backup(security_inode_symlink)(struct inode *dir, struct dentry *dentry, const char *old_name); -int lsm_backup(security_inode_mkdir)(struct inode *dir, struct dentry *dentry, umode_t mode); -int lsm_backup(security_inode_rmdir)(struct inode *dir, struct dentry *dentry); -int lsm_backup(security_inode_mknod)(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev); -int lsm_backup(security_inode_rename)(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, - struct dentry *new_dentry, unsigned int flags); -int lsm_backup(security_inode_readlink)(struct dentry *dentry); -int lsm_backup(security_inode_follow_link)(struct dentry *dentry, struct inode *inode, bool rcu); -int lsm_backup(security_inode_permission)(struct inode *inode, int mask); -int lsm_backup(security_inode_setattr)(struct dentry *dentry, struct iattr *attr); -int lsm_backup(security_inode_getattr)(const struct path *path); -int lsm_backup(security_inode_setxattr)(struct dentry *dentry, const char *name, const void *value, size_t size, - int flags); -void lsm_backup(security_inode_post_setxattr)(struct dentry *dentry, const char *name, const void *value, size_t size, - int flags); -int lsm_backup(security_inode_getxattr)(struct dentry *dentry, const char *name); -int lsm_backup(security_inode_listxattr)(struct dentry *dentry); -int lsm_backup(security_inode_removexattr)(struct dentry *dentry, const char *name); -int lsm_backup(security_inode_set_acl)(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name, - struct posix_acl *kacl); -int lsm_backup(security_inode_get_acl)(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name); -int lsm_backup(security_inode_remove_acl)(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name); -int lsm_backup(security_inode_need_killpriv)(struct dentry *dentry); -int lsm_backup(security_inode_killpriv)(struct dentry *dentry); -int lsm_backup(security_inode_getsecurity)(struct inode *inode, const char *name, void **buffer, bool alloc); -int lsm_backup(security_inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, - int flags); -int lsm_backup(security_inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size); -void lsm_backup(security_inode_getsecid)(struct inode *inode, u32 *secid); -int lsm_backup(security_inode_copy_up)(struct dentry *src, struct cred **new); -int lsm_backup(security_inode_copy_up_xattr)(const char *name); -int lsm_backup(security_kernfs_init_security)(struct kernfs_node *kn_dir, struct kernfs_node *kn); -int lsm_backup(security_file_permission)(struct file *file, int mask); -int lsm_backup(security_file_alloc)(struct file *file); -void lsm_backup(security_file_free)(struct file *file); -int lsm_backup(security_file_ioctl)(struct file *file, unsigned int cmd, unsigned long arg); -int lsm_backup(security_mmap_addr)(unsigned long addr); -int lsm_backup(security_mmap_file)(struct file *file, unsigned long prot, unsigned long flags); -int lsm_backup(security_file_mprotect)(struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot); -int lsm_backup(security_file_lock)(struct file *file, unsigned int cmd); -int lsm_backup(security_file_fcntl)(struct file *file, unsigned int cmd, unsigned long arg); -void lsm_backup(security_file_set_fowner)(struct file *file); -int lsm_backup(security_file_send_sigiotask)(struct task_struct *tsk, struct fown_struct *fown, int sig); -int lsm_backup(security_file_receive)(struct file *file); -// int lsm_backup(security_file_open)(struct file *file); -int lsm_backup(security_file_open)(struct file *file, const struct cred *cred); -int lsm_backup(security_file_truncate)(struct file *file); -int lsm_backup(security_task_alloc)(struct task_struct *task, unsigned long clone_flags); -void lsm_backup(security_task_free)(struct task_struct *task); -int lsm_backup(security_cred_alloc_blank)(struct cred *cred, gfp_t gfp); -void lsm_backup(security_cred_free)(struct cred *cred); -int lsm_backup(security_prepare_creds)(struct cred *new, const struct cred *old, gfp_t gfp); -void lsm_backup(security_transfer_creds)(struct cred *new, const struct cred *old); -void lsm_backup(security_cred_getsecid)(const struct cred *c, u32 *secid); -int lsm_backup(security_kernel_act_as)(struct cred *new, u32 secid); -int lsm_backup(security_kernel_create_files_as)(struct cred *new, struct inode *inode); -int lsm_backup(security_kernel_module_request)(char *kmod_name); -int lsm_backup(security_kernel_load_data)(enum kernel_load_data_id id, bool contents); -int lsm_backup(security_kernel_post_load_data)(char *buf, loff_t size, enum kernel_load_data_id id, char *description); -int lsm_backup(security_kernel_read_file)(struct file *file, enum kernel_read_file_id id, bool contents); -int lsm_backup(security_kernel_post_read_file)(struct file *file, char *buf, loff_t size, enum kernel_read_file_id id); -int lsm_backup(security_task_fix_setuid)(struct cred *new, const struct cred *old, int flags); -int lsm_backup(security_task_fix_setgid)(struct cred *new, const struct cred *old, int flags); -int lsm_backup(security_task_fix_setgroups)(struct cred *new, const struct cred *old); -int lsm_backup(security_task_setpgid)(struct task_struct *p, pid_t pgid); -int lsm_backup(security_task_getpgid)(struct task_struct *p); -int lsm_backup(security_task_getsid)(struct task_struct *p); -void lsm_backup(security_current_getsecid_subj)(u32 *secid); -void lsm_backup(security_task_getsecid_obj)(struct task_struct *p, u32 *secid); // ?-6.3 -void lsm_backup(security_task_getsecid)(struct task_struct *p, u32 *secid); // 4.4-? -int lsm_backup(security_task_setnice)(struct task_struct *p, int nice); -int lsm_backup(security_task_setioprio)(struct task_struct *p, int ioprio); -int lsm_backup(security_task_getioprio)(struct task_struct *p); -int lsm_backup(security_task_prlimit)(const struct cred *cred, const struct cred *tcred, unsigned int flags); -int lsm_backup(security_task_setrlimit)(struct task_struct *p, unsigned int resource, struct rlimit *new_rlim); -int lsm_backup(security_task_setscheduler)(struct task_struct *p); -int lsm_backup(security_task_getscheduler)(struct task_struct *p); -int lsm_backup(security_task_movememory)(struct task_struct *p); -int lsm_backup(security_task_kill)(struct task_struct *p, struct kernel_siginfo *info, int sig, - const struct cred *cred); -int lsm_backup(security_task_prctl)(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, - unsigned long arg5); -void lsm_backup(security_task_to_inode)(struct task_struct *p, struct inode *inode); -int lsm_backup(security_create_user_ns)(const struct cred *cred); -int lsm_backup(security_ipc_permission)(struct kern_ipc_perm *ipcp, short flag); -void lsm_backup(security_ipc_getsecid)(struct kern_ipc_perm *ipcp, u32 *secid); -int lsm_backup(security_msg_msg_alloc)(struct msg_msg *msg); -void lsm_backup(security_msg_msg_free)(struct msg_msg *msg); -int lsm_backup(security_msg_queue_alloc)(struct kern_ipc_perm *msq); -void lsm_backup(security_msg_queue_free)(struct kern_ipc_perm *msq); -int lsm_backup(security_msg_queue_associate)(struct kern_ipc_perm *msq, int msqflg); -int lsm_backup(security_msg_queue_msgctl)(struct kern_ipc_perm *msq, int cmd); -int lsm_backup(security_msg_queue_msgsnd)(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg); -int lsm_backup(security_msg_queue_msgrcv)(struct kern_ipc_perm *msq, struct msg_msg *msg, struct task_struct *target, - long type, int mode); -int lsm_backup(security_shm_alloc)(struct kern_ipc_perm *shp); -void lsm_backup(security_shm_free)(struct kern_ipc_perm *shp); -int lsm_backup(security_shm_associate)(struct kern_ipc_perm *shp, int shmflg); -int lsm_backup(security_shm_shmctl)(struct kern_ipc_perm *shp, int cmd); -int lsm_backup(security_shm_shmat)(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg); -int lsm_backup(security_sem_alloc)(struct kern_ipc_perm *sma); -void lsm_backup(security_sem_free)(struct kern_ipc_perm *sma); -int lsm_backup(security_sem_associate)(struct kern_ipc_perm *sma, int semflg); -int lsm_backup(security_sem_semctl)(struct kern_ipc_perm *sma, int cmd); -int lsm_backup(security_sem_semop)(struct kern_ipc_perm *sma, struct sembuf *sops, unsigned nsops, int alter); -void lsm_backup(security_d_instantiate)(struct dentry *dentry, struct inode *inode); -int lsm_backup(security_getprocattr)(struct task_struct *p, const char *lsm, char *name, char **value); -int lsm_backup(security_setprocattr)(const char *lsm, const char *name, void *value, size_t size); -int lsm_backup(security_netlink_send)(struct sock *sk, struct sk_buff *skb); -int lsm_backup(security_ismaclabel)(const char *name); -int lsm_backup(security_secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); -int lsm_backup(security_secctx_to_secid)(const char *secdata, u32 seclen, u32 *secid); -void lsm_backup(security_release_secctx)(char *secdata, u32 seclen); -void lsm_backup(security_inode_invalidate_secctx)(struct inode *inode); -int lsm_backup(security_inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen); -int lsm_backup(security_inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen); -int lsm_backup(security_inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen); - -// CONFIG_WATCH_QUEUE -int lsm_backup(security_post_notification)(const struct cred *w_cred, const struct cred *cred, - struct watch_notification *n); - -// CONFIG_KEY_NOTIFICATIONS -int lsm_backup(security_watch_key)(struct key *key); - -// CONFIG_SECURITY_NETWORK -int lsm_backup(security_unix_stream_connect)(struct sock *sock, struct sock *other, struct sock *newsk); -int lsm_backup(security_unix_may_send)(struct socket *sock, struct socket *other); -int lsm_backup(security_socket_create)(int family, int type, int protocol, int kern); -int lsm_backup(security_socket_post_create)(struct socket *sock, int family, int type, int protocol, int kern); -int lsm_backup(security_socket_socketpair)(struct socket *socka, struct socket *sockb); -int lsm_backup(security_socket_bind)(struct socket *sock, struct sockaddr *address, int addrlen); -int lsm_backup(security_socket_connect)(struct socket *sock, struct sockaddr *address, int addrlen); -int lsm_backup(security_socket_listen)(struct socket *sock, int backlog); -int lsm_backup(security_socket_accept)(struct socket *sock, struct socket *newsock); -int lsm_backup(security_socket_sendmsg)(struct socket *sock, struct msghdr *msg, int size); -int lsm_backup(security_socket_recvmsg)(struct socket *sock, struct msghdr *msg, int size, int flags); -int lsm_backup(security_socket_getsockname)(struct socket *sock); -int lsm_backup(security_socket_getpeername)(struct socket *sock); -int lsm_backup(security_socket_getsockopt)(struct socket *sock, int level, int optname); -int lsm_backup(security_socket_setsockopt)(struct socket *sock, int level, int optname); -int lsm_backup(security_socket_shutdown)(struct socket *sock, int how); -int lsm_backup(security_sock_rcv_skb)(struct sock *sk, struct sk_buff *skb); -int lsm_backup(security_socket_getpeersec_stream)(struct socket *sock, sockptr_t optval, sockptr_t optlen, - unsigned int len); -int lsm_backup(security_socket_getpeersec_dgram)(struct socket *sock, struct sk_buff *skb, u32 *secid); -int lsm_backup(security_sk_alloc)(struct sock *sk, int family, gfp_t priority); -void lsm_backup(security_sk_free)(struct sock *sk); -void lsm_backup(security_sk_clone)(const struct sock *sk, struct sock *newsk); -void lsm_backup(security_sk_classify_flow)(struct sock *sk, struct flowi_common *flic); -void lsm_backup(security_req_classify_flow)(const struct request_sock *req, struct flowi_common *flic); -void lsm_backup(security_sock_graft)(struct sock *sk, struct socket *parent); -int lsm_backup(security_inet_conn_request)(const struct sock *sk, struct sk_buff *skb, struct request_sock *req); -void lsm_backup(security_inet_csk_clone)(struct sock *newsk, const struct request_sock *req); -void lsm_backup(security_inet_conn_established)(struct sock *sk, struct sk_buff *skb); -int lsm_backup(security_secmark_relabel_packet)(u32 secid); -void lsm_backup(security_secmark_refcount_inc)(void); -void lsm_backup(security_secmark_refcount_dec)(void); -int lsm_backup(security_tun_dev_alloc_security)(void **security); -void lsm_backup(security_tun_dev_free_security)(void *security); -int lsm_backup(security_tun_dev_create)(void); -int lsm_backup(security_tun_dev_attach_queue)(void *security); -int lsm_backup(security_tun_dev_attach)(struct sock *sk, void *security); -int lsm_backup(security_tun_dev_open)(void *security); -int lsm_backup(security_sctp_assoc_request)(struct sctp_association *asoc, struct sk_buff *skb); -int lsm_backup(security_sctp_bind_connect)(struct sock *sk, int optname, struct sockaddr *address, int addrlen); -void lsm_backup(security_sctp_sk_clone)(struct sctp_association *asoc, struct sock *sk, struct sock *newsk); -int lsm_backup(security_sctp_assoc_established)(struct sctp_association *asoc, struct sk_buff *skb); - -// CONFIG_SECURITY_INFINIBAND -int lsm_backup(security_ib_pkey_access)(void *sec, u64 subnet_prefix, u16 pkey); -int lsm_backup(security_ib_endport_manage_subnet)(void *sec, const char *dev_name, u8 port_num); -int lsm_backup(security_ib_alloc_security)(void **sec); -void lsm_backup(security_ib_free_security)(void *sec); - -// CONFIG_SECURITY_NETWORK_XFRM -int lsm_backup(security_xfrm_policy_alloc)(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx, gfp_t gfp); -int lsm_backup(security_xfrm_policy_clone)(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp); -void lsm_backup(security_xfrm_policy_free)(struct xfrm_sec_ctx *ctx); -int lsm_backup(security_xfrm_policy_delete)(struct xfrm_sec_ctx *ctx); -int lsm_backup(security_xfrm_state_alloc)(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); -int lsm_backup(security_xfrm_state_alloc_acquire)(struct xfrm_state *x, struct xfrm_sec_ctx *polsec, u32 secid); -int lsm_backup(security_xfrm_state_delete)(struct xfrm_state *x); -void lsm_backup(security_xfrm_state_free)(struct xfrm_state *x); -int lsm_backup(security_xfrm_policy_lookup)(struct xfrm_sec_ctx *ctx, u32 fl_secid); -int lsm_backup(security_xfrm_state_pol_flow_match)(struct xfrm_state *x, struct xfrm_policy *xp, - const struct flowi_common *flic); -int lsm_backup(security_xfrm_decode_session)(struct sk_buff *skb, u32 *secid); -void lsm_backup(security_skb_classify_flow)(struct sk_buff *skb, struct flowi_common *flic); - -/* key management security hooks */ -// CONFIG_KEYS -typedef void *key_ref_t; -int lsm_backup(security_key_alloc)(struct key *key, const struct cred *cred, unsigned long flags); -void lsm_backup(security_key_free)(struct key *key); -int lsm_backup(security_key_permission)(key_ref_t key_ref, const struct cred *cred, enum key_need_perm need_perm); -int lsm_backup(security_key_getsecurity)(struct key *key, char **_buffer); - -// CONFIG_AUDIT -int lsm_backup(security_audit_rule_init)(u32 field, u32 op, char *rulestr, void **lsmrule); -int lsm_backup(security_audit_rule_known)(struct audit_krule *krule); -void lsm_backup(security_audit_rule_free)(void *lsmrule); -int lsm_backup(security_audit_rule_match)(u32 secid, u32 field, u32 op, void *lsmrule); - -// CONFIG_BPF_SYSCALL -int lsm_backup(security_bpf)(int cmd, union bpf_attr *attr, unsigned int size); -int lsm_backup(security_bpf_map)(struct bpf_map *map, fmode_t fmode); -int lsm_backup(security_bpf_prog)(struct bpf_prog *prog); -int lsm_backup(security_bpf_map_alloc)(struct bpf_map *map); -int lsm_backup(security_bpf_prog_alloc)(struct bpf_prog_aux *aux); -void lsm_backup(security_bpf_map_free)(struct bpf_map *map); -void lsm_backup(security_bpf_prog_free)(struct bpf_prog_aux *aux); -// CONFIG_BPF_SYSCALL - -int lsm_backup(security_locked_down)(enum lockdown_reason what); - -// CONFIG_PERF_EVENTS -int lsm_backup(security_perf_event_open)(struct perf_event_attr *attr, int type); -int lsm_backup(security_perf_event_alloc)(struct perf_event *event); -void lsm_backup(security_perf_event_free)(struct perf_event *event); -int lsm_backup(security_perf_event_read)(struct perf_event *event); -int lsm_backup(security_perf_event_write)(struct perf_event *event); - -// CONFIG_IO_URING -int lsm_backup(security_uring_override_creds)(const struct cred *new); -int lsm_backup(security_uring_sqpoll)(void); -int lsm_backup(security_uring_cmd)(struct io_uring_cmd *ioucmd); - -// @see document: include/linux/lsm_hooks.h - -/* Security operations */ - -int lsm_replace(security_binder_set_context_mgr)(const struct cred *mgr) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_binder_set_context_mgr, ret); - ret = lsm_call_backup(security_binder_set_context_mgr, mgr); - lsm_int_hook_after(LSM_TYPE_security_binder_set_context_mgr, ret); - return ret; -} - -int lsm_replace(security_binder_transaction)(const struct cred *from, const struct cred *to) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_binder_transaction, ret); - ret = lsm_call_backup(security_binder_transaction, from, to); - lsm_int_hook_after(LSM_TYPE_security_binder_transaction, ret); - return ret; -} - -int lsm_replace(security_binder_transfer_binder)(const struct cred *from, const struct cred *to) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_binder_transfer_binder, ret); - ret = lsm_call_backup(security_binder_transfer_binder, from, to); - lsm_int_hook_after(LSM_TYPE_security_binder_transfer_binder, ret); - return ret; -} - -int lsm_replace(security_binder_transfer_file)(const struct cred *from, const struct cred *to, struct file *file) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_binder_transfer_file, ret); - ret = lsm_call_backup(security_binder_transfer_file, from, to, file); - lsm_int_hook_after(LSM_TYPE_security_binder_transfer_file, ret); - return ret; -} - -int lsm_replace(security_ptrace_access_check)(struct task_struct *child, unsigned int mode) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_ptrace_access_check, ret); - ret = lsm_call_backup(security_ptrace_access_check, child, mode); - lsm_int_hook_after(LSM_TYPE_security_ptrace_access_check, ret); - return ret; -} - -int lsm_replace(security_ptrace_traceme)(struct task_struct *parent) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_ptrace_traceme, ret); - ret = lsm_call_backup(security_ptrace_traceme, parent); - lsm_int_hook_after(LSM_TYPE_security_ptrace_traceme, ret); - return ret; -} - -int lsm_replace(security_capget)(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, - kernel_cap_t *permitted) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_capget, ret); - ret = lsm_call_backup(security_capget, target, effective, inheritable, permitted); - lsm_int_hook_after(LSM_TYPE_security_capget, ret); - return ret; -} - -int lsm_replace(security_capset)(struct cred *new, const struct cred *old, const kernel_cap_t *effective, - const kernel_cap_t *inheritable, const kernel_cap_t *permitted) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_capset, ret); - ret = lsm_call_backup(security_capset, new, old, effective, inheritable, permitted); - lsm_int_hook_after(LSM_TYPE_security_capset, ret); - return ret; -} - -int lsm_replace(security_capable)(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_capable, ret); - ret = lsm_call_backup(security_capable, cred, ns, cap, opts); - lsm_int_hook_after(LSM_TYPE_security_capable, ret); - return ret; -} - -int lsm_replace(security_quotactl)(int cmds, int type, int id, struct super_block *sb) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_quotactl, ret); - ret = lsm_call_backup(security_quotactl, cmds, type, id, sb); - lsm_int_hook_after(LSM_TYPE_security_quotactl, ret); - return ret; -} - -int lsm_replace(security_quota_on)(struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_quota_on, ret); - ret = lsm_call_backup(security_quota_on, dentry); - lsm_int_hook_after(LSM_TYPE_security_quota_on, ret); - return ret; -} - -int lsm_replace(security_syslog)(int type) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_syslog, ret); - ret = lsm_call_backup(security_syslog, type); - lsm_int_hook_after(LSM_TYPE_security_syslog, ret); - return ret; -} - -int lsm_replace(security_settime64)(const struct timespec64 *ts, const struct timezone *tz) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_settime64, ret); - ret = lsm_call_backup(security_settime64, ts, tz); - lsm_int_hook_after(LSM_TYPE_security_settime64, ret); - return ret; -} - -int lsm_replace(security_vm_enough_memory_mm)(struct mm_struct *mm, long pages) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_vm_enough_memory_mm, ret); - ret = lsm_call_backup(security_vm_enough_memory_mm, mm, pages); - lsm_int_hook_after(LSM_TYPE_security_vm_enough_memory_mm, ret); - - return ret; -} - -// Security hooks for program execution operations. - -/** - * Security hooks for program execution operations. - * - * @bprm_creds_for_exec: - * If the setup in prepare_exec_creds did not setup @bprm->cred->security - * properly for executing @bprm->file, update the LSM's portion of - * @bprm->cred->security to be what commit_creds needs to install for the - * new program. This hook may also optionally check permissions - * (e.g. for transitions between security domains). - * The hook must set @bprm->secureexec to 1 if AT_SECURE should be set to - * request libc enable secure mode. - * @bprm contains the linux_binprm structure. - * Return 0 if the hook is successful and permission is granted. - */ -int lsm_replace(security_bprm_creds_for_exec)(struct linux_binprm *bprm) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_bprm_creds_for_exec, ret); - ret = lsm_call_backup(security_bprm_creds_for_exec, bprm); - lsm_int_hook_after(LSM_TYPE_security_bprm_creds_for_exec, ret); - return ret; -} - -int lsm_replace(security_bprm_creds_from_file)(struct linux_binprm *bprm, struct file *file) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_bprm_creds_from_file, ret); - ret = lsm_call_backup(security_bprm_creds_from_file, bprm, file); - lsm_int_hook_after(LSM_TYPE_security_bprm_creds_from_file, ret); - return ret; -} - -int lsm_replace(security_bprm_check)(struct linux_binprm *bprm) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_bprm_check, ret); - ret = lsm_call_backup(security_bprm_check, bprm); - lsm_int_hook_after(LSM_TYPE_security_bprm_check, ret); - return ret; -} - -void lsm_replace(security_bprm_committing_creds)(struct linux_binprm *bprm) -{ - lsm_void_hook_before(LSM_TYPE_security_bprm_committing_creds); - lsm_call_backup(security_bprm_committing_creds, bprm); - lsm_void_hook_after(LSM_TYPE_security_bprm_committing_creds); -} - -void lsm_replace(security_bprm_committed_creds)(struct linux_binprm *bprm) -{ - lsm_void_hook_before(LSM_TYPE_security_bprm_committed_creds); - lsm_call_backup(security_bprm_committed_creds, bprm); - lsm_void_hook_after(LSM_TYPE_security_bprm_committed_creds); -} - -int lsm_replace(security_fs_context_dup)(struct fs_context *fc, struct fs_context *src_fc) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_fs_context_dup, ret); - ret = lsm_call_backup(security_fs_context_dup, fc, src_fc); - lsm_int_hook_after(LSM_TYPE_security_fs_context_dup, ret); - return ret; -} - -int lsm_replace(security_fs_context_parse_param)(struct fs_context *fc, struct fs_parameter *param) -{ - // int defrc = -ENOPARAM; - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_fs_context_parse_param, ret); - ret = lsm_call_backup(security_fs_context_parse_param, fc, param); - lsm_int_hook_after(LSM_TYPE_security_fs_context_parse_param, ret); - return ret; -} -int lsm_replace(security_sb_alloc)(struct super_block *sb) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_alloc, ret); - ret = lsm_call_backup(security_sb_alloc, sb); - lsm_int_hook_after(LSM_TYPE_security_sb_alloc, ret); - return ret; -} - -void lsm_replace(security_sb_delete)(struct super_block *sb) -{ - lsm_void_hook_before(LSM_TYPE_security_sb_delete); - lsm_call_backup(security_sb_delete, sb); - lsm_void_hook_after(LSM_TYPE_security_sb_delete); -} - -void lsm_replace(security_sb_free)(struct super_block *sb) -{ - lsm_void_hook_before(LSM_TYPE_security_sb_free); - lsm_call_backup(security_sb_free, sb); - lsm_void_hook_after(LSM_TYPE_security_sb_free); -} - -void lsm_replace(security_free_mnt_opts)(void **mnt_opts) -{ - lsm_void_hook_before(LSM_TYPE_security_free_mnt_opts); - lsm_call_backup(security_free_mnt_opts, mnt_opts); - lsm_void_hook_after(LSM_TYPE_security_free_mnt_opts); -} - -int lsm_replace(security_sb_eat_lsm_opts)(char *options, void **mnt_opts) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_eat_lsm_opts, ret); - ret = lsm_call_backup(security_sb_eat_lsm_opts, options, mnt_opts); - lsm_int_hook_after(LSM_TYPE_security_sb_eat_lsm_opts, ret); - return ret; -} - -int lsm_replace(security_sb_remount)(struct super_block *sb, void *mnt_opts) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_remount, ret); - ret = lsm_call_backup(security_sb_remount, sb, mnt_opts); - lsm_int_hook_after(LSM_TYPE_security_sb_remount, ret); - return ret; -} - -int lsm_replace(security_sb_kern_mount)(struct super_block *sb) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_kern_mount, ret); - ret = lsm_call_backup(security_sb_kern_mount, sb); - lsm_int_hook_after(LSM_TYPE_security_sb_kern_mount, ret); - return ret; -} - -int lsm_replace(security_sb_show_options)(struct seq_file *m, struct super_block *sb) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_show_options, ret); - ret = lsm_call_backup(security_sb_show_options, m, sb); - lsm_int_hook_after(LSM_TYPE_security_sb_show_options, ret); - return ret; -} - -int lsm_replace(security_sb_statfs)(struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_statfs, ret); - ret = lsm_call_backup(security_sb_statfs, dentry); - lsm_int_hook_after(LSM_TYPE_security_sb_statfs, ret); - return ret; -} - -int lsm_replace(security_sb_mount)(const char *dev_name, const struct path *path, const char *type, unsigned long flags, - void *data) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_mount, ret); - ret = lsm_call_backup(security_sb_mount, dev_name, path, type, flags, data); - lsm_int_hook_after(LSM_TYPE_security_sb_mount, ret); - return ret; -} - -int lsm_replace(security_sb_umount)(struct vfsmount *mnt, int flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_umount, ret); - ret = lsm_call_backup(security_sb_umount, mnt, flags); - lsm_int_hook_after(LSM_TYPE_security_sb_umount, ret); - return ret; -} -int lsm_replace(security_sb_pivotroot)(const struct path *old_path, const struct path *new_path) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_pivotroot, ret); - ret = lsm_call_backup(security_sb_pivotroot, old_path, new_path); - lsm_int_hook_after(LSM_TYPE_security_sb_pivotroot, ret); - return ret; -} - -int lsm_replace(security_sb_set_mnt_opts)(struct super_block *sb, void *mnt_opts, unsigned long kern_flags, - unsigned long *set_kern_flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_set_mnt_opts, ret); - ret = lsm_call_backup(security_sb_set_mnt_opts, sb, mnt_opts, kern_flags, set_kern_flags); - lsm_int_hook_after(LSM_TYPE_security_sb_set_mnt_opts, ret); - return ret; -} - -int lsm_replace(security_sb_clone_mnt_opts)(const struct super_block *oldsb, struct super_block *newsb, - unsigned long kern_flags, unsigned long *set_kern_flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sb_clone_mnt_opts, ret); - ret = lsm_call_backup(security_sb_clone_mnt_opts, oldsb, newsb, kern_flags, set_kern_flags); - lsm_int_hook_after(LSM_TYPE_security_sb_clone_mnt_opts, ret); - return ret; -} - -int lsm_replace(security_add_mnt_opt)(const char *option, const char *val, int len, void **mnt_opts) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_add_mnt_opt, ret); - ret = lsm_call_backup(security_add_mnt_opt, option, val, len, mnt_opts); - lsm_int_hook_after(LSM_TYPE_security_add_mnt_opt, ret); - return ret; -} - -int lsm_replace(security_move_mount)(const struct path *from_path, const struct path *to_path) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_move_mount, ret); - ret = lsm_call_backup(security_move_mount, from_path, to_path); - lsm_int_hook_after(LSM_TYPE_security_move_mount, ret); - return ret; -} - -int lsm_replace(security_dentry_init_security)(struct dentry *dentry, int mode, const struct qstr *name, void **ctx, - u32 *ctxlen) -{ - // int defrc = -EOPNOTSUPP; - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_dentry_init_security, ret); - ret = lsm_call_backup(security_dentry_init_security, dentry, mode, name, ctx, ctxlen); - lsm_int_hook_after(LSM_TYPE_security_dentry_init_security, ret); - return ret; -} - -int lsm_replace(security_dentry_create_files_as)(struct dentry *dentry, int mode, struct qstr *name, - const struct cred *old, struct cred *new) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_dentry_create_files_as, ret); - ret = lsm_call_backup(security_dentry_create_files_as, dentry, mode, name, old, new); - lsm_int_hook_after(LSM_TYPE_security_dentry_create_files_as, ret); - return ret; -} - -//CONFIG_SECURITY_PATH -int lsm_replace(security_path_unlink)(const struct path *dir, struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_unlink, ret); - ret = lsm_call_backup(security_path_unlink, dir, dentry); - lsm_int_hook_after(LSM_TYPE_security_path_unlink, ret); - return ret; -} - -int lsm_replace(security_path_mkdir)(const struct path *dir, struct dentry *dentry, umode_t mode) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_mkdir, ret); - ret = lsm_call_backup(security_path_mkdir, dir, dentry, mode); - lsm_int_hook_after(LSM_TYPE_security_path_mkdir, ret); - return ret; -} -int lsm_replace(security_path_rmdir)(const struct path *dir, struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_rmdir, ret); - ret = lsm_call_backup(security_path_rmdir, dir, dentry); - lsm_int_hook_after(LSM_TYPE_security_path_rmdir, ret); - - return ret; -} -int lsm_replace(security_path_mknod)(const struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_mknod, ret); - ret = lsm_call_backup(security_path_mknod, dir, dentry, mode, dev); - lsm_int_hook_after(LSM_TYPE_security_path_mknod, ret); - - return ret; -} -int lsm_replace(security_path_truncate)(const struct path *path) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_truncate, ret); - ret = lsm_call_backup(security_path_truncate, path); - lsm_int_hook_after(LSM_TYPE_security_path_truncate, ret); - - return ret; -} -int lsm_replace(security_path_symlink)(const struct path *dir, struct dentry *dentry, const char *old_name) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_symlink, ret); - ret = lsm_call_backup(security_path_symlink, dir, dentry, old_name); - lsm_int_hook_after(LSM_TYPE_security_path_symlink, ret); - - return ret; -} -int lsm_replace(security_path_link)(struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_link, ret); - ret = lsm_call_backup(security_path_link, old_dentry, new_dir, new_dentry); - lsm_int_hook_after(LSM_TYPE_security_path_link, ret); - - return ret; -} -int lsm_replace(security_path_rename)(const struct path *old_dir, struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry, unsigned int flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_rename, ret); - ret = lsm_call_backup(security_path_rename, old_dir, old_dentry, new_dir, new_dentry, flags); - lsm_int_hook_after(LSM_TYPE_security_path_rename, ret); - - return ret; -} -int lsm_replace(security_path_chmod)(const struct path *path, umode_t mode) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_chmod, ret); - ret = lsm_call_backup(security_path_chmod, path, mode); - lsm_int_hook_after(LSM_TYPE_security_path_chmod, ret); - return ret; -} -int lsm_replace(security_path_chown)(const struct path *path, kuid_t uid, kgid_t gid) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_chown, ret); - ret = lsm_call_backup(security_path_chown, path, uid, gid); - lsm_int_hook_after(LSM_TYPE_security_path_chown, ret); - return ret; -} -int lsm_replace(security_path_chroot)(const struct path *path) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_chroot, ret); - ret = lsm_call_backup(security_path_chroot, path); - lsm_int_hook_after(LSM_TYPE_security_path_chroot, ret); - return ret; -} -/* CONFIG_SECURITY_PATH */ - -// Security hooks for inode operations. - -int lsm_replace(security_path_notify)(const struct path *path, u64 mask, unsigned int obj_type) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_path_notify, ret); - ret = lsm_call_backup(security_path_notify, path, mask, obj_type); - lsm_int_hook_after(LSM_TYPE_security_path_notify, ret); - return ret; -} - -int lsm_replace(security_inode_alloc)(struct inode *inode) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_alloc, ret); - ret = lsm_call_backup(security_inode_alloc, inode); - lsm_int_hook_after(LSM_TYPE_security_inode_alloc, ret); - return ret; -} - -void lsm_replace(security_inode_free)(struct inode *inode) -{ - lsm_void_hook_before(LSM_TYPE_security_inode_free); - lsm_call_backup(security_inode_free, inode); - lsm_void_hook_after(LSM_TYPE_security_inode_free); -} - -int lsm_replace(security_inode_init_security)(struct inode *inode, struct inode *dir, const struct qstr *qstr, - initxattrs initxattrs, void *fs_data) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_init_security, ret); - ret = lsm_call_backup(security_inode_init_security, inode, dir, qstr, initxattrs, fs_data); - lsm_int_hook_after(LSM_TYPE_security_inode_init_security, ret); - return ret; -} - -int lsm_replace(security_old_inode_init_security)(struct inode *inode, struct inode *dir, const struct qstr *qstr, - const char **name, void **value, size_t *len) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_old_inode_init_security, ret); - ret = lsm_call_backup(security_old_inode_init_security, inode, dir, qstr, name, value, len); - lsm_int_hook_after(LSM_TYPE_security_old_inode_init_security, ret); - return ret; -} - -int lsm_replace(security_inode_create)(struct inode *dir, struct dentry *dentry, umode_t mode) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_create, ret); - ret = lsm_call_backup(security_inode_create, dir, dentry, mode); - lsm_int_hook_after(LSM_TYPE_security_inode_create, ret); - return ret; -} - -int lsm_replace(security_inode_link)(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_link, ret); - ret = lsm_call_backup(security_inode_link, old_dentry, dir, new_dentry); - lsm_int_hook_after(LSM_TYPE_security_inode_link, ret); - return ret; -} - -int lsm_replace(security_inode_unlink)(struct inode *dir, struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_unlink, ret); - ret = lsm_call_backup(security_inode_unlink, dir, dentry); - lsm_int_hook_after(LSM_TYPE_security_inode_unlink, ret); - return ret; -} - -int lsm_replace(security_inode_symlink)(struct inode *dir, struct dentry *dentry, const char *old_name) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_symlink, ret); - ret = lsm_call_backup(security_inode_symlink, dir, dentry, old_name); - lsm_int_hook_after(LSM_TYPE_security_inode_symlink, ret); - return ret; -} - -int lsm_replace(security_inode_mkdir)(struct inode *dir, struct dentry *dentry, umode_t mode) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_mkdir, ret); - ret = lsm_call_backup(security_inode_mkdir, dir, dentry, mode); - lsm_int_hook_after(LSM_TYPE_security_inode_mkdir, ret); - return ret; -} - -int lsm_replace(security_inode_rmdir)(struct inode *dir, struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_rmdir, ret); - ret = lsm_call_backup(security_inode_rmdir, dir, dentry); - lsm_int_hook_after(LSM_TYPE_security_inode_rmdir, ret); - return ret; -} - -int lsm_replace(security_inode_mknod)(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_mknod, ret); - ret = lsm_call_backup(security_inode_mknod, dir, dentry, mode, dev); - lsm_int_hook_after(LSM_TYPE_security_inode_mknod, ret); - return ret; -} - -int lsm_replace(security_inode_rename)(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, - struct dentry *new_dentry, unsigned int flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_rename, ret); - ret = lsm_call_backup(security_inode_rename, old_dir, old_dentry, new_dir, new_dentry, flags); - lsm_int_hook_after(LSM_TYPE_security_inode_rename, ret); - return ret; -} - -int lsm_replace(security_inode_readlink)(struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_readlink, ret); - ret = lsm_call_backup(security_inode_readlink, dentry); - lsm_int_hook_after(LSM_TYPE_security_inode_readlink, ret); - return ret; -} - -int lsm_replace(security_inode_follow_link)(struct dentry *dentry, struct inode *inode, bool rcu) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_follow_link, ret); - ret = lsm_call_backup(security_inode_follow_link, dentry, inode, rcu); - lsm_int_hook_after(LSM_TYPE_security_inode_follow_link, ret); - return ret; -} - -int lsm_replace(security_inode_permission)(struct inode *inode, int mask) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_permission, ret); - ret = lsm_call_backup(security_inode_permission, inode, mask); - lsm_int_hook_after(LSM_TYPE_security_inode_permission, ret); - return ret; -} - -int lsm_replace(security_inode_setattr)(struct dentry *dentry, struct iattr *attr) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_setattr, ret); - ret = lsm_call_backup(security_inode_setattr, dentry, attr); - lsm_int_hook_after(LSM_TYPE_security_inode_setattr, ret); - return ret; -} - -int lsm_replace(security_inode_getattr)(const struct path *path) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_getattr, ret); - ret = lsm_call_backup(security_inode_getattr, path); - lsm_int_hook_after(LSM_TYPE_security_inode_getattr, ret); - return ret; -} -int lsm_replace(security_inode_setxattr)(struct dentry *dentry, const char *name, const void *value, size_t size, - int flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_setxattr, ret); - ret = lsm_call_backup(security_inode_setxattr, dentry, name, value, size, flags); - lsm_int_hook_after(LSM_TYPE_security_inode_setxattr, ret); - return ret; -} - -void lsm_replace(security_inode_post_setxattr)(struct dentry *dentry, const char *name, const void *value, size_t size, - int flags) -{ - lsm_void_hook_before(LSM_TYPE_security_inode_post_setxattr); - lsm_call_backup(security_inode_post_setxattr, dentry, name, value, size, flags); - lsm_void_hook_after(LSM_TYPE_security_inode_post_setxattr); -} - -int lsm_replace(security_inode_getxattr)(struct dentry *dentry, const char *name) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_getxattr, ret); - ret = lsm_call_backup(security_inode_getxattr, dentry, name); - lsm_int_hook_after(LSM_TYPE_security_inode_getxattr, ret); - return ret; -} - -int lsm_replace(security_inode_listxattr)(struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_listxattr, ret); - ret = lsm_call_backup(security_inode_listxattr, dentry); - lsm_int_hook_after(LSM_TYPE_security_inode_listxattr, ret); - return ret; -} - -int lsm_replace(security_inode_removexattr)(struct dentry *dentry, const char *name) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_removexattr, ret); - ret = lsm_call_backup(security_inode_removexattr, dentry, name); - lsm_int_hook_after(LSM_TYPE_security_inode_removexattr, ret); - return ret; -} - -int lsm_replace(security_inode_set_acl)(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name, - struct posix_acl *kacl) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_set_acl, ret); - ret = lsm_call_backup(security_inode_set_acl, idmap, dentry, acl_name, kacl); - lsm_int_hook_after(LSM_TYPE_security_inode_set_acl, ret); - return ret; -} - -int lsm_replace(security_inode_get_acl)(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_get_acl, ret); - ret = lsm_call_backup(security_inode_get_acl, idmap, dentry, acl_name); - lsm_int_hook_after(LSM_TYPE_security_inode_get_acl, ret); - return ret; -} - -int lsm_replace(security_inode_remove_acl)(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_remove_acl, ret); - ret = lsm_call_backup(security_inode_remove_acl, idmap, dentry, acl_name); - lsm_int_hook_after(LSM_TYPE_security_inode_remove_acl, ret); - return ret; -} - -int lsm_replace(security_inode_need_killpriv)(struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_need_killpriv, ret); - ret = lsm_call_backup(security_inode_need_killpriv, dentry); - lsm_int_hook_after(LSM_TYPE_security_inode_need_killpriv, ret); - return ret; -} - -int lsm_replace(security_inode_killpriv)(struct dentry *dentry) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_killpriv, ret); - ret = lsm_call_backup(security_inode_killpriv, dentry); - lsm_int_hook_after(LSM_TYPE_security_inode_killpriv, ret); - return ret; -} - -int lsm_replace(security_inode_getsecurity)(struct inode *inode, const char *name, void **buffer, bool alloc) -{ - // int defrc = -EOPNOTSUPP; - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_getsecurity, ret); - ret = lsm_call_backup(security_inode_getsecurity, inode, name, buffer, alloc); - lsm_int_hook_after(LSM_TYPE_security_inode_getsecurity, ret); - return ret; -} - -int lsm_replace(security_inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, - int flags) -{ - // int defrc = -EOPNOTSUPP; - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_setsecurity, ret); - ret = lsm_call_backup(security_inode_setsecurity, inode, name, value, size, flags); - lsm_int_hook_after(LSM_TYPE_security_inode_setsecurity, ret); - return ret; -} - -int lsm_replace(security_inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_listsecurity, ret); - ret = lsm_call_backup(security_inode_listsecurity, inode, buffer, buffer_size); - lsm_int_hook_after(LSM_TYPE_security_inode_listsecurity, ret); - return ret; -} -void lsm_replace(security_inode_getsecid)(struct inode *inode, u32 *secid) -{ - lsm_void_hook_before(LSM_TYPE_security_inode_getsecid); - lsm_call_backup(security_inode_getsecid, inode, secid); - lsm_void_hook_after(LSM_TYPE_security_inode_getsecid); -} -int lsm_replace(security_inode_copy_up)(struct dentry *src, struct cred **new) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_copy_up, ret); - ret = lsm_call_backup(security_inode_copy_up, src, new); - lsm_int_hook_after(LSM_TYPE_security_inode_copy_up, ret); - - return ret; -} -int lsm_replace(security_inode_copy_up_xattr)(const char *name) -{ - // // int defrc = -EOPNOTSUPP; - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_copy_up_xattr, ret); - ret = lsm_call_backup(security_inode_copy_up_xattr, name); - lsm_int_hook_after(LSM_TYPE_security_inode_copy_up_xattr, ret); - return ret; -} -int lsm_replace(security_kernfs_init_security)(struct kernfs_node *kn_dir, struct kernfs_node *kn) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_kernfs_init_security, ret); - ret = lsm_call_backup(security_kernfs_init_security, kn_dir, kn); - lsm_int_hook_after(LSM_TYPE_security_kernfs_init_security, ret); - - return ret; -} -int lsm_replace(security_file_permission)(struct file *file, int mask) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_permission, ret); - ret = lsm_call_backup(security_file_permission, file, mask); - lsm_int_hook_after(LSM_TYPE_security_file_permission, ret); - - return ret; -} -int lsm_replace(security_file_alloc)(struct file *file) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_alloc, ret); - ret = lsm_call_backup(security_file_alloc, file); - lsm_int_hook_after(LSM_TYPE_security_file_alloc, ret); - return ret; -} -void lsm_replace(security_file_free)(struct file *file) -{ - lsm_void_hook_before(LSM_TYPE_security_file_free); - lsm_call_backup(security_file_free, file); - lsm_void_hook_after(LSM_TYPE_security_file_free); -} -int lsm_replace(security_file_ioctl)(struct file *file, unsigned int cmd, unsigned long arg) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_ioctl, ret); - ret = lsm_call_backup(security_file_ioctl, file, cmd, arg); - lsm_int_hook_after(LSM_TYPE_security_file_ioctl, ret); - - return ret; -} -int lsm_replace(security_mmap_addr)(unsigned long addr) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_mmap_addr, ret); - ret = lsm_call_backup(security_mmap_addr, addr); - lsm_int_hook_after(LSM_TYPE_security_mmap_addr, ret); - - return ret; -} -int lsm_replace(security_mmap_file)(struct file *file, unsigned long prot, unsigned long flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_mmap_file, ret); - ret = lsm_call_backup(security_mmap_file, file, prot, flags); - lsm_int_hook_after(LSM_TYPE_security_mmap_file, ret); - - return ret; -} -int lsm_replace(security_file_mprotect)(struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_mprotect, ret); - ret = lsm_call_backup(security_file_mprotect, vma, reqprot, prot); - lsm_int_hook_after(LSM_TYPE_security_file_mprotect, ret); - - return ret; -} -int lsm_replace(security_file_lock)(struct file *file, unsigned int cmd) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_lock, ret); - ret = lsm_call_backup(security_file_lock, file, cmd); - lsm_int_hook_after(LSM_TYPE_security_file_lock, ret); - - return ret; -} -int lsm_replace(security_file_fcntl)(struct file *file, unsigned int cmd, unsigned long arg) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_fcntl, ret); - ret = lsm_call_backup(security_file_fcntl, file, cmd, arg); - lsm_int_hook_after(LSM_TYPE_security_file_fcntl, ret); - - return ret; -} -void lsm_replace(security_file_set_fowner)(struct file *file) -{ - lsm_void_hook_before(LSM_TYPE_security_file_set_fowner); - lsm_call_backup(security_file_set_fowner, file); - lsm_void_hook_after(LSM_TYPE_security_file_set_fowner); -} -int lsm_replace(security_file_send_sigiotask)(struct task_struct *tsk, struct fown_struct *fown, int sig) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_send_sigiotask, ret); - ret = lsm_call_backup(security_file_send_sigiotask, tsk, fown, sig); - lsm_int_hook_after(LSM_TYPE_security_file_send_sigiotask, ret); - - return ret; -} -int lsm_replace(security_file_receive)(struct file *file) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_receive, ret); - ret = lsm_call_backup(security_file_receive, file); - lsm_int_hook_after(LSM_TYPE_security_file_receive, ret); - - return ret; -} -int lsm_replace(security_file_open)(struct file *file, const struct cred *cred) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_open, ret); - ret = lsm_call_backup(security_file_open, file, cred); - lsm_int_hook_after(LSM_TYPE_security_file_open, ret); - - return ret; -} -int lsm_replace(security_file_truncate)(struct file *file) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_file_truncate, ret); - ret = lsm_call_backup(security_file_truncate, file); - lsm_int_hook_after(LSM_TYPE_security_file_truncate, ret); - - return ret; -} -int lsm_replace(security_task_alloc)(struct task_struct *task, unsigned long clone_flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_alloc, ret); - ret = lsm_call_backup(security_task_alloc, task, clone_flags); - lsm_int_hook_after(LSM_TYPE_security_task_alloc, ret); - - return ret; -} -void lsm_replace(security_task_free)(struct task_struct *task) -{ - lsm_void_hook_before(LSM_TYPE_security_task_free); - lsm_call_backup(security_task_free, task); - lsm_void_hook_after(LSM_TYPE_security_task_free); -} -int lsm_replace(security_cred_alloc_blank)(struct cred *cred, gfp_t gfp) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_cred_alloc_blank, ret); - ret = lsm_call_backup(security_cred_alloc_blank, cred, gfp); - lsm_int_hook_after(LSM_TYPE_security_cred_alloc_blank, ret); - return ret; -} -void lsm_replace(security_cred_free)(struct cred *cred) -{ - lsm_void_hook_before(LSM_TYPE_security_cred_free); - lsm_call_backup(security_cred_free, cred); - lsm_void_hook_after(LSM_TYPE_security_cred_free); -} -int lsm_replace(security_prepare_creds)(struct cred *new, const struct cred *old, gfp_t gfp) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_prepare_creds, ret); - ret = lsm_call_backup(security_prepare_creds, new, old, gfp); - lsm_int_hook_after(LSM_TYPE_security_prepare_creds, ret); - return ret; -} -void lsm_replace(security_transfer_creds)(struct cred *new, const struct cred *old) -{ - lsm_void_hook_before(LSM_TYPE_security_transfer_creds); - lsm_call_backup(security_transfer_creds, new, old); - lsm_void_hook_after(LSM_TYPE_security_transfer_creds); -} -void lsm_replace(security_cred_getsecid)(const struct cred *c, u32 *secid) -{ - lsm_void_hook_before(LSM_TYPE_security_cred_getsecid); - lsm_call_backup(security_cred_getsecid, c, secid); - lsm_void_hook_after(LSM_TYPE_security_cred_getsecid); -} -int lsm_replace(security_kernel_act_as)(struct cred *new, u32 secid) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_kernel_act_as, ret); - ret = lsm_call_backup(security_kernel_act_as, new, secid); - lsm_int_hook_after(LSM_TYPE_security_kernel_act_as, ret); - - return ret; -} -int lsm_replace(security_kernel_create_files_as)(struct cred *new, struct inode *inode) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_kernel_create_files_as, ret); - ret = lsm_call_backup(security_kernel_create_files_as, new, inode); - lsm_int_hook_after(LSM_TYPE_security_kernel_create_files_as, ret); - - return ret; -} -int lsm_replace(security_kernel_module_request)(char *kmod_name) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_kernel_module_request, ret); - ret = lsm_call_backup(security_kernel_module_request, kmod_name); - lsm_int_hook_after(LSM_TYPE_security_kernel_module_request, ret); - - return ret; -} -int lsm_replace(security_kernel_load_data)(enum kernel_load_data_id id, bool contents) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_kernel_load_data, ret); - ret = lsm_call_backup(security_kernel_load_data, id, contents); - lsm_int_hook_after(LSM_TYPE_security_kernel_load_data, ret); - - return ret; -} -int lsm_replace(security_kernel_post_load_data)(char *buf, loff_t size, enum kernel_load_data_id id, char *description) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_kernel_post_load_data, ret); - ret = lsm_call_backup(security_kernel_post_load_data, buf, size, id, description); - lsm_int_hook_after(LSM_TYPE_security_kernel_post_load_data, ret); - - return ret; -} -int lsm_replace(security_kernel_read_file)(struct file *file, enum kernel_read_file_id id, bool contents) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_kernel_read_file, ret); - ret = lsm_call_backup(security_kernel_read_file, file, id, contents); - lsm_int_hook_after(LSM_TYPE_security_kernel_read_file, ret); - - return ret; -} -int lsm_replace(security_kernel_post_read_file)(struct file *file, char *buf, loff_t size, enum kernel_read_file_id id) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_kernel_post_read_file, ret); - ret = lsm_call_backup(security_kernel_post_read_file, file, buf, size, id); - lsm_int_hook_after(LSM_TYPE_security_kernel_post_read_file, ret); - - return ret; -} -int lsm_replace(security_task_fix_setuid)(struct cred *new, const struct cred *old, int flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_fix_setuid, ret); - ret = lsm_call_backup(security_task_fix_setuid, new, old, flags); - lsm_int_hook_after(LSM_TYPE_security_task_fix_setuid, ret); - - return ret; -} -int lsm_replace(security_task_fix_setgid)(struct cred *new, const struct cred *old, int flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_fix_setgid, ret); - ret = lsm_call_backup(security_task_fix_setgid, new, old, flags); - lsm_int_hook_after(LSM_TYPE_security_task_fix_setgid, ret); - - return ret; -} -int lsm_replace(security_task_fix_setgroups)(struct cred *new, const struct cred *old) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_fix_setgroups, ret); - ret = lsm_call_backup(security_task_fix_setgroups, new, old); - lsm_int_hook_after(LSM_TYPE_security_task_fix_setgroups, ret); - - return ret; -} -int lsm_replace(security_task_setpgid)(struct task_struct *p, pid_t pgid) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_setpgid, ret); - ret = lsm_call_backup(security_task_setpgid, p, pgid); - lsm_int_hook_after(LSM_TYPE_security_task_setpgid, ret); - - return ret; -} -int lsm_replace(security_task_getpgid)(struct task_struct *p) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_getpgid, ret); - ret = lsm_call_backup(security_task_getpgid, p); - lsm_int_hook_after(LSM_TYPE_security_task_getpgid, ret); - - return ret; -} -int lsm_replace(security_task_getsid)(struct task_struct *p) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_getsid, ret); - ret = lsm_call_backup(security_task_getsid, p); - lsm_int_hook_after(LSM_TYPE_security_task_getsid, ret); - - return ret; -} -void lsm_replace(security_current_getsecid_subj)(u32 *secid) -{ - lsm_void_hook_before(LSM_TYPE_security_current_getsecid_subj); - lsm_call_backup(security_current_getsecid_subj, secid); - lsm_void_hook_after(LSM_TYPE_security_current_getsecid_subj); -} -void lsm_replace(security_task_getsecid_obj)(struct task_struct *p, u32 *secid) // ?-6.3 -{ - lsm_void_hook_before(LSM_TYPE_security_task_getsecid_obj); - lsm_call_backup(security_task_getsecid_obj, p, secid); - lsm_void_hook_after(LSM_TYPE_security_task_getsecid_obj); -} -void lsm_replace(security_task_getsecid)(struct task_struct *p, u32 *secid) // 4.4-? -{ - lsm_void_hook_before(LSM_TYPE_security_task_getsecid); - lsm_call_backup(security_task_getsecid, p, secid); - lsm_void_hook_after(LSM_TYPE_security_task_getsecid); -} -int lsm_replace(security_task_setnice)(struct task_struct *p, int nice) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_setnice, ret); - ret = lsm_call_backup(security_task_setnice, p, nice); - lsm_int_hook_after(LSM_TYPE_security_task_setnice, ret); - - return ret; -} -int lsm_replace(security_task_setioprio)(struct task_struct *p, int ioprio) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_setioprio, ret); - ret = lsm_call_backup(security_task_setioprio, p, ioprio); - lsm_int_hook_after(LSM_TYPE_security_task_setioprio, ret); - - return ret; -} -int lsm_replace(security_task_getioprio)(struct task_struct *p) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_getioprio, ret); - ret = lsm_call_backup(security_task_getioprio, p); - lsm_int_hook_after(LSM_TYPE_security_task_getioprio, ret); - - return ret; -} -int lsm_replace(security_task_prlimit)(const struct cred *cred, const struct cred *tcred, unsigned int flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_prlimit, ret); - ret = lsm_call_backup(security_task_prlimit, cred, tcred, flags); - lsm_int_hook_after(LSM_TYPE_security_task_prlimit, ret); - - return ret; -} -int lsm_replace(security_task_setrlimit)(struct task_struct *p, unsigned int resource, struct rlimit *new_rlim) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_setrlimit, ret); - ret = lsm_call_backup(security_task_setrlimit, p, resource, new_rlim); - lsm_int_hook_after(LSM_TYPE_security_task_setrlimit, ret); - - return ret; -} -int lsm_replace(security_task_setscheduler)(struct task_struct *p) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_setscheduler, ret); - ret = lsm_call_backup(security_task_setscheduler, p); - lsm_int_hook_after(LSM_TYPE_security_task_setscheduler, ret); - - return ret; -} -int lsm_replace(security_task_getscheduler)(struct task_struct *p) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_getscheduler, ret); - ret = lsm_call_backup(security_task_getscheduler, p); - lsm_int_hook_after(LSM_TYPE_security_task_getscheduler, ret); - - return ret; -} -int lsm_replace(security_task_movememory)(struct task_struct *p) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_movememory, ret); - ret = lsm_call_backup(security_task_movememory, p); - lsm_int_hook_after(LSM_TYPE_security_task_movememory, ret); - - return ret; -} -int lsm_replace(security_task_kill)(struct task_struct *p, struct kernel_siginfo *info, int sig, - const struct cred *cred) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_kill, ret); - ret = lsm_call_backup(security_task_kill, p, info, sig, cred); - lsm_int_hook_after(LSM_TYPE_security_task_kill, ret); - - return ret; -} -int lsm_replace(security_task_prctl)(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, - unsigned long arg5) -{ - // int defrc = -ENOSYS; - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_task_prctl, ret); - ret = lsm_call_backup(security_task_prctl, option, arg2, arg3, arg4, arg5); - lsm_int_hook_after(LSM_TYPE_security_task_prctl, ret); - return ret; -} -void lsm_replace(security_task_to_inode)(struct task_struct *p, struct inode *inode) -{ - lsm_void_hook_before(LSM_TYPE_security_task_to_inode); - lsm_call_backup(security_task_to_inode, p, inode); - lsm_void_hook_after(LSM_TYPE_security_task_to_inode); -} -int lsm_replace(security_create_user_ns)(const struct cred *cred) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_create_user_ns, ret); - ret = lsm_call_backup(security_create_user_ns, cred); - lsm_int_hook_after(LSM_TYPE_security_create_user_ns, ret); - - return ret; -} -int lsm_replace(security_ipc_permission)(struct kern_ipc_perm *ipcp, short flag) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_ipc_permission, ret); - ret = lsm_call_backup(security_ipc_permission, ipcp, flag); - lsm_int_hook_after(LSM_TYPE_security_ipc_permission, ret); - - return ret; -} -void lsm_replace(security_ipc_getsecid)(struct kern_ipc_perm *ipcp, u32 *secid) -{ - lsm_void_hook_before(LSM_TYPE_security_ipc_getsecid); - lsm_call_backup(security_ipc_getsecid, ipcp, secid); - lsm_void_hook_after(LSM_TYPE_security_ipc_getsecid); -} -int lsm_replace(security_msg_msg_alloc)(struct msg_msg *msg) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_msg_msg_alloc, ret); - ret = lsm_call_backup(security_msg_msg_alloc, msg); - lsm_int_hook_after(LSM_TYPE_security_msg_msg_alloc, ret); - - return ret; -} -void lsm_replace(security_msg_msg_free)(struct msg_msg *msg) -{ - lsm_void_hook_before(LSM_TYPE_security_msg_msg_free); - lsm_call_backup(security_msg_msg_free, msg); - lsm_void_hook_after(LSM_TYPE_security_msg_msg_free); -} -int lsm_replace(security_msg_queue_alloc)(struct kern_ipc_perm *msq) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_msg_queue_alloc, ret); - ret = lsm_call_backup(security_msg_queue_alloc, msq); - lsm_int_hook_after(LSM_TYPE_security_msg_queue_alloc, ret); - - return ret; -} -void lsm_replace(security_msg_queue_free)(struct kern_ipc_perm *msq) -{ - lsm_void_hook_before(LSM_TYPE_security_msg_queue_free); - lsm_call_backup(security_msg_queue_free, msq); - lsm_void_hook_after(LSM_TYPE_security_msg_queue_free); -} -int lsm_replace(security_msg_queue_associate)(struct kern_ipc_perm *msq, int msqflg) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_msg_queue_associate, ret); - ret = lsm_call_backup(security_msg_queue_associate, msq, msqflg); - lsm_int_hook_after(LSM_TYPE_security_msg_queue_associate, ret); - - return ret; -} -int lsm_replace(security_msg_queue_msgctl)(struct kern_ipc_perm *msq, int cmd) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_msg_queue_msgctl, ret); - ret = lsm_call_backup(security_msg_queue_msgctl, msq, cmd); - lsm_int_hook_after(LSM_TYPE_security_msg_queue_msgctl, ret); - - return ret; -} -int lsm_replace(security_msg_queue_msgsnd)(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_msg_queue_msgsnd, ret); - ret = lsm_call_backup(security_msg_queue_msgsnd, msq, msg, msqflg); - lsm_int_hook_after(LSM_TYPE_security_msg_queue_msgsnd, ret); - - return ret; -} -int lsm_replace(security_msg_queue_msgrcv)(struct kern_ipc_perm *msq, struct msg_msg *msg, struct task_struct *target, - long type, int mode) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_msg_queue_msgrcv, ret); - ret = lsm_call_backup(security_msg_queue_msgrcv, msq, msg, target, type, mode); - lsm_int_hook_after(LSM_TYPE_security_msg_queue_msgrcv, ret); - - return ret; -} -int lsm_replace(security_shm_alloc)(struct kern_ipc_perm *shp) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_shm_alloc, ret); - ret = lsm_call_backup(security_shm_alloc, shp); - lsm_int_hook_after(LSM_TYPE_security_shm_alloc, ret); - - return ret; -} -void lsm_replace(security_shm_free)(struct kern_ipc_perm *shp) -{ - lsm_void_hook_before(LSM_TYPE_security_shm_free); - lsm_call_backup(security_shm_free, shp); - lsm_void_hook_after(LSM_TYPE_security_shm_free); -} -int lsm_replace(security_shm_associate)(struct kern_ipc_perm *shp, int shmflg) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_shm_associate, ret); - ret = lsm_call_backup(security_shm_associate, shp, shmflg); - lsm_int_hook_after(LSM_TYPE_security_shm_associate, ret); - - return ret; -} -int lsm_replace(security_shm_shmctl)(struct kern_ipc_perm *shp, int cmd) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_shm_shmctl, ret); - ret = lsm_call_backup(security_shm_shmctl, shp, cmd); - lsm_int_hook_after(LSM_TYPE_security_shm_shmctl, ret); - - return ret; -} -int lsm_replace(security_shm_shmat)(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_shm_shmat, ret); - ret = lsm_call_backup(security_shm_shmat, shp, shmaddr, shmflg); - lsm_int_hook_after(LSM_TYPE_security_shm_shmat, ret); - - return ret; -} -int lsm_replace(security_sem_alloc)(struct kern_ipc_perm *sma) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sem_alloc, ret); - ret = lsm_call_backup(security_sem_alloc, sma); - lsm_int_hook_after(LSM_TYPE_security_sem_alloc, ret); - - return ret; -} -void lsm_replace(security_sem_free)(struct kern_ipc_perm *sma) -{ - lsm_void_hook_before(LSM_TYPE_security_sem_free); - lsm_call_backup(security_sem_free, sma); - lsm_void_hook_after(LSM_TYPE_security_sem_free); -} -int lsm_replace(security_sem_associate)(struct kern_ipc_perm *sma, int semflg) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sem_associate, ret); - ret = lsm_call_backup(security_sem_associate, sma, semflg); - lsm_int_hook_after(LSM_TYPE_security_sem_associate, ret); - - return ret; -} -int lsm_replace(security_sem_semctl)(struct kern_ipc_perm *sma, int cmd) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sem_semctl, ret); - ret = lsm_call_backup(security_sem_semctl, sma, cmd); - lsm_int_hook_after(LSM_TYPE_security_sem_semctl, ret); - - return ret; -} -int lsm_replace(security_sem_semop)(struct kern_ipc_perm *sma, struct sembuf *sops, unsigned nsops, int alter) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sem_semop, ret); - ret = lsm_call_backup(security_sem_semop, sma, sops, nsops, alter); - lsm_int_hook_after(LSM_TYPE_security_sem_semop, ret); - - return ret; -} -void lsm_replace(security_d_instantiate)(struct dentry *dentry, struct inode *inode) -{ - lsm_void_hook_before(LSM_TYPE_security_d_instantiate); - lsm_call_backup(security_d_instantiate, dentry, inode); - lsm_void_hook_after(LSM_TYPE_security_d_instantiate); -} -int lsm_replace(security_getprocattr)(struct task_struct *p, const char *lsm, char *name, char **value) -{ - // int defrc = -EINVAL; - - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_getprocattr, ret); - ret = lsm_call_backup(security_getprocattr, p, lsm, name, value); - lsm_int_hook_after(LSM_TYPE_security_getprocattr, ret); - - return ret; -} -int lsm_replace(security_setprocattr)(const char *lsm, const char *name, void *value, size_t size) -{ - // int defrc = -EINVAL; - - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_setprocattr, ret); - ret = lsm_call_backup(security_setprocattr, lsm, name, value, size); - lsm_int_hook_after(LSM_TYPE_security_setprocattr, ret); - - return ret; -} -int lsm_replace(security_netlink_send)(struct sock *sk, struct sk_buff *skb) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_netlink_send, ret); - ret = lsm_call_backup(security_netlink_send, sk, skb); - lsm_int_hook_after(LSM_TYPE_security_netlink_send, ret); - - return ret; -} -int lsm_replace(security_ismaclabel)(const char *name) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_ismaclabel, ret); - ret = lsm_call_backup(security_ismaclabel, name); - lsm_int_hook_after(LSM_TYPE_security_ismaclabel, ret); - - return ret; -} -int lsm_replace(security_secid_to_secctx)(u32 secid, char **secdata, u32 *seclen) -{ - // int defrc = -EOPNOTSUPP; - - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_secid_to_secctx, ret); - ret = lsm_call_backup(security_secid_to_secctx, secid, secdata, seclen); - lsm_int_hook_after(LSM_TYPE_security_secid_to_secctx, ret); - - return ret; -} -int lsm_replace(security_secctx_to_secid)(const char *secdata, u32 seclen, u32 *secid) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_secctx_to_secid, ret); - ret = lsm_call_backup(security_secctx_to_secid, secdata, seclen, secid); - lsm_int_hook_after(LSM_TYPE_security_secctx_to_secid, ret); - - return ret; -} -void lsm_replace(security_release_secctx)(char *secdata, u32 seclen) -{ - lsm_void_hook_before(LSM_TYPE_security_release_secctx); - lsm_call_backup(security_release_secctx, secdata, seclen); - lsm_void_hook_after(LSM_TYPE_security_release_secctx); -} -void lsm_replace(security_inode_invalidate_secctx)(struct inode *inode) -{ - lsm_void_hook_before(LSM_TYPE_security_inode_invalidate_secctx); - lsm_call_backup(security_inode_invalidate_secctx, inode); - lsm_void_hook_after(LSM_TYPE_security_inode_invalidate_secctx); -} -int lsm_replace(security_inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_notifysecctx, ret); - ret = lsm_call_backup(security_inode_notifysecctx, inode, ctx, ctxlen); - lsm_int_hook_after(LSM_TYPE_security_inode_notifysecctx, ret); - - return ret; -} -int lsm_replace(security_inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_setsecctx, ret); - ret = lsm_call_backup(security_inode_setsecctx, dentry, ctx, ctxlen); - lsm_int_hook_after(LSM_TYPE_security_inode_setsecctx, ret); - - return ret; -} -int lsm_replace(security_inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inode_getsecctx, ret); - ret = lsm_call_backup(security_inode_getsecctx, inode, ctx, ctxlen); - lsm_int_hook_after(LSM_TYPE_security_inode_getsecctx, ret); - - return ret; -} - -// CONFIG_WATCH_QUEUE -int lsm_replace(security_post_notification)(const struct cred *w_cred, const struct cred *cred, - struct watch_notification *n) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_post_notification, ret); - ret = lsm_call_backup(security_post_notification, w_cred, cred, n); - lsm_int_hook_after(LSM_TYPE_security_post_notification, ret); - - return ret; -} - -// CONFIG_KEY_NOTIFICATIONS -int lsm_replace(security_watch_key)(struct key *key) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_watch_key, ret); - ret = lsm_call_backup(security_watch_key, key); - lsm_int_hook_after(LSM_TYPE_security_watch_key, ret); - - return ret; -} - -// CONFIG_SECURITY_NETWORK -int lsm_replace(security_unix_stream_connect)(struct sock *sock, struct sock *other, struct sock *newsk) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_unix_stream_connect, ret); - ret = lsm_call_backup(security_unix_stream_connect, sock, other, newsk); - lsm_int_hook_after(LSM_TYPE_security_unix_stream_connect, ret); - - return ret; -} -int lsm_replace(security_unix_may_send)(struct socket *sock, struct socket *other) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_unix_may_send, ret); - ret = lsm_call_backup(security_unix_may_send, sock, other); - lsm_int_hook_after(LSM_TYPE_security_unix_may_send, ret); - - return ret; -} -int lsm_replace(security_socket_create)(int family, int type, int protocol, int kern) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_create, ret); - ret = lsm_call_backup(security_socket_create, family, type, protocol, kern); - lsm_int_hook_after(LSM_TYPE_security_socket_create, ret); - - return ret; -} -int lsm_replace(security_socket_post_create)(struct socket *sock, int family, int type, int protocol, int kern) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_post_create, ret); - ret = lsm_call_backup(security_socket_post_create, sock, family, type, protocol, kern); - lsm_int_hook_after(LSM_TYPE_security_socket_post_create, ret); - - return ret; -} -int lsm_replace(security_socket_socketpair)(struct socket *socka, struct socket *sockb) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_socketpair, ret); - ret = lsm_call_backup(security_socket_socketpair, socka, sockb); - lsm_int_hook_after(LSM_TYPE_security_socket_socketpair, ret); - - return ret; -} -int lsm_replace(security_socket_bind)(struct socket *sock, struct sockaddr *address, int addrlen) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_bind, ret); - ret = lsm_call_backup(security_socket_bind, sock, address, addrlen); - lsm_int_hook_after(LSM_TYPE_security_socket_bind, ret); - - return ret; -} -int lsm_replace(security_socket_connect)(struct socket *sock, struct sockaddr *address, int addrlen) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_connect, ret); - ret = lsm_call_backup(security_socket_connect, sock, address, addrlen); - lsm_int_hook_after(LSM_TYPE_security_socket_connect, ret); - - return ret; -} -int lsm_replace(security_socket_listen)(struct socket *sock, int backlog) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_listen, ret); - ret = lsm_call_backup(security_socket_listen, sock, backlog); - lsm_int_hook_after(LSM_TYPE_security_socket_listen, ret); - - return ret; -} -int lsm_replace(security_socket_accept)(struct socket *sock, struct socket *newsock) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_accept, ret); - ret = lsm_call_backup(security_socket_accept, sock, newsock); - lsm_int_hook_after(LSM_TYPE_security_socket_accept, ret); - - return ret; -} -int lsm_replace(security_socket_sendmsg)(struct socket *sock, struct msghdr *msg, int size) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_sendmsg, ret); - ret = lsm_call_backup(security_socket_sendmsg, sock, msg, size); - lsm_int_hook_after(LSM_TYPE_security_socket_sendmsg, ret); - - return ret; -} -int lsm_replace(security_socket_recvmsg)(struct socket *sock, struct msghdr *msg, int size, int flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_recvmsg, ret); - ret = lsm_call_backup(security_socket_recvmsg, sock, msg, size, flags); - lsm_int_hook_after(LSM_TYPE_security_socket_recvmsg, ret); - - return ret; -} -int lsm_replace(security_socket_getsockname)(struct socket *sock) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_getsockname, ret); - ret = lsm_call_backup(security_socket_getsockname, sock); - lsm_int_hook_after(LSM_TYPE_security_socket_getsockname, ret); - - return ret; -} -int lsm_replace(security_socket_getpeername)(struct socket *sock) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_getpeername, ret); - ret = lsm_call_backup(security_socket_getpeername, sock); - lsm_int_hook_after(LSM_TYPE_security_socket_getpeername, ret); - - return ret; -} -int lsm_replace(security_socket_getsockopt)(struct socket *sock, int level, int optname) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_getsockopt, ret); - ret = lsm_call_backup(security_socket_getsockopt, sock, level, optname); - lsm_int_hook_after(LSM_TYPE_security_socket_getsockopt, ret); - - return ret; -} -int lsm_replace(security_socket_setsockopt)(struct socket *sock, int level, int optname) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_setsockopt, ret); - ret = lsm_call_backup(security_socket_setsockopt, sock, level, optname); - lsm_int_hook_after(LSM_TYPE_security_socket_setsockopt, ret); - - return ret; -} -int lsm_replace(security_socket_shutdown)(struct socket *sock, int how) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_shutdown, ret); - ret = lsm_call_backup(security_socket_shutdown, sock, how); - lsm_int_hook_after(LSM_TYPE_security_socket_shutdown, ret); - - return ret; -} -int lsm_replace(security_sock_rcv_skb)(struct sock *sk, struct sk_buff *skb) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sock_rcv_skb, ret); - ret = lsm_call_backup(security_sock_rcv_skb, sk, skb); - lsm_int_hook_after(LSM_TYPE_security_sock_rcv_skb, ret); - - return ret; -} -int lsm_replace(security_socket_getpeersec_stream)(struct socket *sock, sockptr_t optval, sockptr_t optlen, - unsigned int len) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_getpeersec_stream, ret); - ret = lsm_call_backup(security_socket_getpeersec_stream, sock, optval, optlen, len); - lsm_int_hook_after(LSM_TYPE_security_socket_getpeersec_stream, ret); - - return ret; -} -int lsm_replace(security_socket_getpeersec_dgram)(struct socket *sock, struct sk_buff *skb, u32 *secid) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_socket_getpeersec_dgram, ret); - ret = lsm_call_backup(security_socket_getpeersec_dgram, sock, skb, secid); - lsm_int_hook_after(LSM_TYPE_security_socket_getpeersec_dgram, ret); - - return ret; -} -int lsm_replace(security_sk_alloc)(struct sock *sk, int family, gfp_t priority) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sk_alloc, ret); - ret = lsm_call_backup(security_sk_alloc, sk, family, priority); - lsm_int_hook_after(LSM_TYPE_security_sk_alloc, ret); - - return ret; -} -void lsm_replace(security_sk_free)(struct sock *sk) -{ - lsm_void_hook_before(LSM_TYPE_security_sk_free); - lsm_call_backup(security_sk_free, sk); - lsm_void_hook_after(LSM_TYPE_security_sk_free); -} -void lsm_replace(security_sk_clone)(const struct sock *sk, struct sock *newsk) -{ - lsm_void_hook_before(LSM_TYPE_security_sk_clone); - lsm_call_backup(security_sk_clone, sk, newsk); - lsm_void_hook_after(LSM_TYPE_security_sk_clone); -} -void lsm_replace(security_sk_classify_flow)(struct sock *sk, struct flowi_common *flic) -{ - lsm_void_hook_before(LSM_TYPE_security_sk_classify_flow); - lsm_call_backup(security_sk_classify_flow, sk, flic); - lsm_void_hook_after(LSM_TYPE_security_sk_classify_flow); -} -void lsm_replace(security_req_classify_flow)(const struct request_sock *req, struct flowi_common *flic) -{ - lsm_void_hook_before(LSM_TYPE_security_req_classify_flow); - lsm_call_backup(security_req_classify_flow, req, flic); - lsm_void_hook_after(LSM_TYPE_security_req_classify_flow); -} -void lsm_replace(security_sock_graft)(struct sock *sk, struct socket *parent) -{ - lsm_void_hook_before(LSM_TYPE_security_sock_graft); - lsm_call_backup(security_sock_graft, sk, parent); - lsm_void_hook_after(LSM_TYPE_security_sock_graft); -} -int lsm_replace(security_inet_conn_request)(const struct sock *sk, struct sk_buff *skb, struct request_sock *req) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_inet_conn_request, ret); - ret = lsm_call_backup(security_inet_conn_request, sk, skb, req); - lsm_int_hook_after(LSM_TYPE_security_inet_conn_request, ret); - - return ret; -} -void lsm_replace(security_inet_csk_clone)(struct sock *newsk, const struct request_sock *req) -{ - lsm_void_hook_before(LSM_TYPE_security_inet_csk_clone); - lsm_call_backup(security_inet_csk_clone, newsk, req); - lsm_void_hook_after(LSM_TYPE_security_inet_csk_clone); -} -void lsm_replace(security_inet_conn_established)(struct sock *sk, struct sk_buff *skb) -{ - lsm_void_hook_before(LSM_TYPE_security_inet_conn_established); - lsm_call_backup(security_inet_conn_established, sk, skb); - lsm_void_hook_after(LSM_TYPE_security_inet_conn_established); -} -int lsm_replace(security_secmark_relabel_packet)(u32 secid) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_secmark_relabel_packet, ret); - ret = lsm_call_backup(security_secmark_relabel_packet, secid); - lsm_int_hook_after(LSM_TYPE_security_secmark_relabel_packet, ret); - - return ret; -} -void lsm_replace(security_secmark_refcount_inc)(void) -{ - lsm_void_hook_before(LSM_TYPE_security_secmark_refcount_inc); - lsm_call_backup(security_secmark_refcount_inc, ); - lsm_void_hook_after(LSM_TYPE_security_secmark_refcount_inc); -} - -void lsm_replace(security_secmark_refcount_dec)(void) -{ - lsm_void_hook_before(LSM_TYPE_security_secmark_refcount_dec); - lsm_call_backup(security_secmark_refcount_dec); - lsm_void_hook_after(LSM_TYPE_security_secmark_refcount_dec); -} -int lsm_replace(security_tun_dev_alloc_security)(void **security) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_tun_dev_alloc_security, ret); - ret = lsm_call_backup(security_tun_dev_alloc_security, security); - lsm_int_hook_after(LSM_TYPE_security_tun_dev_alloc_security, ret); - - return ret; -} -void lsm_replace(security_tun_dev_free_security)(void *security) -{ - lsm_void_hook_before(LSM_TYPE_security_tun_dev_free_security); - lsm_call_backup(security_tun_dev_free_security, security); - lsm_void_hook_after(LSM_TYPE_security_tun_dev_free_security); -} - -int lsm_replace(security_tun_dev_create)(void) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_tun_dev_create, ret); - ret = lsm_call_backup(security_tun_dev_create); - lsm_int_hook_after(LSM_TYPE_security_tun_dev_create, ret); - return ret; -} - -int lsm_replace(security_tun_dev_attach_queue)(void *security) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_tun_dev_attach_queue, ret); - ret = lsm_call_backup(security_tun_dev_attach_queue, security); - lsm_int_hook_after(LSM_TYPE_security_tun_dev_attach_queue, ret); - return ret; -} - -int lsm_replace(security_tun_dev_attach)(struct sock *sk, void *security) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_tun_dev_attach, ret); - ret = lsm_call_backup(security_tun_dev_attach, sk, security); - lsm_int_hook_after(LSM_TYPE_security_tun_dev_attach, ret); - return ret; -} - -int lsm_replace(security_tun_dev_open)(void *security) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_tun_dev_open, ret); - ret = lsm_call_backup(security_tun_dev_open, security); - lsm_int_hook_after(LSM_TYPE_security_tun_dev_open, ret); - return ret; -} - -int lsm_replace(security_sctp_assoc_request)(struct sctp_association *asoc, struct sk_buff *skb) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sctp_assoc_request, ret); - ret = lsm_call_backup(security_sctp_assoc_request, asoc, skb); - lsm_int_hook_after(LSM_TYPE_security_sctp_assoc_request, ret); - return ret; -} - -int lsm_replace(security_sctp_bind_connect)(struct sock *sk, int optname, struct sockaddr *address, int addrlen) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sctp_bind_connect, ret); - ret = lsm_call_backup(security_sctp_bind_connect, sk, optname, address, addrlen); - lsm_int_hook_after(LSM_TYPE_security_sctp_bind_connect, ret); - return ret; -} - -void lsm_replace(security_sctp_sk_clone)(struct sctp_association *asoc, struct sock *sk, struct sock *newsk) -{ - lsm_void_hook_before(LSM_TYPE_security_sctp_sk_clone); - lsm_call_backup(security_sctp_sk_clone, asoc, sk, newsk); - lsm_void_hook_after(LSM_TYPE_security_sctp_sk_clone); -} - -int lsm_replace(security_sctp_assoc_established)(struct sctp_association *asoc, struct sk_buff *skb) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_sctp_assoc_established, ret); - ret = lsm_call_backup(security_sctp_assoc_established, asoc, skb); - lsm_int_hook_after(LSM_TYPE_security_sctp_assoc_established, ret); - return ret; -} - -// CONFIG_SECURITY_INFINIBAND -int lsm_replace(security_ib_pkey_access)(void *sec, u64 subnet_prefix, u16 pkey) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_ib_pkey_access, ret); - ret = lsm_call_backup(security_ib_pkey_access, sec, subnet_prefix, pkey); - lsm_int_hook_after(LSM_TYPE_security_ib_pkey_access, ret); - return ret; -} -int lsm_replace(security_ib_endport_manage_subnet)(void *sec, const char *dev_name, u8 port_num) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_ib_endport_manage_subnet, ret); - ret = lsm_call_backup(security_ib_endport_manage_subnet, sec, dev_name, port_num); - lsm_int_hook_after(LSM_TYPE_security_ib_endport_manage_subnet, ret); - - return ret; -} -int lsm_replace(security_ib_alloc_security)(void **sec) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_ib_alloc_security, ret); - ret = lsm_call_backup(security_ib_alloc_security, sec); - lsm_int_hook_after(LSM_TYPE_security_ib_alloc_security, ret); - return ret; -} - -void lsm_replace(security_ib_free_security)(void *sec) -{ - lsm_void_hook_before(LSM_TYPE_security_ib_free_security); - lsm_call_backup(security_ib_free_security, sec); - lsm_void_hook_after(LSM_TYPE_security_ib_free_security); -} - -// CONFIG_SECURITY_NETWORK_XFRM -int lsm_replace(security_xfrm_policy_alloc)(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx, gfp_t gfp) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_xfrm_policy_alloc, ret); - ret = lsm_call_backup(security_xfrm_policy_alloc, ctxp, sec_ctx, gfp); - lsm_int_hook_after(LSM_TYPE_security_xfrm_policy_alloc, ret); - return ret; -} - -int lsm_replace(security_xfrm_policy_clone)(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_xfrm_policy_clone, ret); - ret = lsm_call_backup(security_xfrm_policy_clone, old_ctx, new_ctxp); - lsm_int_hook_after(LSM_TYPE_security_xfrm_policy_clone, ret); - return ret; -} - -void lsm_replace(security_xfrm_policy_free)(struct xfrm_sec_ctx *ctx) -{ - lsm_void_hook_before(LSM_TYPE_security_xfrm_policy_free); - lsm_call_backup(security_xfrm_policy_free, ctx); - lsm_void_hook_after(LSM_TYPE_security_xfrm_policy_free); -} - -int lsm_replace(security_xfrm_policy_delete)(struct xfrm_sec_ctx *ctx) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_xfrm_policy_delete, ret); - ret = lsm_call_backup(security_xfrm_policy_delete, ctx); - lsm_int_hook_after(LSM_TYPE_security_xfrm_policy_delete, ret); - return ret; -} - -int lsm_replace(security_xfrm_state_alloc)(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_xfrm_state_alloc, ret); - ret = lsm_call_backup(security_xfrm_state_alloc, x, sec_ctx); - lsm_int_hook_after(LSM_TYPE_security_xfrm_state_alloc, ret); - return ret; -} - -int lsm_replace(security_xfrm_state_alloc_acquire)(struct xfrm_state *x, struct xfrm_sec_ctx *polsec, u32 secid) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_xfrm_state_alloc_acquire, ret); - ret = lsm_call_backup(security_xfrm_state_alloc_acquire, x, polsec, secid); - lsm_int_hook_after(LSM_TYPE_security_xfrm_state_alloc_acquire, ret); - return ret; -} - -int lsm_replace(security_xfrm_state_delete)(struct xfrm_state *x) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_xfrm_state_delete, ret); - ret = lsm_call_backup(security_xfrm_state_delete, x); - lsm_int_hook_after(LSM_TYPE_security_xfrm_state_delete, ret); - return ret; -} - -void lsm_replace(security_xfrm_state_free)(struct xfrm_state *x) -{ - lsm_void_hook_before(LSM_TYPE_security_xfrm_state_free); - lsm_call_backup(security_xfrm_state_free, x); - lsm_void_hook_after(LSM_TYPE_security_xfrm_state_free); -} - -int lsm_replace(security_xfrm_policy_lookup)(struct xfrm_sec_ctx *ctx, u32 fl_secid) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_xfrm_policy_lookup, ret); - ret = lsm_call_backup(security_xfrm_policy_lookup, ctx, fl_secid); - lsm_int_hook_after(LSM_TYPE_security_xfrm_policy_lookup, ret); - return ret; -} - -int lsm_replace(security_xfrm_state_pol_flow_match)(struct xfrm_state *x, struct xfrm_policy *xp, - const struct flowi_common *flic) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_xfrm_state_pol_flow_match, ret); - ret = lsm_call_backup(security_xfrm_state_pol_flow_match, x, xp, flic); - lsm_int_hook_after(LSM_TYPE_security_xfrm_state_pol_flow_match, ret); - return ret; -} - -int lsm_replace(security_xfrm_decode_session)(struct sk_buff *skb, u32 *secid) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_xfrm_decode_session, ret); - ret = lsm_call_backup(security_xfrm_decode_session, skb, secid); - lsm_int_hook_after(LSM_TYPE_security_xfrm_decode_session, ret); - return ret; -} - -void lsm_replace(security_skb_classify_flow)(struct sk_buff *skb, struct flowi_common *flic) -{ - lsm_void_hook_before(LSM_TYPE_security_skb_classify_flow); - lsm_call_backup(security_skb_classify_flow, skb, flic); - lsm_void_hook_after(LSM_TYPE_security_skb_classify_flow); -} - -/* key management security hooks */ -// CONFIG_KEYS -int lsm_replace(security_key_alloc)(struct key *key, const struct cred *cred, unsigned long flags) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_key_alloc, ret); - ret = lsm_call_backup(security_key_alloc, key, cred, flags); - lsm_int_hook_after(LSM_TYPE_security_key_alloc, ret); - return ret; -} - -void lsm_replace(security_key_free)(struct key *key) -{ - lsm_void_hook_before(LSM_TYPE_security_key_free); - lsm_call_backup(security_key_free, key); - lsm_void_hook_after(LSM_TYPE_security_key_free); -} - -int lsm_replace(security_key_permission)(key_ref_t key_ref, const struct cred *cred, enum key_need_perm need_perm) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_key_permission, ret); - ret = lsm_call_backup(security_key_permission, key_ref, cred, need_perm); - lsm_int_hook_after(LSM_TYPE_security_key_permission, ret); - return ret; -} - -int lsm_replace(security_key_getsecurity)(struct key *key, char **_buffer) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_key_getsecurity, ret); - ret = lsm_call_backup(security_key_getsecurity, key, _buffer); - lsm_int_hook_after(LSM_TYPE_security_key_getsecurity, ret); - return ret; -} - -// CONFIG_AUDIT -int lsm_replace(security_audit_rule_init)(u32 field, u32 op, char *rulestr, void **lsmrule) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_audit_rule_init, ret); - ret = lsm_call_backup(security_audit_rule_init, field, op, rulestr, lsmrule); - lsm_int_hook_after(LSM_TYPE_security_audit_rule_init, ret); - - return ret; -} -int lsm_replace(security_audit_rule_known)(struct audit_krule *krule) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_audit_rule_known, ret); - ret = lsm_call_backup(security_audit_rule_known, krule); - lsm_int_hook_after(LSM_TYPE_security_audit_rule_known, ret); - - return ret; -} -void lsm_replace(security_audit_rule_free)(void *lsmrule) -{ - lsm_void_hook_before(LSM_TYPE_security_audit_rule_free); - lsm_call_backup(security_audit_rule_free, lsmrule); - lsm_void_hook_after(LSM_TYPE_security_audit_rule_free); -} -int lsm_replace(security_audit_rule_match)(u32 secid, u32 field, u32 op, void *lsmrule) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_audit_rule_match, ret); - ret = lsm_call_backup(security_audit_rule_match, secid, field, op, lsmrule); - lsm_int_hook_after(LSM_TYPE_security_audit_rule_match, ret); - - return ret; -} - -// CONFIG_BPF_SYSCALL -int lsm_replace(security_bpf)(int cmd, union bpf_attr *attr, unsigned int size) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_bpf, ret); - ret = lsm_call_backup(security_bpf, cmd, attr, size); - lsm_int_hook_after(LSM_TYPE_security_bpf, ret); - - return ret; -} -int lsm_replace(security_bpf_map)(struct bpf_map *map, fmode_t fmode) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_bpf_map, ret); - ret = lsm_call_backup(security_bpf_map, map, fmode); - lsm_int_hook_after(LSM_TYPE_security_bpf_map, ret); - - return ret; -} -int lsm_replace(security_bpf_prog)(struct bpf_prog *prog) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_bpf_prog, ret); - ret = lsm_call_backup(security_bpf_prog, prog); - lsm_int_hook_after(LSM_TYPE_security_bpf_prog, ret); - - return ret; -} -int lsm_replace(security_bpf_map_alloc)(struct bpf_map *map) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_bpf_map_alloc, ret); - ret = lsm_call_backup(security_bpf_map_alloc, map); - lsm_int_hook_after(LSM_TYPE_security_bpf_map_alloc, ret); - - return ret; -} -int lsm_replace(security_bpf_prog_alloc)(struct bpf_prog_aux *aux) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_bpf_prog_alloc, ret); - ret = lsm_call_backup(security_bpf_prog_alloc, aux); - lsm_int_hook_after(LSM_TYPE_security_bpf_prog_alloc, ret); - - return ret; -} -void lsm_replace(security_bpf_map_free)(struct bpf_map *map) -{ - lsm_void_hook_before(LSM_TYPE_security_bpf_map_free); - lsm_call_backup(security_bpf_map_free, map); - lsm_void_hook_after(LSM_TYPE_security_bpf_map_free); -} -void lsm_replace(security_bpf_prog_free)(struct bpf_prog_aux *aux) -{ - lsm_void_hook_before(LSM_TYPE_security_bpf_prog_free); - lsm_call_backup(security_bpf_prog_free, aux); - lsm_void_hook_after(LSM_TYPE_security_bpf_prog_free); -} -// CONFIG_BPF_SYSCALL - -int lsm_replace(security_locked_down)(enum lockdown_reason what) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_locked_down, ret); - ret = lsm_call_backup(security_locked_down, what); - lsm_int_hook_after(LSM_TYPE_security_locked_down, ret); - - return ret; -} - -// CONFIG_PERF_EVENTS -int lsm_replace(security_perf_event_open)(struct perf_event_attr *attr, int type) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_perf_event_open, ret); - ret = lsm_call_backup(security_perf_event_open, attr, type); - lsm_int_hook_after(LSM_TYPE_security_perf_event_open, ret); - - return ret; -} -int lsm_replace(security_perf_event_alloc)(struct perf_event *event) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_perf_event_alloc, ret); - ret = lsm_call_backup(security_perf_event_alloc, event); - lsm_int_hook_after(LSM_TYPE_security_perf_event_alloc, ret); - - return ret; -} -void lsm_replace(security_perf_event_free)(struct perf_event *event) -{ - lsm_void_hook_before(LSM_TYPE_security_perf_event_free); - lsm_call_backup(security_perf_event_free, event); - lsm_void_hook_after(LSM_TYPE_security_perf_event_free); -} -int lsm_replace(security_perf_event_read)(struct perf_event *event) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_perf_event_read, ret); - ret = lsm_call_backup(security_perf_event_read, event); - lsm_int_hook_after(LSM_TYPE_security_perf_event_read, ret); - - return ret; -} -int lsm_replace(security_perf_event_write)(struct perf_event *event) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_perf_event_write, ret); - ret = lsm_call_backup(security_perf_event_write, event); - lsm_int_hook_after(LSM_TYPE_security_perf_event_write, ret); - - return ret; -} - -// CONFIG_IO_URING -int lsm_replace(security_uring_override_creds)(const struct cred *new) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_uring_override_creds, ret); - ret = lsm_call_backup(security_uring_override_creds, new); - lsm_int_hook_after(LSM_TYPE_security_uring_override_creds, ret); - - return ret; -} -int lsm_replace(security_uring_sqpoll)(void) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_uring_sqpoll, ret); - ret = lsm_call_backup(security_uring_sqpoll); - lsm_int_hook_after(LSM_TYPE_security_uring_sqpoll, ret); - return ret; -} -int lsm_replace(security_uring_cmd)(struct io_uring_cmd *ioucmd) -{ - int ret = 0; - lsm_int_hook_before(LSM_TYPE_security_uring_cmd, ret); - ret = lsm_call_backup(security_uring_cmd, ioucmd); - lsm_int_hook_after(LSM_TYPE_security_uring_cmd, ret); - return ret; -} - -int lsm_hook_install() -{ - // Security hooks for program execution operations. - lsm_hook(security_binder_set_context_mgr); - lsm_hook(security_binder_transaction); - lsm_hook(security_binder_transfer_binder); - lsm_hook(security_binder_transfer_file); - lsm_hook(security_ptrace_access_check); - lsm_hook(security_ptrace_traceme); - lsm_hook(security_capget); - lsm_hook(security_capset); - lsm_hook(security_capable); - lsm_hook(security_quotactl); - lsm_hook(security_quota_on); - lsm_hook(security_syslog); - lsm_hook(security_settime64); - lsm_hook(security_vm_enough_memory_mm); - lsm_hook(security_bprm_creds_for_exec); - lsm_hook(security_bprm_creds_from_file); - lsm_hook(security_bprm_check); - lsm_hook(security_bprm_committing_creds); - lsm_hook(security_bprm_committed_creds); - - // Security hooks for mount using fs_context. - lsm_hook(security_fs_context_dup); - lsm_hook(security_fs_context_parse_param); - - // Security hooks for filesystem operations. - lsm_hook(security_sb_alloc); - lsm_hook(security_sb_delete); - lsm_hook(security_sb_free); - lsm_hook(security_free_mnt_opts); - lsm_hook(security_sb_eat_lsm_opts); - lsm_hook(security_sb_remount); - lsm_hook(security_sb_kern_mount); - lsm_hook(security_sb_show_options); - lsm_hook(security_sb_statfs); - lsm_hook(security_sb_mount); - lsm_hook(security_sb_umount); - lsm_hook(security_sb_pivotroot); - lsm_hook(security_sb_set_mnt_opts); - lsm_hook(security_sb_clone_mnt_opts); - lsm_hook(security_add_mnt_opt); - lsm_hook(security_move_mount); - lsm_hook(security_dentry_init_security); - lsm_hook(security_dentry_create_files_as); - - // //CONFIG_SECURITY_PATH - lsm_hook(security_path_unlink); - lsm_hook(security_path_mkdir); - lsm_hook(security_path_rmdir); - lsm_hook(security_path_mknod); - lsm_hook(security_path_truncate); - lsm_hook(security_path_symlink); - lsm_hook(security_path_link); - lsm_hook(security_path_rename); - lsm_hook(security_path_chmod); - lsm_hook(security_path_chown); - lsm_hook(security_path_chroot); - /* CONFIG_SECURITY_PATH */ - - /* Needed for inode based security check */ - lsm_hook(security_path_notify); - lsm_hook(security_inode_alloc); - lsm_hook(security_inode_free); - lsm_hook(security_inode_init_security); - lsm_hook(security_old_inode_init_security); - lsm_hook(security_inode_create); - lsm_hook(security_inode_link); - lsm_hook(security_inode_unlink); - lsm_hook(security_inode_symlink); - lsm_hook(security_inode_mkdir); - lsm_hook(security_inode_rmdir); - lsm_hook(security_inode_mknod); - lsm_hook(security_inode_rename); - lsm_hook(security_inode_readlink); - lsm_hook(security_inode_follow_link); - lsm_hook(security_inode_permission); - lsm_hook(security_inode_setattr); - lsm_hook(security_inode_getattr); - lsm_hook(security_inode_setxattr); - lsm_hook(security_inode_post_setxattr); - lsm_hook(security_inode_getxattr); - lsm_hook(security_inode_listxattr); - lsm_hook(security_inode_removexattr); - lsm_hook(security_inode_set_acl); - lsm_hook(security_inode_get_acl); - lsm_hook(security_inode_remove_acl); - lsm_hook(security_inode_need_killpriv); - lsm_hook(security_inode_killpriv); - lsm_hook(security_inode_getsecurity); - lsm_hook(security_inode_setsecurity); - lsm_hook(security_inode_listsecurity); - lsm_hook(security_inode_getsecid); - lsm_hook(security_inode_copy_up); - lsm_hook(security_inode_copy_up_xattr); - lsm_hook(security_kernfs_init_security); - lsm_hook(security_file_permission); - lsm_hook(security_file_alloc); - lsm_hook(security_file_free); - lsm_hook(security_file_ioctl); - lsm_hook(security_mmap_addr); - lsm_hook(security_mmap_file); - lsm_hook(security_file_mprotect); - lsm_hook(security_file_lock); - lsm_hook(security_file_fcntl); - lsm_hook(security_file_set_fowner); - lsm_hook(security_file_send_sigiotask); - lsm_hook(security_file_receive); - lsm_hook(security_file_open); - lsm_hook(security_file_truncate); - lsm_hook(security_task_alloc); - lsm_hook(security_task_free); - lsm_hook(security_cred_alloc_blank); - lsm_hook(security_cred_free); - lsm_hook(security_prepare_creds); - lsm_hook(security_transfer_creds); - lsm_hook(security_cred_getsecid); - lsm_hook(security_kernel_act_as); - lsm_hook(security_kernel_create_files_as); - lsm_hook(security_kernel_module_request); - lsm_hook(security_kernel_load_data); - lsm_hook(security_kernel_post_load_data); - lsm_hook(security_kernel_read_file); - lsm_hook(security_kernel_post_read_file); - lsm_hook(security_task_fix_setuid); - lsm_hook(security_task_fix_setgid); - lsm_hook(security_task_fix_setgroups); - lsm_hook(security_task_setpgid); - lsm_hook(security_task_getpgid); - lsm_hook(security_task_getsid); - lsm_hook(security_current_getsecid_subj); - lsm_hook(security_task_getsecid_obj); - lsm_hook(security_task_getsecid); - lsm_hook(security_task_setnice); - lsm_hook(security_task_setioprio); - lsm_hook(security_task_getioprio); - lsm_hook(security_task_prlimit); - lsm_hook(security_task_setrlimit); - lsm_hook(security_task_setscheduler); - lsm_hook(security_task_getscheduler); - lsm_hook(security_task_movememory); - lsm_hook(security_task_kill); - lsm_hook(security_task_prctl); - lsm_hook(security_task_to_inode); - lsm_hook(security_create_user_ns); - lsm_hook(security_ipc_permission); - lsm_hook(security_ipc_getsecid); - lsm_hook(security_msg_msg_alloc); - lsm_hook(security_msg_msg_free); - lsm_hook(security_msg_queue_alloc); - lsm_hook(security_msg_queue_free); - lsm_hook(security_msg_queue_associate); - lsm_hook(security_msg_queue_msgctl); - lsm_hook(security_msg_queue_msgsnd); - lsm_hook(security_msg_queue_msgrcv); - lsm_hook(security_shm_alloc); - lsm_hook(security_shm_free); - lsm_hook(security_shm_associate); - lsm_hook(security_shm_shmctl); - lsm_hook(security_shm_shmat); - lsm_hook(security_sem_alloc); - lsm_hook(security_sem_free); - lsm_hook(security_sem_associate); - lsm_hook(security_sem_semctl); - lsm_hook(security_sem_semop); - lsm_hook(security_d_instantiate); - lsm_hook(security_getprocattr); - lsm_hook(security_setprocattr); - lsm_hook(security_netlink_send); - lsm_hook(security_ismaclabel); - lsm_hook(security_secid_to_secctx); - lsm_hook(security_secctx_to_secid); - lsm_hook(security_release_secctx); - lsm_hook(security_inode_invalidate_secctx); - lsm_hook(security_inode_notifysecctx); - lsm_hook(security_inode_setsecctx); - lsm_hook(security_inode_getsecctx); - - // CONFIG_WATCH_QUEUE - lsm_hook(security_post_notification); - - // CONFIG_KEY_NOTIFICATIONS - lsm_hook(security_watch_key); - - // CONFIG_SECURITY_NETWORK - lsm_hook(security_unix_stream_connect); - lsm_hook(security_unix_may_send); - lsm_hook(security_socket_create); - lsm_hook(security_socket_post_create); - lsm_hook(security_socket_socketpair); - lsm_hook(security_socket_bind); - lsm_hook(security_socket_connect); - lsm_hook(security_socket_listen); - lsm_hook(security_socket_accept); - lsm_hook(security_socket_sendmsg); - lsm_hook(security_socket_recvmsg); - lsm_hook(security_socket_getsockname); - lsm_hook(security_socket_getpeername); - lsm_hook(security_socket_getsockopt); - lsm_hook(security_socket_setsockopt); - lsm_hook(security_socket_shutdown); - lsm_hook(security_sock_rcv_skb); - lsm_hook(security_socket_getpeersec_stream); - lsm_hook(security_socket_getpeersec_dgram); - lsm_hook(security_sk_alloc); - lsm_hook(security_sk_free); - lsm_hook(security_sk_clone); - lsm_hook(security_sk_classify_flow); - lsm_hook(security_req_classify_flow); - lsm_hook(security_sock_graft); - lsm_hook(security_inet_conn_request); - lsm_hook(security_inet_csk_clone); - lsm_hook(security_inet_conn_established); - lsm_hook(security_secmark_relabel_packet); - lsm_hook(security_secmark_refcount_inc); - lsm_hook(security_secmark_refcount_dec); - lsm_hook(security_tun_dev_alloc_security); - lsm_hook(security_tun_dev_free_security); - lsm_hook(security_tun_dev_create); - lsm_hook(security_tun_dev_attach_queue); - lsm_hook(security_tun_dev_attach); - lsm_hook(security_tun_dev_open); - lsm_hook(security_sctp_assoc_request); - lsm_hook(security_sctp_bind_connect); - lsm_hook(security_sctp_sk_clone); - lsm_hook(security_sctp_assoc_established); - - // CONFIG_SECURITY_INFINIBAND - lsm_hook(security_ib_pkey_access); - lsm_hook(security_ib_endport_manage_subnet); - lsm_hook(security_ib_alloc_security); - lsm_hook(security_ib_free_security); - - // CONFIG_SECURITY_NETWORK_XFRM - lsm_hook(security_xfrm_policy_alloc); - lsm_hook(security_xfrm_policy_clone); - lsm_hook(security_xfrm_policy_free); - lsm_hook(security_xfrm_policy_delete); - lsm_hook(security_xfrm_state_alloc); - lsm_hook(security_xfrm_state_alloc_acquire); - lsm_hook(security_xfrm_state_delete); - lsm_hook(security_xfrm_state_free); - lsm_hook(security_xfrm_policy_lookup); - lsm_hook(security_xfrm_state_pol_flow_match); - lsm_hook(security_xfrm_decode_session); - lsm_hook(security_skb_classify_flow); - - /* key management security hooks */ - // CONFIG_KEYS - lsm_hook(security_key_alloc); - lsm_hook(security_key_free); - lsm_hook(security_key_permission); - lsm_hook(security_key_getsecurity); - - // CONFIG_AUDIT - lsm_hook(security_audit_rule_init); - lsm_hook(security_audit_rule_known); - lsm_hook(security_audit_rule_free); - lsm_hook(security_audit_rule_match); - - // CONFIG_BPF_SYSCALL - lsm_hook(security_bpf); - lsm_hook(security_bpf_map); - lsm_hook(security_bpf_prog); - lsm_hook(security_bpf_map_alloc); - lsm_hook(security_bpf_prog_alloc); - lsm_hook(security_bpf_map_free); - lsm_hook(security_bpf_prog_free); - // CONFIG_BPF_SYSCALL - - lsm_hook(security_locked_down); - - // CONFIG_PERF_EVENTS - lsm_hook(security_perf_event_open); - lsm_hook(security_perf_event_alloc); - lsm_hook(security_perf_event_free); - lsm_hook(security_perf_event_read); - lsm_hook(security_perf_event_write); - - // CONFIG_IO_URING - lsm_hook(security_uring_override_creds); - lsm_hook(security_uring_sqpoll); - lsm_hook(security_uring_cmd); - - return 0; -} diff --git a/kernel/patch/old/security.c b/kernel/patch/old/security.c deleted file mode 100644 index 59327f82..00000000 --- a/kernel/patch/old/security.c +++ /dev/null @@ -1,589 +0,0 @@ -#include - -// -/* Security operations */ -int kfunc_def(security_binder_set_context_mgr)(const struct cred *mgr) = 0; -int kfunc_def(security_binder_transaction)(const struct cred *from, const struct cred *to) = 0; -int kfunc_def(security_binder_transfer_binder)(const struct cred *from, const struct cred *to) = 0; -int kfunc_def(security_binder_transfer_file)(const struct cred *from, const struct cred *to, struct file *file) = 0; -int kfunc_def(security_ptrace_access_check)(struct task_struct *child, unsigned int mode) = 0; -int kfunc_def(security_ptrace_traceme)(struct task_struct *parent) = 0; -int kfunc_def(security_capget)(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, - kernel_cap_t *permitted) = 0; -int kfunc_def(security_capset)(struct cred *new, const struct cred *old, const kernel_cap_t *effective, - const kernel_cap_t *inheritable, const kernel_cap_t *permitted) = 0; -int kfunc_def(security_capable)(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts) = 0; -int kfunc_def(security_quotactl)(int cmds, int type, int id, struct super_block *sb) = 0; -int kfunc_def(security_quota_on)(struct dentry *dentry) = 0; -int kfunc_def(security_syslog)(int type) = 0; -int kfunc_def(security_settime64)(const struct timespec64 *ts, const struct timezone *tz) = 0; -int kfunc_def(security_vm_enough_memory_mm)(struct mm_struct *mm, long pages) = 0; -int kfunc_def(security_bprm_creds_for_exec)(struct linux_binprm *bprm) = 0; -int kfunc_def(security_bprm_creds_from_file)(struct linux_binprm *bprm, struct file *file) = 0; -int kfunc_def(security_bprm_check)(struct linux_binprm *bprm) = 0; -void kfunc_def(security_bprm_committing_creds)(struct linux_binprm *bprm) = 0; -void kfunc_def(security_bprm_committed_creds)(struct linux_binprm *bprm) = 0; -int kfunc_def(security_fs_context_dup)(struct fs_context *fc, struct fs_context *src_fc) = 0; -int kfunc_def(security_fs_context_parse_param)(struct fs_context *fc, struct fs_parameter *param) = 0; -int kfunc_def(security_sb_alloc)(struct super_block *sb) = 0; -void kfunc_def(security_sb_delete)(struct super_block *sb) = 0; -void kfunc_def(security_sb_free)(struct super_block *sb) = 0; -void kfunc_def(security_free_mnt_opts)(void **mnt_opts) = 0; -int kfunc_def(security_sb_eat_lsm_opts)(char *options, void **mnt_opts) = 0; -int kfunc_def(security_sb_remount)(struct super_block *sb, void *mnt_opts) = 0; -int kfunc_def(security_sb_kern_mount)(struct super_block *sb) = 0; -int kfunc_def(security_sb_show_options)(struct seq_file *m, struct super_block *sb) = 0; -int kfunc_def(security_sb_statfs)(struct dentry *dentry) = 0; -int kfunc_def(security_sb_mount)(const char *dev_name, const struct path *path, const char *type, unsigned long flags, - void *data) = 0; -int kfunc_def(security_sb_umount)(struct vfsmount *mnt, int flags) = 0; -int kfunc_def(security_sb_pivotroot)(const struct path *old_path, const struct path *new_path) = 0; -int kfunc_def(security_sb_set_mnt_opts)(struct super_block *sb, void *mnt_opts, unsigned long kern_flags, - unsigned long *set_kern_flags) = 0; -int kfunc_def(security_sb_clone_mnt_opts)(const struct super_block *oldsb, struct super_block *newsb, - unsigned long kern_flags, unsigned long *set_kern_flags) = 0; -int kfunc_def(security_add_mnt_opt)(const char *option, const char *val, int len, void **mnt_opts) = 0; -int kfunc_def(security_move_mount)(const struct path *from_path, const struct path *to_path) = 0; -int kfunc_def(security_dentry_init_security)(struct dentry *dentry, int mode, const struct qstr *name, void **ctx, - u32 *ctxlen) = 0; -int kfunc_def(security_dentry_create_files_as)(struct dentry *dentry, int mode, struct qstr *name, - const struct cred *old, struct cred *new) = 0; - -//CONFIG_SECURITY_PATH -int kfunc_def(security_path_unlink)(const struct path *dir, struct dentry *dentry) = 0; -int kfunc_def(security_path_mkdir)(const struct path *dir, struct dentry *dentry, umode_t mode) = 0; -int kfunc_def(security_path_rmdir)(const struct path *dir, struct dentry *dentry) = 0; -int kfunc_def(security_path_mknod)(const struct path *dir, struct dentry *dentry, umode_t mode, unsigned int dev) = 0; -int kfunc_def(security_path_truncate)(const struct path *path) = 0; -int kfunc_def(security_path_symlink)(const struct path *dir, struct dentry *dentry, const char *old_name) = 0; -int kfunc_def(security_path_link)(struct dentry *old_dentry, const struct path *new_dir, struct dentry *new_dentry) = 0; -int kfunc_def(security_path_rename)(const struct path *old_dir, struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry, unsigned int flags) = 0; -int kfunc_def(security_path_chmod)(const struct path *path, umode_t mode) = 0; -int kfunc_def(security_path_chown)(const struct path *path, kuid_t uid, kgid_t gid) = 0; -int kfunc_def(security_path_chroot)(const struct path *path) = 0; -/* CONFIG_SECURITY_PATH */ - -/* Needed for inode based security check */ -int kfunc_def(security_path_notify)(const struct path *path, u64 mask, unsigned int obj_type) = 0; -int kfunc_def(security_inode_alloc)(struct inode *inode) = 0; -void kfunc_def(security_inode_free)(struct inode *inode) = 0; -int kfunc_def(security_inode_init_security)(struct inode *inode, struct inode *dir, const struct qstr *qstr, - initxattrs initxattrs, void *fs_data) = 0; -int kfunc_def(security_old_inode_init_security)(struct inode *inode, struct inode *dir, const struct qstr *qstr, - const char **name, void **value, size_t *len) = 0; -int kfunc_def(security_inode_create)(struct inode *dir, struct dentry *dentry, umode_t mode) = 0; -int kfunc_def(security_inode_link)(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) = 0; -int kfunc_def(security_inode_unlink)(struct inode *dir, struct dentry *dentry) = 0; -int kfunc_def(security_inode_symlink)(struct inode *dir, struct dentry *dentry, const char *old_name) = 0; -int kfunc_def(security_inode_mkdir)(struct inode *dir, struct dentry *dentry, umode_t mode) = 0; -int kfunc_def(security_inode_rmdir)(struct inode *dir, struct dentry *dentry) = 0; -int kfunc_def(security_inode_mknod)(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) = 0; -int kfunc_def(security_inode_rename)(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, - struct dentry *new_dentry, unsigned int flags) = 0; -int kfunc_def(security_inode_readlink)(struct dentry *dentry) = 0; -int kfunc_def(security_inode_follow_link)(struct dentry *dentry, struct inode *inode, bool rcu) = 0; -int kfunc_def(security_inode_permission)(struct inode *inode, int mask) = 0; -int kfunc_def(security_inode_setattr)(struct dentry *dentry, struct iattr *attr) = 0; -int kfunc_def(security_inode_getattr)(const struct path *path) = 0; -int kfunc_def(security_inode_setxattr)(struct dentry *dentry, const char *name, const void *value, size_t size, - int flags) = 0; -void kfunc_def(security_inode_post_setxattr)(struct dentry *dentry, const char *name, const void *value, size_t size, - int flags) = 0; -int kfunc_def(security_inode_getxattr)(struct dentry *dentry, const char *name) = 0; -int kfunc_def(security_inode_listxattr)(struct dentry *dentry) = 0; -int kfunc_def(security_inode_removexattr)(struct dentry *dentry, const char *name) = 0; -int kfunc_def(security_inode_set_acl)(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name, - struct posix_acl *kacl) = 0; -int kfunc_def(security_inode_get_acl)(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name) = 0; -int kfunc_def(security_inode_remove_acl)(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name) = 0; -int kfunc_def(security_inode_need_killpriv)(struct dentry *dentry) = 0; -int kfunc_def(security_inode_killpriv)(struct dentry *dentry) = 0; -int kfunc_def(security_inode_getsecurity)(struct inode *inode, const char *name, void **buffer, bool alloc) = 0; -int kfunc_def(security_inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, - int flags) = 0; -int kfunc_def(security_inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size) = 0; -void kfunc_def(security_inode_getsecid)(struct inode *inode, u32 *secid) = 0; -int kfunc_def(security_inode_copy_up)(struct dentry *src, struct cred **new) = 0; -int kfunc_def(security_inode_copy_up_xattr)(const char *name) = 0; -int kfunc_def(security_kernfs_init_security)(struct kernfs_node *kn_dir, struct kernfs_node *kn) = 0; -int kfunc_def(security_file_permission)(struct file *file, int mask) = 0; -int kfunc_def(security_file_alloc)(struct file *file) = 0; -void kfunc_def(security_file_free)(struct file *file) = 0; -int kfunc_def(security_file_ioctl)(struct file *file, unsigned int cmd, unsigned long arg) = 0; -int kfunc_def(security_mmap_addr)(unsigned long addr) = 0; -int kfunc_def(security_mmap_file)(struct file *file, unsigned long prot, unsigned long flags) = 0; -int kfunc_def(security_file_mprotect)(struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot) = 0; -int kfunc_def(security_file_lock)(struct file *file, unsigned int cmd) = 0; -int kfunc_def(security_file_fcntl)(struct file *file, unsigned int cmd, unsigned long arg) = 0; -void kfunc_def(security_file_set_fowner)(struct file *file) = 0; -int kfunc_def(security_file_send_sigiotask)(struct task_struct *tsk, struct fown_struct *fown, int sig) = 0; -int kfunc_def(security_file_receive)(struct file *file) = 0; -// int kfunc_def(security_file_open)(struct file *file) = 0; -int kfunc_def(security_file_open)(struct file *file, const struct cred *cred) = 0; -int kfunc_def(security_file_truncate)(struct file *file) = 0; -int kfunc_def(security_task_alloc)(struct task_struct *task, unsigned long clone_flags) = 0; -void kfunc_def(security_task_free)(struct task_struct *task) = 0; -int kfunc_def(security_cred_alloc_blank)(struct cred *cred, gfp_t gfp) = 0; -void kfunc_def(security_cred_free)(struct cred *cred) = 0; -int kfunc_def(security_prepare_creds)(struct cred *new, const struct cred *old, gfp_t gfp) = 0; -void kfunc_def(security_transfer_creds)(struct cred *new, const struct cred *old) = 0; -void kfunc_def(security_cred_getsecid)(const struct cred *c, u32 *secid) = 0; -int kfunc_def(security_kernel_act_as)(struct cred *new, u32 secid) = 0; -int kfunc_def(security_kernel_create_files_as)(struct cred *new, struct inode *inode) = 0; -int kfunc_def(security_kernel_module_request)(char *kmod_name) = 0; -int kfunc_def(security_kernel_load_data)(enum kernel_load_data_id id, bool contents) = 0; -int kfunc_def(security_kernel_post_load_data)(char *buf, loff_t size, enum kernel_load_data_id id, - char *description) = 0; -int kfunc_def(security_kernel_read_file)(struct file *file, enum kernel_read_file_id id, bool contents) = 0; -int kfunc_def(security_kernel_post_read_file)(struct file *file, char *buf, loff_t size, - enum kernel_read_file_id id) = 0; -int kfunc_def(security_task_fix_setuid)(struct cred *new, const struct cred *old, int flags) = 0; -int kfunc_def(security_task_fix_setgid)(struct cred *new, const struct cred *old, int flags) = 0; -int kfunc_def(security_task_fix_setgroups)(struct cred *new, const struct cred *old) = 0; -int kfunc_def(security_task_setpgid)(struct task_struct *p, pid_t pgid) = 0; -int kfunc_def(security_task_getpgid)(struct task_struct *p) = 0; -int kfunc_def(security_task_getsid)(struct task_struct *p) = 0; - -void kfunc_def(security_current_getsecid_subj)(u32 *secid); // 5.10 -void kfunc_def(security_task_getsecid_obj)(struct task_struct *p, u32 *secid); // ?-6.3 -void kfunc_def(security_task_getsecid)(struct task_struct *p, u32 *secid); // 4.4-5.10 - -int kfunc_def(security_task_setnice)(struct task_struct *p, int nice) = 0; -int kfunc_def(security_task_setioprio)(struct task_struct *p, int ioprio) = 0; -int kfunc_def(security_task_getioprio)(struct task_struct *p) = 0; -int kfunc_def(security_task_prlimit)(const struct cred *cred, const struct cred *tcred, unsigned int flags) = 0; -int kfunc_def(security_task_setrlimit)(struct task_struct *p, unsigned int resource, struct rlimit *new_rlim) = 0; -int kfunc_def(security_task_setscheduler)(struct task_struct *p) = 0; -int kfunc_def(security_task_getscheduler)(struct task_struct *p) = 0; -int kfunc_def(security_task_movememory)(struct task_struct *p) = 0; -int kfunc_def(security_task_kill)(struct task_struct *p, struct kernel_siginfo *info, int sig, - const struct cred *cred) = 0; -int kfunc_def(security_task_prctl)(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, - unsigned long arg5) = 0; -void kfunc_def(security_task_to_inode)(struct task_struct *p, struct inode *inode) = 0; -int kfunc_def(security_create_user_ns)(const struct cred *cred) = 0; -int kfunc_def(security_ipc_permission)(struct kern_ipc_perm *ipcp, short flag) = 0; -void kfunc_def(security_ipc_getsecid)(struct kern_ipc_perm *ipcp, u32 *secid) = 0; -int kfunc_def(security_msg_msg_alloc)(struct msg_msg *msg) = 0; -void kfunc_def(security_msg_msg_free)(struct msg_msg *msg) = 0; -int kfunc_def(security_msg_queue_alloc)(struct kern_ipc_perm *msq) = 0; -void kfunc_def(security_msg_queue_free)(struct kern_ipc_perm *msq) = 0; -int kfunc_def(security_msg_queue_associate)(struct kern_ipc_perm *msq, int msqflg) = 0; -int kfunc_def(security_msg_queue_msgctl)(struct kern_ipc_perm *msq, int cmd) = 0; -int kfunc_def(security_msg_queue_msgsnd)(struct kern_ipc_perm *msq, struct msg_msg *msg, int msqflg) = 0; -int kfunc_def(security_msg_queue_msgrcv)(struct kern_ipc_perm *msq, struct msg_msg *msg, struct task_struct *target, - long type, int mode) = 0; -int kfunc_def(security_shm_alloc)(struct kern_ipc_perm *shp) = 0; -void kfunc_def(security_shm_free)(struct kern_ipc_perm *shp) = 0; -int kfunc_def(security_shm_associate)(struct kern_ipc_perm *shp, int shmflg) = 0; -int kfunc_def(security_shm_shmctl)(struct kern_ipc_perm *shp, int cmd) = 0; -int kfunc_def(security_shm_shmat)(struct kern_ipc_perm *shp, char __user *shmaddr, int shmflg) = 0; -int kfunc_def(security_sem_alloc)(struct kern_ipc_perm *sma) = 0; -void kfunc_def(security_sem_free)(struct kern_ipc_perm *sma) = 0; -int kfunc_def(security_sem_associate)(struct kern_ipc_perm *sma, int semflg) = 0; -int kfunc_def(security_sem_semctl)(struct kern_ipc_perm *sma, int cmd) = 0; -int kfunc_def(security_sem_semop)(struct kern_ipc_perm *sma, struct sembuf *sops, unsigned nsops, int alter) = 0; -void kfunc_def(security_d_instantiate)(struct dentry *dentry, struct inode *inode) = 0; -int kfunc_def(security_getprocattr)(struct task_struct *p, const char *lsm, char *name, char **value) = 0; -int kfunc_def(security_setprocattr)(const char *lsm, const char *name, void *value, size_t size) = 0; -int kfunc_def(security_netlink_send)(struct sock *sk, struct sk_buff *skb) = 0; -int kfunc_def(security_ismaclabel)(const char *name) = 0; -int kfunc_def(security_secid_to_secctx)(u32 secid, char **secdata, u32 *seclen) = 0; -int kfunc_def(security_secctx_to_secid)(const char *secdata, u32 seclen, u32 *secid) = 0; -void kfunc_def(security_release_secctx)(char *secdata, u32 seclen) = 0; -void kfunc_def(security_inode_invalidate_secctx)(struct inode *inode) = 0; -int kfunc_def(security_inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen) = 0; -int kfunc_def(security_inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen) = 0; -int kfunc_def(security_inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen) = 0; - -// CONFIG_WATCH_QUEUE -int kfunc_def(security_post_notification)(const struct cred *w_cred, const struct cred *cred, - struct watch_notification *n) = 0; - -// CONFIG_KEY_NOTIFICATIONS -int kfunc_def(security_watch_key)(struct key *key) = 0; - -// CONFIG_SECURITY_NETWORK -int kfunc_def(security_unix_stream_connect)(struct sock *sock, struct sock *other, struct sock *newsk) = 0; -int kfunc_def(security_unix_may_send)(struct socket *sock, struct socket *other) = 0; -int kfunc_def(security_socket_create)(int family, int type, int protocol, int kern) = 0; -int kfunc_def(security_socket_post_create)(struct socket *sock, int family, int type, int protocol, int kern) = 0; -int kfunc_def(security_socket_socketpair)(struct socket *socka, struct socket *sockb) = 0; -int kfunc_def(security_socket_bind)(struct socket *sock, struct sockaddr *address, int addrlen) = 0; -int kfunc_def(security_socket_connect)(struct socket *sock, struct sockaddr *address, int addrlen) = 0; -int kfunc_def(security_socket_listen)(struct socket *sock, int backlog) = 0; -int kfunc_def(security_socket_accept)(struct socket *sock, struct socket *newsock) = 0; -int kfunc_def(security_socket_sendmsg)(struct socket *sock, struct msghdr *msg, int size) = 0; -int kfunc_def(security_socket_recvmsg)(struct socket *sock, struct msghdr *msg, int size, int flags) = 0; -int kfunc_def(security_socket_getsockname)(struct socket *sock) = 0; -int kfunc_def(security_socket_getpeername)(struct socket *sock) = 0; -int kfunc_def(security_socket_getsockopt)(struct socket *sock, int level, int optname) = 0; -int kfunc_def(security_socket_setsockopt)(struct socket *sock, int level, int optname) = 0; -int kfunc_def(security_socket_shutdown)(struct socket *sock, int how) = 0; -int kfunc_def(security_sock_rcv_skb)(struct sock *sk, struct sk_buff *skb) = 0; -int kfunc_def(security_socket_getpeersec_stream)(struct socket *sock, sockptr_t optval, sockptr_t optlen, - unsigned int len) = 0; -int kfunc_def(security_socket_getpeersec_dgram)(struct socket *sock, struct sk_buff *skb, u32 *secid) = 0; -int kfunc_def(security_sk_alloc)(struct sock *sk, int family, gfp_t priority) = 0; -void kfunc_def(security_sk_free)(struct sock *sk) = 0; -void kfunc_def(security_sk_clone)(const struct sock *sk, struct sock *newsk) = 0; -void kfunc_def(security_sk_classify_flow)(struct sock *sk, struct flowi_common *flic) = 0; -void kfunc_def(security_req_classify_flow)(const struct request_sock *req, struct flowi_common *flic) = 0; -void kfunc_def(security_sock_graft)(struct sock *sk, struct socket *parent) = 0; -int kfunc_def(security_inet_conn_request)(const struct sock *sk, struct sk_buff *skb, struct request_sock *req) = 0; -void kfunc_def(security_inet_csk_clone)(struct sock *newsk, const struct request_sock *req) = 0; -void kfunc_def(security_inet_conn_established)(struct sock *sk, struct sk_buff *skb) = 0; -int kfunc_def(security_secmark_relabel_packet)(u32 secid) = 0; -void kfunc_def(security_secmark_refcount_inc)(void) = 0; -void kfunc_def(security_secmark_refcount_dec)(void) = 0; -int kfunc_def(security_tun_dev_alloc_security)(void **security) = 0; -void kfunc_def(security_tun_dev_free_security)(void *security) = 0; -int kfunc_def(security_tun_dev_create)(void) = 0; -int kfunc_def(security_tun_dev_attach_queue)(void *security) = 0; -int kfunc_def(security_tun_dev_attach)(struct sock *sk, void *security) = 0; -int kfunc_def(security_tun_dev_open)(void *security) = 0; -int kfunc_def(security_sctp_assoc_request)(struct sctp_association *asoc, struct sk_buff *skb) = 0; -int kfunc_def(security_sctp_bind_connect)(struct sock *sk, int optname, struct sockaddr *address, int addrlen) = 0; -void kfunc_def(security_sctp_sk_clone)(struct sctp_association *asoc, struct sock *sk, struct sock *newsk) = 0; -int kfunc_def(security_sctp_assoc_established)(struct sctp_association *asoc, struct sk_buff *skb) = 0; - -// CONFIG_SECURITY_INFINIBAND -int kfunc_def(security_ib_pkey_access)(void *sec, u64 subnet_prefix, u16 pkey) = 0; -int kfunc_def(security_ib_endport_manage_subnet)(void *sec, const char *dev_name, u8 port_num) = 0; -int kfunc_def(security_ib_alloc_security)(void **sec) = 0; -void kfunc_def(security_ib_free_security)(void *sec) = 0; - -// CONFIG_SECURITY_NETWORK_XFRM -int kfunc_def(security_xfrm_policy_alloc)(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx, gfp_t gfp) = 0; -int kfunc_def(security_xfrm_policy_clone)(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp) = 0; -void kfunc_def(security_xfrm_policy_free)(struct xfrm_sec_ctx *ctx) = 0; -int kfunc_def(security_xfrm_policy_delete)(struct xfrm_sec_ctx *ctx) = 0; -int kfunc_def(security_xfrm_state_alloc)(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) = 0; -int kfunc_def(security_xfrm_state_alloc_acquire)(struct xfrm_state *x, struct xfrm_sec_ctx *polsec, u32 secid) = 0; -int kfunc_def(security_xfrm_state_delete)(struct xfrm_state *x) = 0; -void kfunc_def(security_xfrm_state_free)(struct xfrm_state *x) = 0; -int kfunc_def(security_xfrm_policy_lookup)(struct xfrm_sec_ctx *ctx, u32 fl_secid) = 0; -int kfunc_def(security_xfrm_state_pol_flow_match)(struct xfrm_state *x, struct xfrm_policy *xp, - const struct flowi_common *flic) = 0; -int kfunc_def(security_xfrm_decode_session)(struct sk_buff *skb, u32 *secid) = 0; -void kfunc_def(security_skb_classify_flow)(struct sk_buff *skb, struct flowi_common *flic) = 0; - -/* key management security hooks */ -// CONFIG_KEYS -typedef void *key_ref_t; -int kfunc_def(security_key_alloc)(struct key *key, const struct cred *cred, unsigned long flags) = 0; -void kfunc_def(security_key_free)(struct key *key) = 0; -int kfunc_def(security_key_permission)(key_ref_t key_ref, const struct cred *cred, enum key_need_perm need_perm) = 0; -int kfunc_def(security_key_getsecurity)(struct key *key, char **_buffer) = 0; - -// CONFIG_AUDIT -int kfunc_def(security_audit_rule_init)(u32 field, u32 op, char *rulestr, void **lsmrule) = 0; -int kfunc_def(security_audit_rule_known)(struct audit_krule *krule) = 0; -void kfunc_def(security_audit_rule_free)(void *lsmrule) = 0; -int kfunc_def(security_audit_rule_match)(u32 secid, u32 field, u32 op, void *lsmrule) = 0; - -// CONFIG_BPF_SYSCALL -int kfunc_def(security_bpf)(int cmd, union bpf_attr *attr, unsigned int size) = 0; -int kfunc_def(security_bpf_map)(struct bpf_map *map, fmode_t fmode) = 0; -int kfunc_def(security_bpf_prog)(struct bpf_prog *prog) = 0; -int kfunc_def(security_bpf_map_alloc)(struct bpf_map *map) = 0; -int kfunc_def(security_bpf_prog_alloc)(struct bpf_prog_aux *aux) = 0; -void kfunc_def(security_bpf_map_free)(struct bpf_map *map) = 0; -void kfunc_def(security_bpf_prog_free)(struct bpf_prog_aux *aux) = 0; -// CONFIG_BPF_SYSCALL - -int kfunc_def(security_locked_down)(enum lockdown_reason what) = 0; - -// CONFIG_PERF_EVENTS -int kfunc_def(security_perf_event_open)(struct perf_event_attr *attr, int type) = 0; -int kfunc_def(security_perf_event_alloc)(struct perf_event *event) = 0; -void kfunc_def(security_perf_event_free)(struct perf_event *event) = 0; -int kfunc_def(security_perf_event_read)(struct perf_event *event) = 0; -int kfunc_def(security_perf_event_write)(struct perf_event *event) = 0; - -// CONFIG_IO_URING -int kfunc_def(security_uring_override_creds)(const struct cred *new) = 0; -int kfunc_def(security_uring_sqpoll)(void) = 0; -int kfunc_def(security_uring_cmd)(struct io_uring_cmd *ioucmd) = 0; - -void _linux_security_security_sym_match(const char *name, unsigned long addr) -{ - // kfunc_match(security_binder_set_context_mgr, name, addr); - // kfunc_match(security_binder_transaction, name, addr); - // kfunc_match(security_binder_transfer_binder, name, addr); - // kfunc_match(security_binder_transfer_file, name, addr); - // kfunc_match(security_ptrace_access_check, name, addr); - // kfunc_match(security_ptrace_traceme, name, addr); - // kfunc_match(security_capget, name, addr); - // kfunc_match(security_capset, name, addr); - // kfunc_match(security_capable, name, addr); - // kfunc_match(security_quotactl, name, addr); - // kfunc_match(security_quota_on, name, addr); - // kfunc_match(security_syslog, name, addr); - // kfunc_match(security_settime64, name, addr); - // kfunc_match(security_vm_enough_memory_mm, name, addr); - // kfunc_match(security_bprm_creds_for_exec, name, addr); - // kfunc_match(security_bprm_creds_from_file, name, addr); - // kfunc_match(security_bprm_check, name, addr); - // kfunc_match(security_bprm_committing_creds, name, addr); - // kfunc_match(security_bprm_committed_creds, name, addr); - // kfunc_match(security_fs_context_dup, name, addr); - // kfunc_match(security_fs_context_parse_param, name, addr); - // kfunc_match(security_sb_alloc, name, addr); - // kfunc_match(security_sb_delete, name, addr); - // kfunc_match(security_sb_free, name, addr); - // kfunc_match(security_free_mnt_opts, name, addr); - // kfunc_match(security_sb_eat_lsm_opts, name, addr); - // kfunc_match(security_sb_remount, name, addr); - // kfunc_match(security_sb_kern_mount, name, addr); - // kfunc_match(security_sb_show_options, name, addr); - // kfunc_match(security_sb_statfs, name, addr); - // kfunc_match(security_sb_mount, name, addr); - // kfunc_match(security_sb_umount, name, addr); - // kfunc_match(security_sb_pivotroot, name, addr); - // kfunc_match(security_sb_set_mnt_opts, name, addr); - // kfunc_match(security_sb_clone_mnt_opts, name, addr); - // kfunc_match(security_add_mnt_opt, name, addr); - // kfunc_match(security_move_mount, name, addr); - // kfunc_match(security_dentry_init_security, name, addr); - // kfunc_match(security_dentry_create_files_as, name, addr); - - // //CONFIG_SECURITY_PATH - // kfunc_match(security_path_unlink, name, addr); - // kfunc_match(security_path_mkdir, name, addr); - // kfunc_match(security_path_rmdir, name, addr); - // kfunc_match(security_path_mknod, name, addr); - // kfunc_match(security_path_truncate, name, addr); - // kfunc_match(security_path_symlink, name, addr); - // kfunc_match(security_path_link, name, addr); - // kfunc_match(security_path_rename, name, addr); - // kfunc_match(security_path_chmod, name, addr); - // kfunc_match(security_path_chown, name, addr); - // kfunc_match(security_path_chroot, name, addr); - // /* CONFIG_SECURITY_PATH */ - - // /* Needed for inode based security check */ - // kfunc_match(security_path_notify, name, addr); - // kfunc_match(security_inode_alloc, name, addr); - // kfunc_match(security_inode_free, name, addr); - // kfunc_match(security_inode_init_security, name, addr); - // kfunc_match(security_old_inode_init_security, name, addr); - // kfunc_match(security_inode_create, name, addr); - // kfunc_match(security_inode_link, name, addr); - // kfunc_match(security_inode_unlink, name, addr); - // kfunc_match(security_inode_symlink, name, addr); - // kfunc_match(security_inode_mkdir, name, addr); - // kfunc_match(security_inode_rmdir, name, addr); - // kfunc_match(security_inode_mknod, name, addr); - // kfunc_match(security_inode_rename, name, addr); - // kfunc_match(security_inode_readlink, name, addr); - // kfunc_match(security_inode_follow_link, name, addr); - // kfunc_match(security_inode_permission, name, addr); - // kfunc_match(security_inode_setattr, name, addr); - // kfunc_match(security_inode_getattr, name, addr); - // kfunc_match(security_inode_setxattr, name, addr); - // kfunc_match(security_inode_post_setxattr, name, addr); - // kfunc_match(security_inode_getxattr, name, addr); - // kfunc_match(security_inode_listxattr, name, addr); - // kfunc_match(security_inode_removexattr, name, addr); - // kfunc_match(security_inode_set_acl, name, addr); - // kfunc_match(security_inode_get_acl, name, addr); - // kfunc_match(security_inode_remove_acl, name, addr); - // kfunc_match(security_inode_need_killpriv, name, addr); - // kfunc_match(security_inode_killpriv, name, addr); - // kfunc_match(security_inode_getsecurity, name, addr); - // kfunc_match(security_inode_setsecurity, name, addr); - // kfunc_match(security_inode_listsecurity, name, addr); - // kfunc_match(security_inode_getsecid, name, addr); - // kfunc_match(security_inode_copy_up, name, addr); - // kfunc_match(security_inode_copy_up_xattr, name, addr); - // kfunc_match(security_kernfs_init_security, name, addr); - // kfunc_match(security_file_permission, name, addr); - // kfunc_match(security_file_alloc, name, addr); - // kfunc_match(security_file_free, name, addr); - // kfunc_match(security_file_ioctl, name, addr); - // kfunc_match(security_mmap_addr, name, addr); - // kfunc_match(security_mmap_file, name, addr); - // kfunc_match(security_file_mprotect, name, addr); - // kfunc_match(security_file_lock, name, addr); - // kfunc_match(security_file_fcntl, name, addr); - // kfunc_match(security_file_set_fowner, name, addr); - // kfunc_match(security_file_send_sigiotask, name, addr); - // kfunc_match(security_file_receive, name, addr); - // kfunc_match(security_file_open, name, addr); - // kfunc_match(security_file_truncate, name, addr); - // kfunc_match(security_task_alloc, name, addr); - // kfunc_match(security_task_free, name, addr); - // kfunc_match(security_cred_alloc_blank, name, addr); - // kfunc_match(security_cred_free, name, addr); - // kfunc_match(security_prepare_creds, name, addr); - // kfunc_match(security_transfer_creds, name, addr); - kfunc_match(security_cred_getsecid, name, addr); - // kfunc_match(security_kernel_act_as, name, addr); - // kfunc_match(security_kernel_create_files_as, name, addr); - // kfunc_match(security_kernel_module_request, name, addr); - // kfunc_match(security_kernel_load_data, name, addr); - // kfunc_match(security_kernel_post_load_data, name, addr); - // kfunc_match(security_kernel_read_file, name, addr); - // kfunc_match(security_kernel_post_read_file, name, addr); - // kfunc_match(security_task_fix_setuid, name, addr); - // kfunc_match(security_task_fix_setgid, name, addr); - // kfunc_match(security_task_fix_setgroups, name, addr); - // kfunc_match(security_task_setpgid, name, addr); - // kfunc_match(security_task_getpgid, name, addr); - // kfunc_match(security_task_getsid, name, addr); - // kfunc_match(security_current_getsecid_subj, name, addr); - // kfunc_match(security_task_getsecid_obj, name, addr); - // kfunc_match(security_task_getsecid, name, addr); - // kfunc_match(security_task_setnice, name, addr); - // kfunc_match(security_task_setioprio, name, addr); - // kfunc_match(security_task_getioprio, name, addr); - // kfunc_match(security_task_prlimit, name, addr); - // kfunc_match(security_task_setrlimit, name, addr); - // kfunc_match(security_task_setscheduler, name, addr); - // kfunc_match(security_task_getscheduler, name, addr); - // kfunc_match(security_task_movememory, name, addr); - // kfunc_match(security_task_kill, name, addr); - // kfunc_match(security_task_prctl, name, addr); - // kfunc_match(security_task_to_inode, name, addr); - // kfunc_match(security_create_user_ns, name, addr); - // kfunc_match(security_ipc_permission, name, addr); - // kfunc_match(security_ipc_getsecid, name, addr); - // kfunc_match(security_msg_msg_alloc, name, addr); - // kfunc_match(security_msg_msg_free, name, addr); - // kfunc_match(security_msg_queue_alloc, name, addr); - // kfunc_match(security_msg_queue_free, name, addr); - // kfunc_match(security_msg_queue_associate, name, addr); - // kfunc_match(security_msg_queue_msgctl, name, addr); - // kfunc_match(security_msg_queue_msgsnd, name, addr); - // kfunc_match(security_msg_queue_msgrcv, name, addr); - // kfunc_match(security_shm_alloc, name, addr); - // kfunc_match(security_shm_free, name, addr); - // kfunc_match(security_shm_associate, name, addr); - // kfunc_match(security_shm_shmctl, name, addr); - // kfunc_match(security_shm_shmat, name, addr); - // kfunc_match(security_sem_alloc, name, addr); - // kfunc_match(security_sem_free, name, addr); - // kfunc_match(security_sem_associate, name, addr); - // kfunc_match(security_sem_semctl, name, addr); - // kfunc_match(security_sem_semop, name, addr); - // kfunc_match(security_d_instantiate, name, addr); - // kfunc_match(security_getprocattr, name, addr); - // kfunc_match(security_setprocattr, name, addr); - // kfunc_match(security_netlink_send, name, addr); - // kfunc_match(security_ismaclabel, name, addr); - // kfunc_match(security_secid_to_secctx, name, addr); - // kfunc_match(security_secctx_to_secid, name, addr); - // kfunc_match(security_release_secctx, name, addr); - // kfunc_match(security_inode_invalidate_secctx, name, addr); - // kfunc_match(security_inode_notifysecctx, name, addr); - // kfunc_match(security_inode_setsecctx, name, addr); - // kfunc_match(security_inode_getsecctx, name, addr); - - // // CONFIG_WATCH_QUEUE - // kfunc_match(security_post_notification, name, addr); - - // // CONFIG_KEY_NOTIFICATIONS - // kfunc_match(security_watch_key, name, addr); - - // // CONFIG_SECURITY_NETWORK - // kfunc_match(security_unix_stream_connect, name, addr); - // kfunc_match(security_unix_may_send, name, addr); - // kfunc_match(security_socket_create, name, addr); - // kfunc_match(security_socket_post_create, name, addr); - // kfunc_match(security_socket_socketpair, name, addr); - // kfunc_match(security_socket_bind, name, addr); - // kfunc_match(security_socket_connect, name, addr); - // kfunc_match(security_socket_listen, name, addr); - // kfunc_match(security_socket_accept, name, addr); - // kfunc_match(security_socket_sendmsg, name, addr); - // kfunc_match(security_socket_recvmsg, name, addr); - // kfunc_match(security_socket_getsockname, name, addr); - // kfunc_match(security_socket_getpeername, name, addr); - // kfunc_match(security_socket_getsockopt, name, addr); - // kfunc_match(security_socket_setsockopt, name, addr); - // kfunc_match(security_socket_shutdown, name, addr); - // kfunc_match(security_sock_rcv_skb, name, addr); - // kfunc_match(security_socket_getpeersec_stream, name, addr); - // kfunc_match(security_socket_getpeersec_dgram, name, addr); - // kfunc_match(security_sk_alloc, name, addr); - // kfunc_match(security_sk_free, name, addr); - // kfunc_match(security_sk_clone, name, addr); - // kfunc_match(security_sk_classify_flow, name, addr); - // kfunc_match(security_req_classify_flow, name, addr); - // kfunc_match(security_sock_graft, name, addr); - // kfunc_match(security_inet_conn_request, name, addr); - // kfunc_match(security_inet_csk_clone, name, addr); - // kfunc_match(security_inet_conn_established, name, addr); - // kfunc_match(security_secmark_relabel_packet, name, addr); - // kfunc_match(security_secmark_refcount_inc, name, addr); - // kfunc_match(security_secmark_refcount_dec, name, addr); - // kfunc_match(security_tun_dev_alloc_security, name, addr); - // kfunc_match(security_tun_dev_free_security, name, addr); - // kfunc_match(security_tun_dev_create, name, addr); - // kfunc_match(security_tun_dev_attach_queue, name, addr); - // kfunc_match(security_tun_dev_attach, name, addr); - // kfunc_match(security_tun_dev_open, name, addr); - // kfunc_match(security_sctp_assoc_request, name, addr); - // kfunc_match(security_sctp_bind_connect, name, addr); - // kfunc_match(security_sctp_sk_clone, name, addr); - // kfunc_match(security_sctp_assoc_established, name, addr); - - // // CONFIG_SECURITY_INFINIBAND - // kfunc_match(security_ib_pkey_access, name, addr); - // kfunc_match(security_ib_endport_manage_subnet, name, addr); - // kfunc_match(security_ib_alloc_security, name, addr); - // kfunc_match(security_ib_free_security, name, addr); - - // // CONFIG_SECURITY_NETWORK_XFRM - // kfunc_match(security_xfrm_policy_alloc, name, addr); - // kfunc_match(security_xfrm_policy_clone, name, addr); - // kfunc_match(security_xfrm_policy_free, name, addr); - // kfunc_match(security_xfrm_policy_delete, name, addr); - // kfunc_match(security_xfrm_state_alloc, name, addr); - // kfunc_match(security_xfrm_state_alloc_acquire, name, addr); - // kfunc_match(security_xfrm_state_delete, name, addr); - // kfunc_match(security_xfrm_state_free, name, addr); - // kfunc_match(security_xfrm_policy_lookup, name, addr); - // kfunc_match(security_xfrm_state_pol_flow_match, name, addr); - // kfunc_match(security_xfrm_decode_session, name, addr); - // kfunc_match(security_skb_classify_flow, name, addr); - - // /* key management security hooks */ - // // CONFIG_KEYS - // kfunc_match(security_key_alloc, name, addr); - // kfunc_match(security_key_free, name, addr); - // kfunc_match(security_key_permission, name, addr); - // kfunc_match(security_key_getsecurity, name, addr); - - // // CONFIG_AUDIT - // kfunc_match(security_audit_rule_init, name, addr); - // kfunc_match(security_audit_rule_known, name, addr); - // kfunc_match(security_audit_rule_free, name, addr); - // kfunc_match(security_audit_rule_match, name, addr); - - // // CONFIG_BPF_SYSCALL - // kfunc_match(security_bpf, name, addr); - // kfunc_match(security_bpf_map, name, addr); - // kfunc_match(security_bpf_prog, name, addr); - // kfunc_match(security_bpf_map_alloc, name, addr); - // kfunc_match(security_bpf_prog_alloc, name, addr); - // kfunc_match(security_bpf_map_free, name, addr); - // kfunc_match(security_bpf_prog_free, name, addr); - // // CONFIG_BPF_SYSCALL - - // kfunc_match(security_locked_down, name, addr); - - // // CONFIG_PERF_EVENTS - // kfunc_match(security_perf_event_open, name, addr); - // kfunc_match(security_perf_event_alloc, name, addr); - // kfunc_match(security_perf_event_free, name, addr); - // kfunc_match(security_perf_event_read, name, addr); - // kfunc_match(security_perf_event_write, name, addr); - - // // CONFIG_IO_URING - // kfunc_match(security_uring_override_creds, name, addr); - // kfunc_match(security_uring_sqpoll, name, addr); - // kfunc_match(security_uring_cmd, name, addr); -} diff --git a/kernel/patch/old/selinux.c b/kernel/patch/old/selinux.c deleted file mode 100644 index 3002b4c2..00000000 --- a/kernel/patch/old/selinux.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include - -#include -#include - -int kvar_def(selinux_enabled_boot) = 0; -int kvar_def(selinux_enabled) = 0; -struct selinux_state kvar_def(selinux_state) = 0; -struct security_class_mapping kvar_def(secclass_map)[] = 0; - -int kfunc_def(security_mls_enabled)(void) = 0; -int kfunc_def(security_load_policy)(void *data, size_t len, struct selinux_load_state *load_state) = 0; -void kfunc_def(selinux_policy_commit)(struct selinux_load_state *load_state) = 0; -void kfunc_def(selinux_policy_cancel)(struct selinux_load_state *load_state) = 0; -int kfunc_def(security_read_policy)(void **data, size_t *len) = 0; -int kfunc_def(security_read_state_kernel)(void **data, size_t *len) = 0; -int kfunc_def(security_policycap_supported)(unsigned int req_cap) = 0; -void kfunc_def(security_compute_av)(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd, - struct extended_perms *xperms) = 0; -void kfunc_def(security_compute_xperms_decision)(u32 ssid, u32 tsid, u16 tclass, u8 driver, - struct extended_perms_decision *xpermd) = 0; -void kfunc_def(security_compute_av_user)(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd) = 0; -int kfunc_def(security_transition_sid)(u32 ssid, u32 tsid, u16 tclass, const struct qstr *qstr, u32 *out_sid) = 0; -int kfunc_def(security_transition_sid_user)(u32 ssid, u32 tsid, u16 tclass, const char *objname, u32 *out_sid) = 0; -int kfunc_def(security_member_sid)(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) = 0; -int kfunc_def(security_change_sid)(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) = 0; -int kfunc_def(security_sid_to_context)(u32 sid, char **scontext, u32 *scontext_len) = 0; -int kfunc_def(security_sid_to_context_force)(u32 sid, char **scontext, u32 *scontext_len) = 0; -int kfunc_def(security_sid_to_context_inval)(u32 sid, char **scontext, u32 *scontext_len) = 0; -int kfunc_def(security_context_to_sid)(const char *scontext, u32 scontext_len, u32 *out_sid, gfp_t gfp) = 0; -int kfunc_def(security_context_str_to_sid)(const char *scontext, u32 *out_sid, gfp_t gfp) = 0; -int kfunc_def(security_context_to_sid_default)(const char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid, - gfp_t gfp_flags) = 0; -int kfunc_def(security_context_to_sid_force)(const char *scontext, u32 scontext_len, u32 *sid) = 0; -int kfunc_def(security_get_user_sids)(u32 callsid, char *username, u32 **sids, u32 *nel) = 0; -int kfunc_def(security_port_sid)(u8 protocol, u16 port, u32 *out_sid) = 0; -int kfunc_def(security_ib_pkey_sid)(u64 subnet_prefix, u16 pkey_num, u32 *out_sid) = 0; -int kfunc_def(security_ib_endport_sid)(const char *dev_name, u8 port_num, u32 *out_sid) = 0; -int kfunc_def(security_netif_sid)(char *name, u32 *if_sid) = 0; -int kfunc_def(security_node_sid)(u16 domain, void *addr, u32 addrlen, u32 *out_sid) = 0; -int kfunc_def(security_validate_transition)(u32 oldsid, u32 newsid, u32 tasksid, u16 tclass) = 0; -int kfunc_def(security_validate_transition_user)(u32 oldsid, u32 newsid, u32 tasksid, u16 tclass) = 0; -int kfunc_def(security_bounded_transition)(u32 oldsid, u32 newsid) = 0; -int kfunc_def(security_sid_mls_copy)(u32 sid, u32 mls_sid, u32 *new_sid) = 0; -int kfunc_def(security_net_peersid_resolve)(u32 nlbl_sid, u32 nlbl_type, u32 xfrm_sid, u32 *peer_sid) = 0; -int kfunc_def(security_get_classes)(struct selinux_policy *policy, char ***classes, int *nclasses) = 0; -int kfunc_def(security_get_permissions)(struct selinux_policy *policy, char *class, char ***perms, int *nperms) = 0; -int kfunc_def(security_get_reject_unknown)(void) = 0; -int kfunc_def(security_get_allow_unknown)(void) = 0; - -int kfunc_def(security_fs_use)(struct super_block *sb) = 0; -int kfunc_def(security_genfs_sid)(const char *fstype, const char *path, u16 sclass, u32 *sid) = 0; -int kfunc_def(selinux_policy_genfs_sid)(struct selinux_policy *policy, const char *fstype, const char *path, u16 sclass, - u32 *sid) = 0; -int kfunc_def(security_netlbl_secattr_to_sid)(struct netlbl_lsm_secattr *secattr, u32 *sid) = 0; -int kfunc_def(security_netlbl_sid_to_secattr)(u32 sid, struct netlbl_lsm_secattr *secattr) = 0; -const char *kfunc_def(security_get_initial_sid_context)(u32 sid) = 0; - -void kfunc_def(selinux_status_update_setenforce)(int enforcing) = 0; -void kfunc_def(selinux_status_update_policyload)(int seqno) = 0; -void kfunc_def(selinux_complete_init)(void) = 0; -void kfunc_def(exit_sel_fs)(void) = 0; -void kfunc_def(selnl_notify_setenforce)(int val) = 0; -void kfunc_def(selnl_notify_policyload)(u32 seqno) = 0; -int kfunc_def(selinux_nlmsg_lookup)(u16 sclass, u16 nlmsg_type, u32 *perm) = 0; - -void kfunc_def(avtab_cache_init)(void) = 0; -void kfunc_def(ebitmap_cache_init)(void) = 0; -void kfunc_def(hashtab_cache_init)(void) = 0; -int kfunc_def(security_sidtab_hash_stats)(char *page) = 0; - -void _linux_security_selinux_sym_match(const char *name, unsigned long addr) -{ - // kvar_match(selinux_enabled_boot, name, addr); - // kvar_match(selinux_enabled, name, addr); - // kvar_match(selinux_state, name, addr); - // kvar_match(secclass_map, name, addr); - - // kfunc_match(security_mls_enabled, name, addr); - // kfunc_match(security_load_policy, name, addr); - // kfunc_match(selinux_policy_commit, name, addr); - // kfunc_match(selinux_policy_cancel, name, addr); - // kfunc_match(security_read_policy, name, addr); - // kfunc_match(security_read_state_kernel, name, addr); - // kfunc_match(security_policycap_supported, name, addr); - // kfunc_match(security_compute_av, name, addr); - // kfunc_match(security_compute_xperms_decision, name, addr); - // kfunc_match(security_compute_av_user, name, addr); - // kfunc_match(security_transition_sid, name, addr); - // kfunc_match(security_transition_sid_user, name, addr); - // kfunc_match(security_member_sid, name, addr); - // kfunc_match(security_change_sid, name, addr); - // kfunc_match(security_sid_to_context, name, addr); - // kfunc_match(security_sid_to_context_force, name, addr); - // kfunc_match(security_sid_to_context_inval, name, addr); - // kfunc_match(security_context_to_sid, name, addr); - // kfunc_match(security_context_str_to_sid, name, addr); - // kfunc_match(security_context_to_sid_default, name, addr); - // kfunc_match(security_context_to_sid_force, name, addr); - // kfunc_match(security_get_user_sids, name, addr); - // kfunc_match(security_port_sid, name, addr); - // kfunc_match(security_ib_pkey_sid, name, addr); - // kfunc_match(security_ib_endport_sid, name, addr); - // kfunc_match(security_netif_sid, name, addr); - // kfunc_match(security_node_sid, name, addr); - // kfunc_match(security_validate_transition, name, addr); - // kfunc_match(security_validate_transition_user, name, addr); - // kfunc_match(security_bounded_transition, name, addr); - // kfunc_match(security_sid_mls_copy, name, addr); - // kfunc_match(security_net_peersid_resolve, name, addr); - // kfunc_match(security_get_classes, name, addr); - // kfunc_match(security_get_permissions, name, addr); - // kfunc_match(security_get_reject_unknown, name, addr); - // kfunc_match(security_get_allow_unknown, name, addr); - - // kfunc_match(security_fs_use, name, addr); - // kfunc_match(security_genfs_sid, name, addr); - // kfunc_match(selinux_policy_genfs_sid, name, addr); - // kfunc_match(security_netlbl_secattr_to_sid, name, addr); - // kfunc_match(security_netlbl_sid_to_secattr, name, addr); - // kfunc_match(security_get_initial_sid_context, name, addr); - - // kfunc_match(selinux_status_update_setenforce, name, addr); - // kfunc_match(selinux_status_update_policyload, name, addr); - // kfunc_match(selinux_complete_init, name, addr); - // kfunc_match(exit_sel_fs, name, addr); - // kfunc_match(selnl_notify_setenforce, name, addr); - // kfunc_match(selnl_notify_policyload, name, addr); - // kfunc_match(selinux_nlmsg_lookup, name, addr); - - // kfunc_match(avtab_cache_init, name, addr); - // kfunc_match(ebitmap_cache_init, name, addr); - // kfunc_match(hashtab_cache_init, name, addr); - // kfunc_match(security_sidtab_hash_stats, name, addr); -} \ No newline at end of file diff --git a/tools/common.h b/tools/common.h index f10cec94..4f29e4a0 100644 --- a/tools/common.h +++ b/tools/common.h @@ -17,18 +17,18 @@ extern bool log_enable; #define tools_logi(fmt, ...) \ - if (log_enable) fprintf(stdout, "[+] %s; " fmt, __FILE__, ##__VA_ARGS__); + if (log_enable) fprintf(stdout, "[+] " fmt, ##__VA_ARGS__); #define tools_logw(fmt, ...) \ - if (log_enable) fprintf(stdout, "[?] %s; " fmt, __FILE__, ##__VA_ARGS__); + if (log_enable) fprintf(stdout, "[?] " fmt, ##__VA_ARGS__); #define tools_loge(fmt, ...) \ - if (log_enable) fprintf(stdout, "[-] error %s:%d/%s(); " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); + if (log_enable) fprintf(stdout, "[-] %s:%d/%s(); " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); -#define tools_error_exit(fmt, ...) \ - do { \ - fprintf(stdout, "[-] error %s:%d/%s(); " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ - exit(EXIT_FAILURE); \ +#define tools_error_exit(fmt, ...) \ + do { \ + fprintf(stderr, "[-] %s:%d/%s(); " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ + exit(EXIT_FAILURE); \ } while (0) #define SZ_4K 0x1000 diff --git a/tools/kallsym.c b/tools/kallsym.c index 4b7f1737..24a43942 100644 --- a/tools/kallsym.c +++ b/tools/kallsym.c @@ -261,12 +261,12 @@ static int try_find_arm64_relo_table(kallsym_t *info, char *img, int32_t imglen) uint64_t r_addend = uint_unpack(img + cand + 16, 8, info->is_be); if (!r_offset && !r_info && !r_addend) continue; if (r_offset <= kernel_va || r_offset >= max_va - imglen) { - // tools_loge("warn ignore arm64 relocation r_offset: 0x%08lx at 0x%08x\n", r_offset, cand); + // tools_logw("warn ignore arm64 relocation r_offset: 0x%08lx at 0x%08x\n", r_offset, cand); continue; } int32_t offset = r_offset - kernel_va; if (offset >= imglen) { - // tools_loge("apply relocations error\n"); + // tools_logw("apply relocations error\n"); continue; } uint64_t value = uint_unpack(img + offset, 8, info->is_be); @@ -342,7 +342,7 @@ static int find_approx_addresses(kallsym_t *info, char *img, int32_t imglen) // if (info->relo_applied) { - tools_loge("mismatch relo applied, subsequent operations may be undefined\n"); + tools_logw("mismatch relo applied, subsequent operations may be undefined\n"); } return 0; diff --git a/tools/kpm.c b/tools/kpm.c index 8c71e8bb..d9a4f895 100644 --- a/tools/kpm.c +++ b/tools/kpm.c @@ -123,8 +123,6 @@ void print_kpm_info(kpm_info_t *info) void print_kpm_info_path(const char *kpm_path) { - fprintf(stdout, "path=%s\n", kpm_path); - char *img; int len = 0; read_file(kpm_path, &img, &len); diff --git a/tools/patch.c b/tools/patch.c index 0c454acf..771fc2b5 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -56,11 +56,11 @@ void print_preset_info(preset_t *preset) void print_kp_image_info_path(const char *kpimg_path) { - fprintf(stdout, "path=%s\n", kpimg_path); char *kpimg; int len = 0; read_file(kpimg_path, &kpimg, &len); preset_t *preset = (preset_t *)kpimg; + fprintf(stdout, INFO_KP_IMG_SESSION "\n"); print_preset_info(preset); fprintf(stdout, "\n"); free(kpimg); @@ -140,14 +140,17 @@ void print_image_patch_info(patched_kimg_t *pimg) { preset_t *preset = pimg->preset; + fprintf(stdout, INFO_KERNEL_IMG_SESSION "\n"); fprintf(stdout, "linux_banner=%s", pimg->banner); - if (pimg->banner[strlen(pimg->banner) - 1] != '\n') fprintf(stdout, "\n"); + if (pimg->banner[strlen(pimg->banner) - 1] != '\n') fprintf(stdout, "\n"); fprintf(stdout, "patched=%s\n", preset ? "true" : "false"); if (preset) { + fprintf(stdout, INFO_KP_IMG_SESSION "\n"); print_preset_info(preset); - fprintf(stdout, "extra_item_num=%d\n", pimg->embed_item_num); + fprintf(stdout, "extra_num=%d\n", pimg->embed_item_num); + for (int i = 0; i < pimg->embed_item_num; i++) { patch_extra_item_t *item = pimg->embed_item[i]; const char *type = "none"; @@ -158,8 +161,15 @@ void print_image_patch_info(patched_kimg_t *pimg) case EXTRA_TYPE_SHELL: type = "shell"; break; + case EXTRA_TYPE_EXEC: + type = "exec"; + break; + case EXTRA_TYPE_RAW: + type = "raw"; + break; } - fprintf(stdout, "extra_index=%d\n", i); + fprintf(stdout, INFO_EXTRA_SESSION_N "\n", i); + fprintf(stdout, "index=%d\n", i); fprintf(stdout, "type=%s\n", type); fprintf(stdout, "con_size=0x%x\n", item->con_size); fprintf(stdout, "args_size=0x%x\n", item->args_size); @@ -176,7 +186,6 @@ void print_image_patch_info(patched_kimg_t *pimg) void print_image_patch_info_path(const char *kimg_path) { - fprintf(stdout, "path=%s\n", kimg_path); patched_kimg_t pimg = { 0 }; char *kimg; int kimg_len; @@ -229,15 +238,12 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * struct extra_items_wrap { patch_extra_item_t item; + const char *name; extra_item_type type; const char *data; const char *args; int data_len; int args_len; - union - { - const char *name; - }; } *extra_items = (struct extra_items_wrap *)malloc(sizeof(struct extra_items_wrap) * EXTRA_ITEM_MAX_NUM); memset(extra_items, 0, sizeof(struct extra_items_wrap) * EXTRA_ITEM_MAX_NUM); @@ -267,6 +273,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * item_wrap->name = kpm_info.name; // set runtime item + strcpy(item->name, kpm_info.name); item->priority = 0; item->type = EXTRA_TYPE_KPM; item->con_size = kpm_len; @@ -429,7 +436,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * patch_extra_item_t *item = &item_wrap->item; tools_logi("embedding %s, name: %s, size: 0x%x + 0x%x + 0x%x\n", type, item_wrap->name, (int)sizeof(*item), - item_wrap->data_len, item_wrap->args_len); + item_wrap->args_len, item_wrap->data_len); write_file(out_path, (void *)item, sizeof(*item), true); if (item_wrap->args_len > 0) write_file(out_path, (void *)item_wrap->args, item_wrap->args_len, true); diff --git a/tools/patch.h b/tools/patch.h index 2fc812e6..6cfdd709 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -12,6 +12,11 @@ #include "preset.h" #include "image.h" +#define INFO_KERNEL_IMG_SESSION "[kernel]" +#define INFO_KP_IMG_SESSION "[patch]" +#define INFO_EXTRA_SESSION "[extra]" +#define INFO_EXTRA_SESSION_N "[extra %d]" + #define EXTRA_ITEM_MAX_NUM 32 typedef struct From 19711b22a3dfbc3f7a75896aba8f50a3c18a86de Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 31 Jan 2024 10:36:01 +0800 Subject: [PATCH 06/51] x --- README.md | 2 -- tools/patch.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 0d310c36..a2f54da3 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,6 @@ Linux 6.3+ (not yet adapted) ## Get Involved -Please submit your pull request in **dev** branch - ## More Information [Documentation](./doc/) diff --git a/tools/patch.c b/tools/patch.c index 771fc2b5..8402f27b 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -141,7 +141,7 @@ void print_image_patch_info(patched_kimg_t *pimg) preset_t *preset = pimg->preset; fprintf(stdout, INFO_KERNEL_IMG_SESSION "\n"); - fprintf(stdout, "linux_banner=%s", pimg->banner); + fprintf(stdout, "banner=%s", pimg->banner); if (pimg->banner[strlen(pimg->banner) - 1] != '\n') fprintf(stdout, "\n"); fprintf(stdout, "patched=%s\n", preset ? "true" : "false"); From 8eaa89c3bca0e1260a1fb1d1083544b7ed2a387a Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 31 Jan 2024 11:27:20 +0800 Subject: [PATCH 07/51] x --- tools/patch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/patch.c b/tools/patch.c index 8402f27b..3d576fd0 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -46,8 +46,8 @@ void print_preset_info(preset_t *preset) setup_header_t *header = &preset->header; version_t ver = header->kp_version; uint32_t ver_num = (ver.major << 16) + (ver.minor << 8) + ver.patch; - bool is_android = header->config_flags | CONFIG_ANDROID; - bool is_debug = header->config_flags | CONFIG_DEBUG; + bool is_android = !!(header->config_flags & CONFIG_ANDROID); + bool is_debug = !!(header->config_flags & CONFIG_DEBUG); fprintf(stdout, "version=0x%x\n", ver_num); fprintf(stdout, "compile_time=%s\n", header->compile_time); @@ -168,7 +168,7 @@ void print_image_patch_info(patched_kimg_t *pimg) type = "raw"; break; } - fprintf(stdout, INFO_EXTRA_SESSION_N "\n", i); + fprintf(stdout, INFO_EXTRA_SESSION "\n"); fprintf(stdout, "index=%d\n", i); fprintf(stdout, "type=%s\n", type); fprintf(stdout, "con_size=0x%x\n", item->con_size); From 3759207f21a67805fd3ab11bc5efad4f19ef72f4 Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 31 Jan 2024 11:28:48 +0800 Subject: [PATCH 08/51] Revert "x" This reverts commit 8eaa89c3bca0e1260a1fb1d1083544b7ed2a387a. --- tools/patch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/patch.c b/tools/patch.c index 3d576fd0..8402f27b 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -46,8 +46,8 @@ void print_preset_info(preset_t *preset) setup_header_t *header = &preset->header; version_t ver = header->kp_version; uint32_t ver_num = (ver.major << 16) + (ver.minor << 8) + ver.patch; - bool is_android = !!(header->config_flags & CONFIG_ANDROID); - bool is_debug = !!(header->config_flags & CONFIG_DEBUG); + bool is_android = header->config_flags | CONFIG_ANDROID; + bool is_debug = header->config_flags | CONFIG_DEBUG; fprintf(stdout, "version=0x%x\n", ver_num); fprintf(stdout, "compile_time=%s\n", header->compile_time); @@ -168,7 +168,7 @@ void print_image_patch_info(patched_kimg_t *pimg) type = "raw"; break; } - fprintf(stdout, INFO_EXTRA_SESSION "\n"); + fprintf(stdout, INFO_EXTRA_SESSION_N "\n", i); fprintf(stdout, "index=%d\n", i); fprintf(stdout, "type=%s\n", type); fprintf(stdout, "con_size=0x%x\n", item->con_size); From 1280fad01a2e162fe892bc55c2869a9681500702 Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 31 Jan 2024 15:12:09 +0800 Subject: [PATCH 09/51] x --- tools/patch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/patch.h b/tools/patch.h index 6cfdd709..a8481183 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -13,7 +13,7 @@ #include "image.h" #define INFO_KERNEL_IMG_SESSION "[kernel]" -#define INFO_KP_IMG_SESSION "[patch]" +#define INFO_KP_IMG_SESSION "[kpimg]" #define INFO_EXTRA_SESSION "[extra]" #define INFO_EXTRA_SESSION_N "[extra %d]" From 9eaa799be2ee03a7674d9ec39f438f5f4955499a Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 31 Jan 2024 16:04:32 +0800 Subject: [PATCH 10/51] x --- tools/kpm.c | 2 +- tools/kpm.h | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/kpm.c b/tools/kpm.c index d9a4f895..fcb1a663 100644 --- a/tools/kpm.c +++ b/tools/kpm.c @@ -126,7 +126,7 @@ void print_kpm_info_path(const char *kpm_path) char *img; int len = 0; read_file(kpm_path, &img, &len); - + fprintf(stdout, INFO_EXTRA_KPM_SESSION "\n"); kpm_info_t kpm_info = { 0 }; int rc = get_kpm_info(img, len, &kpm_info); if (!rc) { diff --git a/tools/kpm.h b/tools/kpm.h index 178ebf32..842bf10e 100644 --- a/tools/kpm.h +++ b/tools/kpm.h @@ -6,6 +6,9 @@ #ifndef _KP_TOOL_KPM_H_ #define _KP_TOOL_KPM_H_ +#include "elf/elf.h" +#include "common.h" + #define Elf_Shdr Elf64_Shdr #define Elf_Phdr Elf64_Phdr #define Elf_Sym Elf64_Sym @@ -21,8 +24,7 @@ #define ELF_R_TYPE(X) ELF64_R_TYPE(X) #define ELF_R_SYM(X) ELF64_R_SYM(X) -#include "elf/elf.h" -#include "common.h" +#define INFO_EXTRA_KPM_SESSION "[kpm]" struct load_info { From 2456f7f29d26035637f472ad2f5410c9d5880615 Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 1 Feb 2024 10:48:40 +0800 Subject: [PATCH 11/51] a --- tools/common.c | 40 ++++++++++++++++++---------------- tools/common.h | 6 ++--- tools/fls_ffs.h | 6 ++--- tools/image.c | 8 +++---- tools/insn.c | 58 ++++++++++++++++++++++++------------------------- tools/insn.h | 8 +++---- tools/kallsym.c | 2 +- tools/kpm.c | 8 +++---- tools/kpm.h | 8 +++---- tools/patch.c | 47 +++++++++++++++++++-------------------- tools/symbol.c | 18 +++++++-------- 11 files changed, 106 insertions(+), 103 deletions(-) diff --git a/tools/common.c b/tools/common.c index 01906dde..593452b6 100644 --- a/tools/common.c +++ b/tools/common.c @@ -40,15 +40,15 @@ int32_t relo_branch_func(const char *img, int32_t func_offset) void read_file_align(const char *path, char **con, int *out_len, int align) { FILE *fp = fopen(path, "rb"); - if (!fp) tools_error_exit("open file: %s, %s\n", path, strerror(errno)); + if (!fp) tools_loge_exit("open file: %s, %s\n", path, strerror(errno)); fseek(fp, 0, SEEK_END); - long len = ftell(fp); + int len = (int)ftell(fp); fseek(fp, 0, SEEK_SET); - long align_len = align_ceil(len, align); + int align_len = (int)align_ceil(len, align); char *buf = (char *)malloc(align_len); memset(buf + len, 0, align_len - len); int readlen = fread(buf, 1, len, fp); - if (readlen != len) tools_error_exit("read file: %s incomplete\n", path); + if (readlen != len) tools_loge_exit("read file: %s incomplete\n", path); fclose(fp); *con = buf; *out_len = align_len; @@ -56,48 +56,50 @@ void read_file_align(const char *path, char **con, int *out_len, int align) void write_file(const char *path, const char *con, int len, bool append) { - FILE *fout = fopen(path, append ? "a" : "w"); - if (!fout) tools_error_exit("open %s %s\n", path, strerror(errno)); + FILE *fout = fopen(path, append ? "ab" : "wb"); + if (!fout) tools_loge_exit("open %s %s\n", path, strerror(errno)); int writelen = fwrite(con, 1, len, fout); - if (writelen != len) tools_error_exit("write file: %s incomplete\n", path); + if (writelen != len) tools_loge_exit("write file: %s incomplete\n", path); fclose(fout); } -int64_t int_unpack(void *ptr, int32_t size, int32_t is_be) +int64_t int_unpack(void *ptr, int32_t size, bool is_be) { - int16_t res16; - int32_t res32; + bool swp = is_be ^ is_be(); int64_t res64; + int32_t res32; + int16_t res16; switch (size) { case 8: res64 = *(int64_t *)ptr; - return is_be ? i64be(res64) : i64le(res64); + return swp ? i64swp(res64) : res64; case 4: res32 = *(int32_t *)ptr; - return is_be ? i32be(res32) : i32le(res32); + return swp ? i32swp(res32) : res32; case 2: res16 = *(int16_t *)ptr; - return is_be ? i16be(res16) : i16le(res16); + return swp ? i16swp(res16) : res16; default: return *(int8_t *)ptr; } } -uint64_t uint_unpack(void *ptr, int32_t size, int32_t is_be) +uint64_t uint_unpack(void *ptr, int32_t size, bool is_be) { - uint16_t res16; - uint32_t res32; + bool swp = is_be ^ is_be(); uint64_t res64; + uint32_t res32; + uint16_t res16; switch (size) { case 8: res64 = *(uint64_t *)ptr; - return is_be ? u64be(res64) : u64le(res64); + return swp ? u64swp(res64) : res64; case 4: res32 = *(uint32_t *)ptr; - return is_be ? u32be(res32) : u32le(res32); + return swp ? u32swp(res32) : res32; case 2: res16 = *(uint16_t *)ptr; - return is_be ? u16be(res16) : u16le(res16); + return swp ? u16swp(res16) : res16; default: return *(uint8_t *)ptr; } diff --git a/tools/common.h b/tools/common.h index 4f29e4a0..b5f5eb23 100644 --- a/tools/common.h +++ b/tools/common.h @@ -25,7 +25,7 @@ extern bool log_enable; #define tools_loge(fmt, ...) \ if (log_enable) fprintf(stdout, "[-] %s:%d/%s(); " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); -#define tools_error_exit(fmt, ...) \ +#define tools_loge_exit(fmt, ...) \ do { \ fprintf(stderr, "[-] %s:%d/%s(); " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ exit(EXIT_FAILURE); \ @@ -56,8 +56,8 @@ void write_file(const char *path, const char *con, int len, bool append); void read_file_align(const char *path, char **con, int *len, int align); -int64_t int_unpack(void *ptr, int32_t size, int32_t is_be); -uint64_t uint_unpack(void *ptr, int32_t size, int32_t is_be); +int64_t int_unpack(void *ptr, int32_t size, bool is_be); +uint64_t uint_unpack(void *ptr, int32_t size, bool is_be); static inline void read_file(const char *path, char **con, int *len) { diff --git a/tools/fls_ffs.h b/tools/fls_ffs.h index 26dee7d2..3367b1a3 100644 --- a/tools/fls_ffs.h +++ b/tools/fls_ffs.h @@ -12,7 +12,7 @@ * This is defined the same way as ffs. * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. */ -static inline int fls(unsigned int x) +static inline int fls(uint32_t x) { int r = 32; @@ -40,7 +40,7 @@ static inline int fls(unsigned int x) return r; } -static inline unsigned long __fls(unsigned long word) +static inline uint64_t __fls(uint64_t word) { int num = BITS_PER_LONG - 1; @@ -82,7 +82,7 @@ static inline int fls64(u64 x) * * Undefined if no bit exists, so code should check against 0 first. */ -static inline unsigned long __ffs(unsigned long word) +static inline uint64_t __ffs(uint64_t word) { int num = 0; diff --git a/tools/image.c b/tools/image.c index fabcc567..20daecf0 100644 --- a/tools/image.c +++ b/tools/image.c @@ -60,14 +60,14 @@ int32_t get_kernel_info(kernel_info_t *kinfo, const char *img, int32_t imglen) if (!strncmp("UNCOMPRESSED_IMG", img, strlen("UNCOMPRESSED_IMG"))) { kinfo->img_offset = 0x14; - tools_error_exit("kernel image with UNCOMPRESSED_IMG header\n"); + tools_loge_exit("kernel image with UNCOMPRESSED_IMG header\n"); } kinfo->is_be = 0; arm64_hdr_t *khdr = (arm64_hdr_t *)(img + kinfo->img_offset); if (strncmp(khdr->magic, KERNEL_MAGIC, strlen(KERNEL_MAGIC))) { - tools_error_exit("kernel image magic error: %s\n", khdr->magic); + tools_loge_exit("kernel image magic error: %s\n", khdr->magic); } kinfo->uefi = !strncmp((const char *)khdr->hdr.efi.mz, EFI_MAGIC_SIG, strlen(EFI_MAGIC_SIG)); @@ -85,7 +85,7 @@ int32_t get_kernel_info(kernel_info_t *kinfo, const char *img, int32_t imglen) b_primary_entry_insn = u32le(b_primary_entry_insn); if ((b_primary_entry_insn & 0xFC000000) != 0x14000000) { - tools_error_exit("kernel primary entry: %x\n", b_primary_entry_insn); + tools_loge_exit("kernel primary entry: %x\n", b_primary_entry_insn); } else { uint32_t imm = (b_primary_entry_insn & 0x03ffffff) << 2; kinfo->primary_entry_offset = imm + b_stext_insn_offset; @@ -97,7 +97,7 @@ int32_t get_kernel_info(kernel_info_t *kinfo, const char *img, int32_t imglen) uint8_t flag = u64le(khdr->kernel_flag_le) & 0x0f; kinfo->is_be = flag & 0x01; - if (kinfo->is_be) tools_error_exit("kernel unexpected arm64 big endian img\n"); + if (kinfo->is_be) tools_loge_exit("kernel unexpected arm64 big endian img\n"); switch ((flag & 0b0110) >> 1) { case 2: // 16k diff --git a/tools/insn.c b/tools/insn.c index 87a8e993..6679a11e 100644 --- a/tools/insn.c +++ b/tools/insn.c @@ -83,15 +83,15 @@ #define BITS_PER_LONG 64 -static inline unsigned long __ffs64(u64 word) +static inline uint64_t __ffs64(u64 word) { - return __ffs((unsigned long)word); + return __ffs((uint64_t)word); } #define upper_32_bits(n) ((u32)(((n) >> 16) >> 16)) #define lower_32_bits(n) ((u32)(n)) -static inline unsigned long hweight64(u64 w) +static inline uint64_t hweight64(u64 w) { u64 res = w - ((w >> 1) & 0x5555555555555555ul); res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); @@ -402,9 +402,9 @@ static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type, u32 i return insn; } -static inline long branch_imm_common(unsigned long pc, unsigned long addr, long range) +static inline int64_t branch_imm_common(uint64_t pc, uint64_t addr, int64_t range) { - long offset; + int64_t offset; if ((pc & 0x3) || (addr & 0x3)) { fprintf(stdout, "%s: A64 instructions must be word aligned\n", __func__); @@ -421,10 +421,10 @@ static inline long branch_imm_common(unsigned long pc, unsigned long addr, long return offset; } -u32 aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, enum aarch64_insn_branch_type type) +u32 aarch64_insn_gen_branch_imm(uint64_t pc, uint64_t addr, enum aarch64_insn_branch_type type) { u32 insn; - long offset; + int64_t offset; /* * B/BL support [-128M, 128M) offset @@ -449,11 +449,11 @@ u32 aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, enum aarch return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn, offset >> 2); } -u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, enum aarch64_insn_register reg, +u32 aarch64_insn_gen_comp_branch_imm(uint64_t pc, uint64_t addr, enum aarch64_insn_register reg, enum aarch64_insn_variant variant, enum aarch64_insn_branch_type type) { u32 insn; - long offset; + int64_t offset; offset = branch_imm_common(pc, addr, SZ_1M); if (offset >= SZ_1M) return AARCH64_BREAK_FAULT; @@ -486,10 +486,10 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, enum return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn, offset >> 2); } -u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr, enum aarch64_insn_condition cond) +u32 aarch64_insn_gen_cond_branch_imm(uint64_t pc, uint64_t addr, enum aarch64_insn_condition cond) { u32 insn; - long offset; + int64_t offset; offset = branch_imm_common(pc, addr, SZ_1M); @@ -1207,89 +1207,89 @@ u32 aarch32_insn_mcr_extract_crm(u32 insn) return insn & CRM_MASK; } -static bool __check_eq(unsigned long pstate) +static bool __check_eq(uint64_t pstate) { return (pstate & PSR_Z_BIT) != 0; } -static bool __check_ne(unsigned long pstate) +static bool __check_ne(uint64_t pstate) { return (pstate & PSR_Z_BIT) == 0; } -static bool __check_cs(unsigned long pstate) +static bool __check_cs(uint64_t pstate) { return (pstate & PSR_C_BIT) != 0; } -static bool __check_cc(unsigned long pstate) +static bool __check_cc(uint64_t pstate) { return (pstate & PSR_C_BIT) == 0; } -static bool __check_mi(unsigned long pstate) +static bool __check_mi(uint64_t pstate) { return (pstate & PSR_N_BIT) != 0; } -static bool __check_pl(unsigned long pstate) +static bool __check_pl(uint64_t pstate) { return (pstate & PSR_N_BIT) == 0; } -static bool __check_vs(unsigned long pstate) +static bool __check_vs(uint64_t pstate) { return (pstate & PSR_V_BIT) != 0; } -static bool __check_vc(unsigned long pstate) +static bool __check_vc(uint64_t pstate) { return (pstate & PSR_V_BIT) == 0; } -static bool __check_hi(unsigned long pstate) +static bool __check_hi(uint64_t pstate) { pstate &= ~(pstate >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ return (pstate & PSR_C_BIT) != 0; } -static bool __check_ls(unsigned long pstate) +static bool __check_ls(uint64_t pstate) { pstate &= ~(pstate >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ return (pstate & PSR_C_BIT) == 0; } -static bool __check_ge(unsigned long pstate) +static bool __check_ge(uint64_t pstate) { pstate ^= (pstate << 3); /* PSR_N_BIT ^= PSR_V_BIT */ return (pstate & PSR_N_BIT) == 0; } -static bool __check_lt(unsigned long pstate) +static bool __check_lt(uint64_t pstate) { pstate ^= (pstate << 3); /* PSR_N_BIT ^= PSR_V_BIT */ return (pstate & PSR_N_BIT) != 0; } -static bool __check_gt(unsigned long pstate) +static bool __check_gt(uint64_t pstate) { /*PSR_N_BIT ^= PSR_V_BIT */ - unsigned long temp = pstate ^ (pstate << 3); + uint64_t temp = pstate ^ (pstate << 3); temp |= (pstate << 1); /*PSR_N_BIT |= PSR_Z_BIT */ return (temp & PSR_N_BIT) == 0; } -static bool __check_le(unsigned long pstate) +static bool __check_le(uint64_t pstate) { /*PSR_N_BIT ^= PSR_V_BIT */ - unsigned long temp = pstate ^ (pstate << 3); + uint64_t temp = pstate ^ (pstate << 3); temp |= (pstate << 1); /*PSR_N_BIT |= PSR_Z_BIT */ return (temp & PSR_N_BIT) != 0; } -static bool __check_al(unsigned long pstate) +static bool __check_al(uint64_t pstate) { return true; } @@ -1314,7 +1314,7 @@ static bool range_of_ones(u64 val) static u32 aarch64_encode_immediate(u64 imm, enum aarch64_insn_variant variant, u32 insn) { - unsigned int immr, imms, n, ones, ror, esz, tmp; + uint32_t immr, imms, n, ones, ror, esz, tmp; u64 mask = ~0UL; /* Can't encode full zeroes or full ones */ diff --git a/tools/insn.h b/tools/insn.h index fab77ef2..4136b68d 100644 --- a/tools/insn.h +++ b/tools/insn.h @@ -416,10 +416,10 @@ bool aarch64_insn_is_branch(u32 insn); u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn); u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, u32 insn, u64 imm); u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type, u32 insn); -u32 aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, enum aarch64_insn_branch_type type); -u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr, enum aarch64_insn_register reg, +u32 aarch64_insn_gen_branch_imm(uint64_t pc, uint64_t addr, enum aarch64_insn_branch_type type); +u32 aarch64_insn_gen_comp_branch_imm(uint64_t pc, uint64_t addr, enum aarch64_insn_register reg, enum aarch64_insn_variant variant, enum aarch64_insn_branch_type type); -u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr, enum aarch64_insn_condition cond); +u32 aarch64_insn_gen_cond_branch_imm(uint64_t pc, uint64_t addr, enum aarch64_insn_condition cond); u32 aarch64_insn_gen_hint(enum aarch64_insn_hint_op op); u32 aarch64_insn_gen_nop(void); u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg, enum aarch64_insn_branch_type type); @@ -475,7 +475,7 @@ u32 aarch32_insn_extract_reg_num(u32 insn, int offset); u32 aarch32_insn_mcr_extract_opc2(u32 insn); u32 aarch32_insn_mcr_extract_crm(u32 insn); -typedef bool(pstate_check_t)(unsigned long); +typedef bool(pstate_check_t)(uint64_t); extern pstate_check_t *const aarch32_opcode_cond_checks[16]; #endif /* __ASSEMBLY__ */ diff --git a/tools/kallsym.c b/tools/kallsym.c index 24a43942..3b7cbc68 100644 --- a/tools/kallsym.c +++ b/tools/kallsym.c @@ -55,7 +55,7 @@ static int find_linux_banner(kallsym_t *info, char *img, int32_t imglen) // PATCHLEVEL info->version.minor = (uint8_t)strtoul(dot + 1, &dot, 10); // SUBLEVEL - unsigned long patch = strtoul(dot + 1, &dot, 10); + int32_t patch = (int32_t)strtoul(dot + 1, &dot, 10); info->version.patch = patch <= 256 ? patch : 255; tools_logi("kernel version major: %d, minor: %d, patch: %d\n", info->version.major, info->version.minor, diff --git a/tools/kpm.c b/tools/kpm.c index fcb1a663..d9be1ad4 100644 --- a/tools/kpm.c +++ b/tools/kpm.c @@ -11,7 +11,7 @@ #define elf_check_arch(x) ((x)->e_machine == EM_AARCH64) -static char *next_string(char *string, unsigned long *secsize) +static char *next_string(char *string, uint64_t *secsize) { while (string[0]) { string++; @@ -27,9 +27,9 @@ static char *next_string(char *string, unsigned long *secsize) static char *get_next_modinfo(const struct load_info *info, const char *tag, char *prev) { char *p; - unsigned int taglen = strlen(tag); + uint32_t taglen = strlen(tag); Elf_Shdr *infosec = &info->sechdrs[info->index.info]; - unsigned long size = infosec->sh_size; + uint64_t size = infosec->sh_size; char *modinfo = (char *)info->hdr + infosec->sh_offset; if (prev) { size -= prev - modinfo; @@ -64,7 +64,7 @@ static void *get_sh_base(struct load_info *info, const char *secname) return addr; } -static unsigned long get_sh_size(struct load_info *info, const char *secname) +static uint64_t get_sh_size(struct load_info *info, const char *secname) { int idx = find_sec(info, secname); if (!idx) return 0; diff --git a/tools/kpm.h b/tools/kpm.h index 842bf10e..44d40af7 100644 --- a/tools/kpm.h +++ b/tools/kpm.h @@ -31,17 +31,17 @@ struct load_info struct { const char *base; - unsigned long size; + uint64_t size; const char *name, *version, *license, *author, *description; } info; Elf_Ehdr *hdr; - unsigned long len; + uint64_t len; Elf_Shdr *sechdrs; char *secstrings, *strtab; - unsigned long symoffs, stroffs; + uint64_t symoffs, stroffs; struct { - unsigned int sym, str, mod, info; + uint32_t sym, str, mod, info; } index; }; diff --git a/tools/patch.c b/tools/patch.c index 8402f27b..67913fe6 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -35,7 +35,7 @@ uint32_t get_kpimg_version(const char *kpimg_path) int kpimg_len = 0; read_file(kpimg_path, &kpimg, &kpimg_len); preset_t *preset = get_preset(kpimg, kpimg_len); - if (!preset) tools_error_exit("not patched kernel image\n"); + if (!preset) tools_loge_exit("not patched kernel image\n"); version_t ver = preset->header.kp_version; uint32_t version = (ver.major << 16) + (ver.minor << 8) + ver.patch; return version; @@ -52,6 +52,7 @@ void print_preset_info(preset_t *preset) fprintf(stdout, "version=0x%x\n", ver_num); fprintf(stdout, "compile_time=%s\n", header->compile_time); fprintf(stdout, "config=%s,%s\n", is_debug ? "debug" : "release", is_android ? "android" : "linux"); + fprintf(stdout, "superkey=%s\n", preset->setup.superkey); } void print_kp_image_info_path(const char *kpimg_path) @@ -73,7 +74,7 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) // kernel image infomation kernel_info_t *kinfo = &pimg->kinfo; - if (get_kernel_info(kinfo, kimg, kimg_len)) tools_error_exit("get_kernel_info error\n"); + if (get_kernel_info(kinfo, kimg, kimg_len)) tools_loge_exit("get_kernel_info error\n"); // find banner char linux_banner_prefix[] = "Linux version "; @@ -86,7 +87,7 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) break; } } - if (!pimg->banner) tools_error_exit("can't find linux banner\n"); + if (!pimg->banner) tools_loge_exit("can't find linux banner\n"); // patched or new preset_t *old_preset = get_preset(kimg, kimg_len); @@ -101,7 +102,7 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) tools_logi("patched kernel image ...\n"); int saved_kimg_len = old_preset->setup.kimg_size; int align_kimg_len = (char *)old_preset - kimg; - if (align_kimg_len != (int)align_ceil(saved_kimg_len, SZ_4K)) tools_error_exit("saved kernel image size error\n"); + if (align_kimg_len != (int)align_ceil(saved_kimg_len, SZ_4K)) tools_loge_exit("saved kernel image size error\n"); pimg->ori_kimg_len = saved_kimg_len; memcpy((char *)kimg, old_preset->setup.header_backup, sizeof(old_preset->setup.header_backup)); @@ -126,7 +127,7 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) int parse_image_patch_info_path(const char *kimg_path, patched_kimg_t *pimg) { - if (!kimg_path) tools_error_exit("empty kernel image\n"); + if (!kimg_path) tools_loge_exit("empty kernel image\n"); char *kimg; int kimg_len; @@ -177,7 +178,7 @@ void print_image_patch_info(patched_kimg_t *pimg) kpm_info_t kpm_info = { 0 }; void *kpm = (kpm_info_t *)((uintptr_t)item + sizeof(patch_extra_item_t) + item->args_size); int rc = get_kpm_info(kpm, item->con_size, &kpm_info); - if (rc) tools_error_exit("get kpm infomation error: %d\n", rc); + if (rc) tools_loge_exit("get kpm infomation error: %d\n", rc); print_kpm_info(&kpm_info); } } @@ -202,16 +203,16 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * { set_log_enable(true); - if (!kpimg_path) tools_error_exit("empty kpimg\n"); - if (!out_path) tools_error_exit("empty out image path\n"); - if (!superkey) tools_error_exit("empty superkey\n"); + if (!kpimg_path) tools_loge_exit("empty kpimg\n"); + if (!out_path) tools_loge_exit("empty out image path\n"); + if (!superkey) tools_loge_exit("empty superkey\n"); patched_kimg_t pimg = { 0 }; char *kimg; int kimg_len; read_file(kimg_path, &kimg, &kimg_len); int rc = parse_image_patch_info(kimg, kimg_len, &pimg); - if (rc) tools_error_exit("parse kernel image error\n"); + if (rc) tools_loge_exit("parse kernel image error\n"); // print_image_patch_info(&pimg); // kimg base info @@ -223,7 +224,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * memcpy(kallsym_kimg, pimg.kimg, pimg.ori_kimg_len); kallsym_t kallsym = { 0 }; if (analyze_kallsym_info(&kallsym, kallsym_kimg, pimg.ori_kimg_len, ARM64, 1)) { - tools_error_exit("analyze_kallsym_info error\n"); + tools_loge_exit("analyze_kallsym_info error\n"); } // kpimg @@ -257,7 +258,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * kpm_info_t kpm_info = { 0 }; int rc = get_kpm_info(kpm_data, kpm_len, &kpm_info); - if (rc) tools_error_exit("can get infomation of kpm, path: %s\n", embed_kpm_path[i]); + if (rc) tools_loge_exit("can get infomation of kpm, path: %s\n", embed_kpm_path[i]); struct extra_items_wrap *item_wrap = extra_items + extra_num; patch_extra_item_t *item = &item_wrap->item; @@ -383,7 +384,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * setup->printk_offset = get_symbol_offset_zero(&kallsym, kallsym_kimg, "printk"); if (!setup->printk_offset) setup->printk_offset = get_symbol_offset_zero(&kallsym, kallsym_kimg, "_printk"); - if (!setup->printk_offset) tools_error_exit("no symbol printk\n"); + if (!setup->printk_offset) tools_loge_exit("no symbol printk\n"); if ((is_be() ^ kinfo->is_be)) { setup->kimg_size = i64swp(setup->kimg_size); @@ -466,15 +467,15 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * int unpatch_img(const char *kimg_path, const char *out_path) { - if (!kimg_path) tools_error_exit("empty kernel image\n"); - if (!out_path) tools_error_exit("empty out image path\n"); + if (!kimg_path) tools_loge_exit("empty kernel image\n"); + if (!out_path) tools_loge_exit("empty out image path\n"); char *kimg = NULL; int kimg_len = 0; read_file(kimg_path, &kimg, &kimg_len); preset_t *preset = get_preset(kimg, kimg_len); - if (!preset) tools_error_exit("not patched kernel image\n"); + if (!preset) tools_loge_exit("not patched kernel image\n"); memcpy(kimg, preset->setup.header_backup, sizeof(preset->setup.header_backup)); int kimg_size = preset->setup.kimg_size ?: ((char *)preset - kimg); @@ -486,19 +487,19 @@ int unpatch_img(const char *kimg_path, const char *out_path) int reset_key(const char *kimg_path, const char *out_path, const char *superkey) { - if (!kimg_path) tools_error_exit("empty kernel image\n"); - if (!out_path) tools_error_exit("empty out image path\n"); - if (!superkey) tools_error_exit("empty superkey\n"); + if (!kimg_path) tools_loge_exit("empty kernel image\n"); + if (!out_path) tools_loge_exit("empty out image path\n"); + if (!superkey) tools_loge_exit("empty superkey\n"); - if (strlen(superkey) <= 0) tools_error_exit("empty superkey\n"); - if (strlen(superkey) >= SUPER_KEY_LEN) tools_error_exit("too long superkey\n"); + if (strlen(superkey) <= 0) tools_loge_exit("empty superkey\n"); + if (strlen(superkey) >= SUPER_KEY_LEN) tools_loge_exit("too long superkey\n"); char *kimg = NULL; int kimg_len = 0; read_file(kimg_path, &kimg, &kimg_len); preset_t *preset = get_preset(kimg, kimg_len); - if (!preset) tools_error_exit("not patched kernel image\n"); + if (!preset) tools_loge_exit("not patched kernel image\n"); char *origin_key = strdup((char *)preset->setup.superkey); strcpy((char *)preset->setup.superkey, superkey); @@ -514,7 +515,7 @@ int reset_key(const char *kimg_path, const char *out_path, const char *superkey) int dump_kallsym(const char *kimg_path) { - if (!kimg_path) tools_error_exit("empty kernel image\n"); + if (!kimg_path) tools_loge_exit("empty kernel image\n"); set_log_enable(true); // read image files char *kimg = NULL; diff --git a/tools/symbol.c b/tools/symbol.c index 7856bb16..a7e4f421 100644 --- a/tools/symbol.c +++ b/tools/symbol.c @@ -18,7 +18,7 @@ int32_t get_symbol_offset_exit(kallsym_t *info, char *img, char *symbol) if (offset >= 0) { return offset; } else { - tools_error_exit("no symbol %s\n", symbol); + tools_loge_exit("no symbol %s\n", symbol); } } @@ -66,14 +66,14 @@ int fillin_map_symbol(kallsym_t *kallsym, char *img_buf, map_symbol_t *symbol, i symbol->memblock_phys_alloc_relo = get_symbol_offset_zero(kallsym, img_buf, "memblock_phys_alloc_try_nid"); symbol->memblock_virt_alloc_relo = get_symbol_offset_zero(kallsym, img_buf, "memblock_virt_alloc_try_nid"); if (!symbol->memblock_phys_alloc_relo && !symbol->memblock_virt_alloc_relo) - tools_error_exit("no symbol memblock_alloc"); + tools_loge_exit("no symbol memblock_alloc"); uint64_t memblock_alloc_try_nid = get_symbol_offset_zero(kallsym, img_buf, "memblock_alloc_try_nid"); if (!symbol->memblock_phys_alloc_relo) symbol->memblock_phys_alloc_relo = memblock_alloc_try_nid; if (!symbol->memblock_virt_alloc_relo) symbol->memblock_virt_alloc_relo = memblock_alloc_try_nid; if (!symbol->memblock_phys_alloc_relo && !symbol->memblock_virt_alloc_relo) - tools_error_exit("no symbol memblock_alloc"); + tools_loge_exit("no symbol memblock_alloc"); if ((is_be() ^ target_is_be)) { for (int64_t *pos = (int64_t *)symbol; pos <= (int64_t *)symbol; pos++) { @@ -103,7 +103,7 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym if (!symbol->rest_init && !symbol->cgroup_init) { symbol->rest_init = find_suffixed_symbol(kallsym, img_buf, "rest_init"); } - if (!symbol->rest_init && !symbol->cgroup_init) tools_error_exit("no symbol rest_init"); + if (!symbol->rest_init && !symbol->cgroup_init) tools_loge_exit("no symbol rest_init"); symbol->kernel_init = get_symbol_offset_zero(kallsym, img_buf, "kernel_init"); @@ -116,7 +116,7 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym if (!symbol->copy_process && !symbol->cgroup_post_fork) { symbol->copy_process = find_suffixed_symbol(kallsym, img_buf, "copy_process"); } - if (!symbol->copy_process && !symbol->cgroup_post_fork) tools_error_exit("no symbol copy_process"); + if (!symbol->copy_process && !symbol->cgroup_post_fork) tools_loge_exit("no symbol copy_process"); symbol->__do_execve_file = get_symbol_offset_zero(kallsym, img_buf, "__do_execve_file"); symbol->do_execveat_common = get_symbol_offset_zero(kallsym, img_buf, "do_execveat_common"); @@ -127,14 +127,14 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym symbol->do_execve_common = find_suffixed_symbol(kallsym, img_buf, "do_execve_common"); } if (!symbol->__do_execve_file && !symbol->do_execveat_common && !symbol->do_execve_common) - tools_error_exit("no symbol execve"); + tools_loge_exit("no symbol execve"); symbol->avc_denied = get_symbol_offset_zero(kallsym, img_buf, "avc_denied"); if (!symbol->avc_denied) { // gcc -fipa-sra eg: avc_denied.isra.5 symbol->avc_denied = find_suffixed_symbol(kallsym, img_buf, "avc_denied"); } - if (!symbol->avc_denied && is_android) tools_error_exit("no symbol avc_denied"); + if (!symbol->avc_denied && is_android) tools_loge_exit("no symbol avc_denied"); symbol->slow_avc_audit = get_symbol_offset_zero(kallsym, img_buf, "slow_avc_audit"); @@ -148,7 +148,7 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym symbol->do_statx = find_suffixed_symbol(kallsym, img_buf, "do_statx"); symbol->vfs_fstatat = find_suffixed_symbol(kallsym, img_buf, "vfs_fstatat"); } - if (!symbol->vfs_statx && !symbol->do_statx && !symbol->vfs_fstatat) tools_error_exit("no symbol stat"); + if (!symbol->vfs_statx && !symbol->do_statx && !symbol->vfs_fstatat) tools_loge_exit("no symbol stat"); symbol->do_faccessat = get_symbol_offset_zero(kallsym, img_buf, "do_faccessat"); symbol->sys_faccessat = get_symbol_offset_zero(kallsym, img_buf, "sys_faccessat"); @@ -156,7 +156,7 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym symbol->do_faccessat = find_suffixed_symbol(kallsym, img_buf, "do_faccessat"); symbol->sys_faccessat = find_suffixed_symbol(kallsym, img_buf, "sys_faccessat"); } - if (!symbol->do_faccessat && !symbol->sys_faccessat) tools_error_exit("no symbol accessat"); + if (!symbol->do_faccessat && !symbol->sys_faccessat) tools_loge_exit("no symbol accessat"); if ((is_be() ^ target_is_be)) { for (int64_t *pos = (int64_t *)symbol; pos <= (int64_t *)symbol; pos++) { From 34ff5ed802b38f877905aeda03eb4d269e7b1ac3 Mon Sep 17 00:00:00 2001 From: bmax Date: Fri, 2 Feb 2024 09:44:35 +0800 Subject: [PATCH 12/51] add additional infomation --- kernel/include/preset.h | 3 + tools/kptools.c | 23 +++++-- tools/patch.c | 133 +++++++++++++++++++++++++--------------- tools/patch.h | 4 +- 4 files changed, 108 insertions(+), 55 deletions(-) diff --git a/kernel/include/preset.h b/kernel/include/preset.h index 41d2c0d0..f830f218 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -30,6 +30,8 @@ #define PATCH_SYMBOL_LEN (512) +#define ADDITIONAL_LEN (256) + #define PATCH_EXTRA_ITEM_LEN (64) #define VERSION(major, minor, patch) (((major) << 16) + ((minor) << 8) + (patch)) @@ -185,6 +187,7 @@ typedef struct _setup_preset_t uint8_t header_backup[HDR_BACKUP_SIZE]; uint8_t superkey[SUPER_KEY_LEN]; patch_symbol_t patch_symbol; + char additional[ADDITIONAL_LEN]; } setup_preset_t; #else #define setup_kernel_version_offset 0 diff --git a/tools/kptools.c b/tools/kptools.c index f22fefb2..f4de8e57 100644 --- a/tools/kptools.c +++ b/tools/kptools.c @@ -51,11 +51,13 @@ void print_usage(char **argv) " -i, --image PATH Kernel image path.\n" " -k, --kpimg PATH KernelPatch image path.\n" " -o, --out PATH Patched image path.\n" + " -K, --kpatch PATH Embed kpatch executable binary into patches.\n" " -E, --embed-kpm PATH Embed KPM into patches.\n" - " -A, --embed-kpm-args ARGS KPM args will be passed to previous KPM(-E).\n" + " -A, --embed-kpm-args ARGS Arguments will be passed to previous KPM(-E).\n" " -D, --detach-kpm NAME Detach embeded KPM from patches.\n" " -M, --kpm PATH Specify KPM path.\n" + " -a --addition KEY=VALUE Add additional information.\n" "\n"; fprintf(stdout, c, version, program_name); } @@ -78,18 +80,21 @@ int main(int argc, char *argv[]) { "kpimg", required_argument, NULL, 'k' }, { "skey", required_argument, NULL, 's' }, { "out", required_argument, NULL, 'o' }, + { "kpatch", required_argument, NULL, 'K' }, { "embed-kpm", required_argument, NULL, 'E' }, { "embed-kpm-args", required_argument, NULL, 'A' }, { "detach-kpm", required_argument, NULL, 'D' }, { "kpm", required_argument, NULL, 'M' }, + { "addition", required_argument, NULL, 'a' }, { 0, 0, 0, 0 } }; - char *optstr = "hvpurdli:s:k:o:E:A:D:M:"; + char *optstr = "hvpurdli:s:k:o:K:E:A:D:M:a:"; char *kimg_path = NULL; char *kpimg_path = NULL; char *out_path = NULL; char *superkey = NULL; + char *kpatch_path = NULL; int embed_kpm_num = 0; char *embed_kpms_path[EXTRA_ITEM_MAX_NUM] = { 0 }; @@ -98,6 +103,9 @@ int main(int argc, char *argv[]) int detach_kpm_num = 0; char *detach_kpms_name[EXTRA_ITEM_MAX_NUM] = { 0 }; + int additional_num = 0; + char *additional[16] = { 0 }; + char *alone_kpm_path = NULL; char cmd = '\0'; @@ -127,6 +135,9 @@ int main(int argc, char *argv[]) case 'o': out_path = optarg; break; + case 'K': + kpatch_path = optarg; + break; case 'E': embed_kpms_path[embed_kpm_num++] = optarg; break; @@ -139,6 +150,9 @@ int main(int argc, char *argv[]) case 'M': alone_kpm_path = optarg; break; + case 'a': + additional[additional_num++] = optarg; + break; default: break; } @@ -153,8 +167,9 @@ int main(int argc, char *argv[]) else fprintf(stdout, "%x\n", version); } else if (cmd == 'p') { - ret = patch_update_img(kimg_path, kpimg_path, out_path, superkey, embed_kpms_path, embed_kpms_args, - embed_kpm_num, detach_kpms_name, detach_kpm_num); + ret = patch_update_img(kimg_path, kpimg_path, out_path, superkey, (const char **)embed_kpms_path, + (const char **)embed_kpms_args, (const char **)detach_kpms_name, + (const char **)additional); } else if (cmd == 'd') { ret = dump_kallsym(kimg_path); } else if (cmd == 'u') { diff --git a/tools/patch.c b/tools/patch.c index 67913fe6..0d29878d 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -44,15 +44,27 @@ uint32_t get_kpimg_version(const char *kpimg_path) void print_preset_info(preset_t *preset) { setup_header_t *header = &preset->header; + setup_preset_t *setup = &preset->setup; version_t ver = header->kp_version; uint32_t ver_num = (ver.major << 16) + (ver.minor << 8) + ver.patch; bool is_android = header->config_flags | CONFIG_ANDROID; bool is_debug = header->config_flags | CONFIG_DEBUG; + fprintf(stdout, INFO_KP_IMG_SESSION "\n"); fprintf(stdout, "version=0x%x\n", ver_num); fprintf(stdout, "compile_time=%s\n", header->compile_time); fprintf(stdout, "config=%s,%s\n", is_debug ? "debug" : "release", is_android ? "android" : "linux"); - fprintf(stdout, "superkey=%s\n", preset->setup.superkey); + fprintf(stdout, "superkey=%s\n", setup->superkey); + + fprintf(stdout, INFO_ADDITIONAL_SESSION "\n"); + char *pos = setup->additional; + for (; pos < setup->additional + ADDITIONAL_LEN - 1;) { + pos++; + if (!*(pos - 1) && *pos) { + fprintf(stdout, "%s\n", pos); + pos += strlen(pos); + } + } } void print_kp_image_info_path(const char *kpimg_path) @@ -61,7 +73,6 @@ void print_kp_image_info_path(const char *kpimg_path) int len = 0; read_file(kpimg_path, &kpimg, &len); preset_t *preset = (preset_t *)kpimg; - fprintf(stdout, INFO_KP_IMG_SESSION "\n"); print_preset_info(preset); fprintf(stdout, "\n"); free(kpimg); @@ -146,11 +157,10 @@ void print_image_patch_info(patched_kimg_t *pimg) if (pimg->banner[strlen(pimg->banner) - 1] != '\n') fprintf(stdout, "\n"); fprintf(stdout, "patched=%s\n", preset ? "true" : "false"); + fprintf(stdout, "extra_num=%d\n", pimg->embed_item_num); if (preset) { - fprintf(stdout, INFO_KP_IMG_SESSION "\n"); print_preset_info(preset); - fprintf(stdout, "extra_num=%d\n", pimg->embed_item_num); for (int i = 0; i < pimg->embed_item_num; i++) { patch_extra_item_t *item = pimg->embed_item[i]; @@ -196,10 +206,9 @@ void print_image_patch_info_path(const char *kimg_path) free(kimg); } -// todo: opt int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey, - char **embed_kpm_path, char **embed_kpm_args, int embed_kpm_num, char **detach_kpm_names, - int detach_kpm_num) + const char **embed_kpm_path, const char **embed_kpm_args, const char **detach_kpm_names, + const char **additional) { set_log_enable(true); @@ -249,48 +258,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * memset(extra_items, 0, sizeof(struct extra_items_wrap) * EXTRA_ITEM_MAX_NUM); - // new extra - for (int i = 0; i < embed_kpm_num && extra_num < EXTRA_ITEM_MAX_NUM; i++) { - char *kpm_data; - int kpm_len = 0; - int args_len = 0; - read_file_align(embed_kpm_path[i], &kpm_data, &kpm_len, EXTRA_ALIGN); - - kpm_info_t kpm_info = { 0 }; - int rc = get_kpm_info(kpm_data, kpm_len, &kpm_info); - if (rc) tools_loge_exit("can get infomation of kpm, path: %s\n", embed_kpm_path[i]); - - struct extra_items_wrap *item_wrap = extra_items + extra_num; - patch_extra_item_t *item = &item_wrap->item; - - // set wrap - const char *args = embed_kpm_args[i]; - if (args) args_len = align_ceil(strlen(args), EXTRA_ALIGN); - item_wrap->type = EXTRA_TYPE_KPM; - item_wrap->data = kpm_data; - item_wrap->data_len = kpm_len; - item_wrap->args = args; - item_wrap->args_len = args_len; - item_wrap->name = kpm_info.name; - - // set runtime item - strcpy(item->name, kpm_info.name); - item->priority = 0; - item->type = EXTRA_TYPE_KPM; - item->con_size = kpm_len; - item->args_size = args_len; - if ((is_be() ^ kinfo->is_be)) { - item->priority = i32swp(item->priority); - item->type = i32swp(item->type); - item->con_size = i32swp(item->con_size); - item->args_size = i32swp(item->args_size); - } - - extra_size += (kpm_len + args_len + sizeof(patch_extra_item_t)); - extra_num++; - } - - // reserved pre-patched extra + // reserved patched extra for (int i = 0; i < pimg.embed_item_num; i++) { struct extra_items_wrap *item_wrap = extra_items + extra_num; patch_extra_item_t *item = pimg.embed_item[i]; @@ -304,7 +272,8 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * kpm_info_t kpm_info = { 0 }; void *kpm = (kpm_info_t *)((uintptr_t)item + sizeof(patch_extra_item_t) + item->args_size); get_kpm_info(kpm, item->con_size, &kpm_info); - for (int j = 0; j < detach_kpm_num; j++) { + for (int j = 0;; j++) { + if (!detach_kpm_names[j]) break; if (!strcmp(detach_kpm_names[j], kpm_info.name)) { detach = true; break; @@ -333,6 +302,49 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * } } + // new extra + for (int i = 0; extra_num < EXTRA_ITEM_MAX_NUM; i++) { + if (!embed_kpm_path[i]) break; + + char *kpm_data; + int kpm_len = 0; + int args_len = 0; + read_file_align(embed_kpm_path[i], &kpm_data, &kpm_len, EXTRA_ALIGN); + + kpm_info_t kpm_info = { 0 }; + int rc = get_kpm_info(kpm_data, kpm_len, &kpm_info); + if (rc) tools_loge_exit("can get infomation of kpm, path: %s\n", embed_kpm_path[i]); + + struct extra_items_wrap *item_wrap = extra_items + extra_num; + patch_extra_item_t *item = &item_wrap->item; + + // set wrap + const char *args = embed_kpm_args[i]; + if (args) args_len = align_ceil(strlen(args), EXTRA_ALIGN); + item_wrap->type = EXTRA_TYPE_KPM; + item_wrap->data = kpm_data; + item_wrap->data_len = kpm_len; + item_wrap->args = args; + item_wrap->args_len = args_len; + item_wrap->name = kpm_info.name; + + // set runtime item + strcpy(item->name, kpm_info.name); + item->priority = 0; + item->type = EXTRA_TYPE_KPM; + item->con_size = kpm_len; + item->args_size = args_len; + if ((is_be() ^ kinfo->is_be)) { + item->priority = i32swp(item->priority); + item->type = i32swp(item->type); + item->con_size = i32swp(item->con_size); + item->args_size = i32swp(item->args_size); + } + + extra_size += (kpm_len + args_len + sizeof(patch_extra_item_t)); + extra_num++; + } + extra_size += sizeof(patch_extra_item_t); // copy to out image @@ -417,6 +429,27 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * int text_offset = align_kimg_len + SZ_4K; b((uint32_t *)(out_img + kinfo->b_stext_insn_offset), kinfo->b_stext_insn_offset, text_offset); + // additional key=value set + char *addition_pos = setup->additional; + for (; addition_pos < setup->additional + ADDITIONAL_LEN - 1; addition_pos++) { + if (!*addition_pos && !*(addition_pos + 1)) break; + } + for (int i = 0;; i++) { + addition_pos++; + const char *kv = additional[i]; + if (!kv) break; + if (!strchr(kv, '=')) { + tools_loge_exit("addition must be format of key=value\n"); + } + int kvlen = strlen(kv); + if (addition_pos + kvlen >= setup->additional + ADDITIONAL_LEN) { + tools_loge_exit("no memory for addition\n"); + } + tools_logi("adding addition: %s\n", kv); + strcpy(addition_pos, kv); + addition_pos += kvlen; + } + // write out write_file(out_path, out_img, out_img_len, false); diff --git a/tools/patch.h b/tools/patch.h index a8481183..8d949e46 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -14,6 +14,7 @@ #define INFO_KERNEL_IMG_SESSION "[kernel]" #define INFO_KP_IMG_SESSION "[kpimg]" +#define INFO_ADDITIONAL_SESSION "[additional]" #define INFO_EXTRA_SESSION "[extra]" #define INFO_EXTRA_SESSION_N "[extra %d]" @@ -35,7 +36,8 @@ preset_t *get_preset(const char *kimg, int kimg_len); uint32_t get_kpimg_version(const char *kpimg_path); int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey, - char **embed_kpm, char **embed_kpm_args, int embed_kpm_num, char **detach_kpm, int detach_kpm_num); + const char **embed_kpm_path, const char **embed_kpm_args, const char **detach_kpm_names, + const char **additional); int unpatch_img(const char *kimg_path, const char *out_path); int reset_key(const char *kimg_path, const char *out_path, const char *key); int dump_kallsym(const char *kimg_path); From 39302e500df8109a7723d266d46e65046c4d4e4e Mon Sep 17 00:00:00 2001 From: bmax Date: Fri, 2 Feb 2024 15:35:09 +0800 Subject: [PATCH 13/51] x --- tools/kpm.c | 3 ++- tools/kpm.h | 2 +- tools/kptools.c | 6 +++--- tools/patch.c | 24 +++++++++++++++++------- tools/patch.h | 6 +++--- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/tools/kpm.c b/tools/kpm.c index d9be1ad4..4395b2fb 100644 --- a/tools/kpm.c +++ b/tools/kpm.c @@ -121,7 +121,7 @@ void print_kpm_info(kpm_info_t *info) fprintf(stdout, "description=%s\n", info->description); } -void print_kpm_info_path(const char *kpm_path) +int print_kpm_info_path(const char *kpm_path) { char *img; int len = 0; @@ -133,4 +133,5 @@ void print_kpm_info_path(const char *kpm_path) print_kpm_info(&kpm_info); } free(img); + return rc; } diff --git a/tools/kpm.h b/tools/kpm.h index 44d40af7..ed852765 100644 --- a/tools/kpm.h +++ b/tools/kpm.h @@ -53,6 +53,6 @@ typedef struct int get_kpm_info(const char *kpm, int len, kpm_info_t *info); void print_kpm_info(kpm_info_t *info); -void print_kpm_info_path(const char *kpm_path); +int print_kpm_info_path(const char *kpm_path); #endif \ No newline at end of file diff --git a/tools/kptools.c b/tools/kptools.c index f4de8e57..03eb213d 100644 --- a/tools/kptools.c +++ b/tools/kptools.c @@ -177,9 +177,9 @@ int main(int argc, char *argv[]) } else if (cmd == 'r') { ret = reset_key(kimg_path, out_path, superkey); } else if (cmd == 'l') { - if (kimg_path) print_image_patch_info_path(kimg_path); - if (alone_kpm_path) print_kpm_info_path(alone_kpm_path); - if (kpimg_path) print_kp_image_info_path(kpimg_path); + if (kimg_path) return print_image_patch_info_path(kimg_path); + if (alone_kpm_path) return print_kpm_info_path(alone_kpm_path); + if (kpimg_path) return print_kp_image_info_path(kpimg_path); } else { diff --git a/tools/patch.c b/tools/patch.c index 0d29878d..204f7202 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -67,15 +67,21 @@ void print_preset_info(preset_t *preset) } } -void print_kp_image_info_path(const char *kpimg_path) +int print_kp_image_info_path(const char *kpimg_path) { + int rc = 0; char *kpimg; int len = 0; read_file(kpimg_path, &kpimg, &len); preset_t *preset = (preset_t *)kpimg; - print_preset_info(preset); - fprintf(stdout, "\n"); - free(kpimg); + if (get_preset(kpimg, len) != preset) { + rc = -ENOENT; + } else { + print_preset_info(preset); + fprintf(stdout, "\n"); + free(kpimg); + } + return rc; } int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) @@ -148,8 +154,10 @@ int parse_image_patch_info_path(const char *kimg_path, patched_kimg_t *pimg) return rc; } -void print_image_patch_info(patched_kimg_t *pimg) +int print_image_patch_info(patched_kimg_t *pimg) { + int rc = 0; + preset_t *preset = pimg->preset; fprintf(stdout, INFO_KERNEL_IMG_SESSION "\n"); @@ -187,15 +195,16 @@ void print_image_patch_info(patched_kimg_t *pimg) if (item->type == EXTRA_TYPE_KPM) { kpm_info_t kpm_info = { 0 }; void *kpm = (kpm_info_t *)((uintptr_t)item + sizeof(patch_extra_item_t) + item->args_size); - int rc = get_kpm_info(kpm, item->con_size, &kpm_info); + rc = get_kpm_info(kpm, item->con_size, &kpm_info); if (rc) tools_loge_exit("get kpm infomation error: %d\n", rc); print_kpm_info(&kpm_info); } } } + return rc; } -void print_image_patch_info_path(const char *kimg_path) +int print_image_patch_info_path(const char *kimg_path) { patched_kimg_t pimg = { 0 }; char *kimg; @@ -204,6 +213,7 @@ void print_image_patch_info_path(const char *kimg_path) int rc = parse_image_patch_info(kimg, kimg_len, &pimg); print_image_patch_info(&pimg); free(kimg); + return rc; } int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey, diff --git a/tools/patch.h b/tools/patch.h index 8d949e46..9065bb65 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -42,8 +42,8 @@ int unpatch_img(const char *kimg_path, const char *out_path); int reset_key(const char *kimg_path, const char *out_path, const char *key); int dump_kallsym(const char *kimg_path); -void print_kp_image_info_path(const char *kpimg_path); -void print_image_patch_info(patched_kimg_t *pimg); -void print_image_patch_info_path(const char *kimg_path); +int print_kp_image_info_path(const char *kpimg_path); +int print_image_patch_info(patched_kimg_t *pimg); +int print_image_patch_info_path(const char *kimg_path); #endif From 122404f3effae6a3a057d3be7f9fecf8e85ae4da Mon Sep 17 00:00:00 2001 From: bmax Date: Mon, 5 Feb 2024 11:16:50 +0800 Subject: [PATCH 14/51] a --- kernel/include/predata.h | 2 +- .../linux/arch/arm64/include/asm/processor.h | 22 +---- kernel/linux/arch/arm64/include/asm/ptrace.h | 2 +- kernel/patch/android/kpuserd.c | 98 +++++++++++++------ kernel/patch/android/sucompat.c | 20 ++-- kernel/patch/common/utils.c | 24 +++++ kernel/patch/include/uapi/scdefs.h | 1 + tools/kptools.c | 13 ++- tools/patch.c | 27 ++++- tools/patch.h | 4 +- user/su.c | 2 +- 11 files changed, 147 insertions(+), 68 deletions(-) diff --git a/kernel/include/predata.h b/kernel/include/predata.h index 22be04d2..a0af95ec 100644 --- a/kernel/include/predata.h +++ b/kernel/include/predata.h @@ -7,11 +7,11 @@ #define _KP_PREDATA_H_ #include -#include #include int superkey_auth(const char *key); const char *get_superkey(); +uint64_t get_build_config(); struct patch_symbol *get_preset_patch_sym(); int on_each_extra_item(int (*callback)(const patch_extra_item_t *extra, const char *arg, const void *data, void *udata), void *udata); diff --git a/kernel/linux/arch/arm64/include/asm/processor.h b/kernel/linux/arch/arm64/include/asm/processor.h index 97a0dc2e..9fcdabd1 100644 --- a/kernel/linux/arch/arm64/include/asm/processor.h +++ b/kernel/linux/arch/arm64/include/asm/processor.h @@ -17,26 +17,8 @@ // #define THREAD_START_SP (THREAD_SIZE - 16) // #define task_pt_regs(p) ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) -static inline struct pt_regs *_task_pt_reg(struct task_struct *task) -{ - unsigned long stack = (unsigned long)task_stack_page(task); - uintptr_t addr = (uintptr_t)(thread_size + stack); - if (kver < VERSION(4, 4, 19)) { - // todo: fault on 3.18 ranch-27 - addr -= 16; - addr -= sizeof(struct pt_regs_lt4419); - } else if (kver < VERSION(4, 14, 0)) { - addr -= 16; - addr -= sizeof(struct pt_regs_lt4140); - } else if (kver < VERSION(5, 10, 0)) { - addr -= sizeof(struct pt_regs_lt5100); - } else { - addr -= sizeof(struct pt_regs); - } - struct pt_regs *regs; - regs = (struct pt_regs *)(addr); - return regs; -} +// implemented in utils +struct pt_regs *_task_pt_reg(struct task_struct *task); #define task_pt_regs(p) _task_pt_reg(p) diff --git a/kernel/linux/arch/arm64/include/asm/ptrace.h b/kernel/linux/arch/arm64/include/asm/ptrace.h index fc98797e..63caef6c 100644 --- a/kernel/linux/arch/arm64/include/asm/ptrace.h +++ b/kernel/linux/arch/arm64/include/asm/ptrace.h @@ -276,7 +276,7 @@ static inline void forget_syscall(struct pt_regs *regs) static inline unsigned long user_stack_pointer(struct pt_regs *regs) { - if (compat_user_mode(regs)) return regs->compat_sp; + // if (compat_user_mode(regs)) return regs->compat_sp; return regs->sp; } diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index d73ccbbe..e8f45747 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -35,10 +35,14 @@ const char origin_rc_file[] = "/system/etc/init/atrace.rc"; const char replace_rc_file[] = "/dev/.atrace.rc"; static const char patch_rc[] = "" + "on early-init\n" + " echo 'testabc'\n" "on late-init\n" " rm %s \n" + // " rm " KPATCH_DEV_PATH "\n" "on post-fs-data\n" " start logd\n" + " cp " KPATCH_DEV_PATH " " KPATCH_PATH "\n" " exec -- " KPATCH_SHADOW_PATH " %s android_user init -k\n" " exec -- " KPATCH_SHADOW_PATH " %s android_user post-fs-data -k'\n" "on nonencrypted\n" @@ -68,18 +72,34 @@ static const void *kernel_read_file(const char *path, loff_t *len) return data; } -static void load_config() +static void kernel_write_file(const char *path, const void *data, loff_t len) { set_priv_selinx_allow(current, 1); - + struct file *fp = filp_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0744); + if (IS_ERR(fp)) { + log_boot("create file %s error: %d\n", path, PTR_ERR(fp)); + goto out; + } + loff_t off = 0; + kernel_write(fp, data, len, &off); + if (off != len) { + log_boot("write file %s error: %x\n", path, off); + goto out; + } +out: + filp_close(fp, 0); set_priv_selinx_allow(current, 0); } +static void load_config() +{ +} + static void on_post_fs_data() { - static bool done = false; + static int done = 0; if (done) return; - done = true; + done = 1; set_priv_selinx_allow(current, 1); load_config(); set_priv_selinx_allow(current, 0); @@ -89,6 +109,20 @@ static void on_second_stage() { } +static int extra_call_back(const patch_extra_item_t *extra, const char *arg, const void *con, void *udata) +{ + if (extra->type == EXTRA_TYPE_EXEC && !strcmp("kpatch", extra->name)) { + log_boot("write kpatch to /dev/\n"); + kernel_write_file("/dev/kpatch", con, extra->con_size); + } + return 0; +} + +static void before_first_stage() +{ + on_each_extra_item(extra_call_back, 0); +} + // int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) // int __do_execve_file(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags, // struct file *file); @@ -102,29 +136,39 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) struct filename *filename = (struct filename *)args->args[filename_index]; if (!filename || IS_ERR(filename)) return; + static int init_first_stage_executed = 0; + const char app_process[] = "/system/bin/app_process"; - static bool first_app_process = true; + static int first_app_process = 1; - /* This applies to versions Android 10+ */ + // Android 10+ static const char system_bin_init[] = "/system/bin/init"; - /* This applies to versions between Android 6 ~ 9 */ + // Android 6 ~ 9 static const char old_system_init[] = "/init"; - static bool init_second_stage_executed = false; + static int init_second_stage_executed = 0; if (!memcmp(filename->name, system_bin_init, sizeof(system_bin_init) - 1) || !memcmp(filename->name, old_system_init, sizeof(old_system_init) - 1)) { - for (int i = 1;; i++) { - const char *__user p1 = - get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); - if (!p1) break; - if (!IS_ERR(p1)) { - char arg[16] = { '\0' }; - if (strncpy_from_user_nofault(arg, p1, sizeof(arg)) <= 0) break; - - if (!strcmp(arg, "second_stage")) { - log_boot("0 exec %s second_stage\n", filename->name); - on_second_stage(); - init_second_stage_executed = true; + // + if (!init_first_stage_executed) { + init_first_stage_executed = 1; + before_first_stage(); + return; + } + + if (!init_second_stage_executed) { + for (int i = 1;; i++) { + const char *__user p1 = + get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); + if (!p1) break; + if (!IS_ERR(p1)) { + char arg[16] = { '\0' }; + if (strncpy_from_user_nofault(arg, p1, sizeof(arg)) <= 0) break; + if (!strcmp(arg, "second_stage")) { + log_boot("0 exec %s second_stage\n", filename->name); + on_second_stage(); + init_second_stage_executed = 1; + } } } } @@ -138,19 +182,16 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) char env[256]; if (strncpy_from_user_nofault(env, up, sizeof(env)) <= 0) break; - // Parsing environment variable names and values char *env_name = env; char *env_value = strchr(env, '='); if (env_value) { - // Replace equal sign with string terminator *env_value = '\0'; env_value++; - // Check if the environment variable name and value are matching if (!strcmp(env_name, "INIT_SECOND_STAGE") && - (!strcmp(env_value, "1") || !strcmp(env_value, "true"))) { + (!strcmp(env_value, "1") || !strcmp(env_value, "1"))) { log_boot("1 exec %s second_stage\n", filename->name); on_second_stage(); - init_second_stage_executed = true; + init_second_stage_executed = 1; } } } @@ -158,7 +199,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) } if (unlikely(first_app_process && !memcmp(filename->name, app_process, sizeof(app_process) - 1))) { - first_app_process = false; + first_app_process = 0; log_boot("exec app_process, /data prepared, second_stage: %d\n", init_second_stage_executed); on_post_fs_data(); remove_execv_hook(before_do_execve, 0); @@ -172,7 +213,7 @@ static void before_openat(hook_fargs4_t *args, void *udata) // clear local args->local.data0 = 0; - static bool replaced = false; + static int replaced = 0; if (replaced) return; const char __user *filename = (typeof(filename))syscall_argn(args, 1); @@ -180,7 +221,7 @@ static void before_openat(hook_fargs4_t *args, void *udata) strncpy_from_user_nofault(buf, filename, sizeof(buf)); if (strcmp(origin_rc_file, buf)) return; - replaced = true; + replaced = 1; set_priv_selinx_allow(current, 1); // create replace file and redirect @@ -229,6 +270,7 @@ static void after_openat(hook_fargs4_t *args, void *udata) #define EV_KEY 0x01 #define KEY_VOLUMEDOWN 114 +/* Modified from KernelSU */ // void input_handle_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) static void before_input_handle_event(hook_fargs4_t *args, void *udata) { diff --git a/kernel/patch/android/sucompat.c b/kernel/patch/android/sucompat.c index 59cb55e2..314b3561 100644 --- a/kernel/patch/android/sucompat.c +++ b/kernel/patch/android/sucompat.c @@ -254,6 +254,7 @@ static uid_t current_uid() return uid; } +/* KernelSU idea */ static void *__user copy_to_user_stack(void *data, size_t len) { uintptr_t addr = current_user_stack_pointer(); @@ -270,7 +271,8 @@ static inline char *__user android_sh_user_path() static inline char *__user android_su_user_path() { - return (char *__user)copy_to_user_stack((void *)default_su_path, sizeof(default_su_path)); + int len = strlen(current_su_path); + return (char *__user)copy_to_user_stack((void *)current_su_path, len); } // int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) @@ -309,7 +311,9 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) const char *__user p0 = get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], 0); int sz = seq_copy_to_user((char *__user)p0, default_su_path, sizeof(default_su_path)); - if (sz != sizeof(default_su_path)) logkfe("seq_copy_to_user error: %d\n", sz); + if (sz != sizeof(default_su_path)) { + logkfe("seq_copy_to_user error: %d\n", sz); + } } kvfree(profile); } else if (!strcmp(kpatch_shadow_path, filename->name)) { @@ -393,10 +397,14 @@ static void before_stat(hook_fargs8_t *args, void *udata) } else { logkfd("1 uid: %d\n", uid); int sz = seq_copy_to_user(u_filename, sh_path, sizeof(sh_path)); - if (sz != sizeof(sh_path)) logkfe("seq_copy_to_user error: %d\n", sz); - change_flag = 1; - args->local.data[0] = change_flag; - args->local.data[1] = (uint64_t)local_su_path; + if (sz == sizeof(sh_path)) { + change_flag = 1; + args->local.data[0] = change_flag; + args->local.data[1] = (uint64_t)local_su_path; + } else { + // logkfe("seq_copy_to_user error: %d\n", sz); + args->arg1 = (uint64_t)android_sh_user_path(); + } } } diff --git a/kernel/patch/common/utils.c b/kernel/patch/common/utils.c index 4962a95e..a2894e1d 100644 --- a/kernel/patch/common/utils.c +++ b/kernel/patch/common/utils.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include int trace_seq_copy_to_user(void __user *to, const void *from, int n) { @@ -69,3 +71,25 @@ long strncpy_from_user_nofault(char *dest, const char __user *src, long count) return 0; } KP_EXPORT_SYMBOL(strncpy_from_user_nofault); + +struct pt_regs *_task_pt_reg(struct task_struct *task) +{ + unsigned long stack = (unsigned long)task_stack_page(task); + uintptr_t addr = (uintptr_t)(thread_size + stack); +#ifndef ANDROID + if (kver < VERSION(4, 4, 19)) { + addr -= sizeof(struct pt_regs_lt4419); + } else +#endif + if (kver < VERSION(4, 14, 0)) { + addr -= sizeof(struct pt_regs_lt4140); + } else if (kver < VERSION(5, 10, 0)) { + addr -= sizeof(struct pt_regs_lt5100); + } else { + addr -= sizeof(struct pt_regs); + } + struct pt_regs *regs; + regs = (struct pt_regs *)(addr); + return regs; +} +KP_EXPORT_SYMBOL(_task_pt_reg); \ No newline at end of file diff --git a/kernel/patch/include/uapi/scdefs.h b/kernel/patch/include/uapi/scdefs.h index f435f577..1bc2d448 100644 --- a/kernel/patch/include/uapi/scdefs.h +++ b/kernel/patch/include/uapi/scdefs.h @@ -59,6 +59,7 @@ struct su_profile #define ANDROID_SU_PATH "/system/bin/kp" #define KPATCH_PATH "/data/adb/kpatch" +#define KPATCH_DEV_PATH "/dev/kpatch" #define APD_PATH "/data/adb/apd" #define KPATCH_SHADOW_PATH "/system/bin/truncate" diff --git a/tools/kptools.c b/tools/kptools.c index 03eb213d..a8708823 100644 --- a/tools/kptools.c +++ b/tools/kptools.c @@ -97,14 +97,14 @@ int main(int argc, char *argv[]) char *kpatch_path = NULL; int embed_kpm_num = 0; - char *embed_kpms_path[EXTRA_ITEM_MAX_NUM] = { 0 }; - char *embed_kpms_args[EXTRA_ITEM_MAX_NUM] = { 0 }; + const char *embed_kpms_path[EXTRA_ITEM_MAX_NUM] = { 0 }; + const char *embed_kpms_args[EXTRA_ITEM_MAX_NUM] = { 0 }; int detach_kpm_num = 0; - char *detach_kpms_name[EXTRA_ITEM_MAX_NUM] = { 0 }; + const char *detach_kpms_name[EXTRA_ITEM_MAX_NUM] = { 0 }; int additional_num = 0; - char *additional[16] = { 0 }; + const char *additional[16] = { 0 }; char *alone_kpm_path = NULL; @@ -167,9 +167,8 @@ int main(int argc, char *argv[]) else fprintf(stdout, "%x\n", version); } else if (cmd == 'p') { - ret = patch_update_img(kimg_path, kpimg_path, out_path, superkey, (const char **)embed_kpms_path, - (const char **)embed_kpms_args, (const char **)detach_kpms_name, - (const char **)additional); + ret = patch_update_img(kimg_path, kpimg_path, out_path, superkey, kpatch_path, embed_kpms_path, embed_kpms_args, + detach_kpms_name, additional); } else if (cmd == 'd') { ret = dump_kallsym(kimg_path); } else if (cmd == 'u') { diff --git a/tools/patch.c b/tools/patch.c index 204f7202..88b11964 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -217,8 +217,8 @@ int print_image_patch_info_path(const char *kimg_path) } int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey, - const char **embed_kpm_path, const char **embed_kpm_args, const char **detach_kpm_names, - const char **additional) + const char *kpatch_path, const char **embed_kpm_path, const char **embed_kpm_args, + const char **detach_kpm_names, const char **additional) { set_log_enable(true); @@ -487,6 +487,29 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * write_file(out_path, (void *)item_wrap->data, item_wrap->data_len, true); } + // embed kpatch executable + if (kpatch_path) { + char *con; + int len; + read_file_align(kpatch_path, &con, &len, EXTRA_ALIGN); + patch_extra_item_t kpatch_item = { + .name = "kpatch", + .type = EXTRA_TYPE_EXEC, + .priority = __INT32_MAX__, + .con_size = len, + .args_size = 0, + }; + if ((is_be() ^ kinfo->is_be)) { + kpatch_item.priority = i32swp(kpatch_item.priority); + kpatch_item.type = i32swp(kpatch_item.type); + kpatch_item.con_size = i32swp(kpatch_item.con_size); + kpatch_item.args_size = i32swp(kpatch_item.args_size); + } + tools_logi("embedding kpatch executable, size: 0x%x\n", len); + write_file(out_path, (void *)&kpatch_item, sizeof(kpatch_item), true); + write_file(out_path, (void *)con, len, true); + } + // guard extra patch_extra_item_t empty_item = { .type = EXTRA_TYPE_NONE, diff --git a/tools/patch.h b/tools/patch.h index 9065bb65..067b04fc 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -36,8 +36,8 @@ preset_t *get_preset(const char *kimg, int kimg_len); uint32_t get_kpimg_version(const char *kpimg_path); int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey, - const char **embed_kpm_path, const char **embed_kpm_args, const char **detach_kpm_names, - const char **additional); + const char *kpatch_path, const char **embed_kpm_path, const char **embed_kpm_args, + const char **detach_kpm_names, const char **additional); int unpatch_img(const char *kimg_path, const char *out_path); int reset_key(const char *kimg_path, const char *out_path, const char *key); int dump_kallsym(const char *kimg_path); diff --git a/user/su.c b/user/su.c index 737cb1f8..e0421899 100644 --- a/user/su.c +++ b/user/su.c @@ -168,7 +168,7 @@ static void usage(int status) "-i, --target-isolate Use new isolated namespace if -t is specified.\n " "-s, --shell SHELL use SHELL instead of the default\n" "-, -l, --login Pretend the shell to be a login shell\n" - "-Z, -x, --context SCONTEXT Switch security context to SCONTEXT, If SCONTEXT is not specified\n" + "-Z, --context SCONTEXT Switch security context to SCONTEXT, If SCONTEXT is not specified\n" " or specified with a non-existent value, bypass all selinux permission\n" " checks for all calls initiated by this task using hooks, \n" " but the permission determined by other task remain unchanged. \n" From e63c3cd6ad4c4e485561574061c55e99476db506 Mon Sep 17 00:00:00 2001 From: bmax Date: Mon, 5 Feb 2024 11:31:35 +0800 Subject: [PATCH 15/51] tools fix linux header --- tools/patch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/patch.c b/tools/patch.c index 88b11964..1d06ddcd 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -3,6 +3,9 @@ * Copyright (C) 2024 bmax121. All Rights Reserved. */ +#define _GNU_SOURCE +#define __USE_GNU + #include #include #include @@ -11,9 +14,6 @@ #include #include -#define _GNU_SOURCE -#define __USE_GNU - #include "patch.h" #include "kallsym.h" #include "image.h" From b3ad1b6f3ee50e3bad64bb010ed2d6b40e21819f Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 6 Feb 2024 17:42:56 +0800 Subject: [PATCH 16/51] a --- kernel/patch/android/kpuserd.c | 57 +++++++++++++-------------------- kernel/patch/android/sucompat.c | 20 +++++++----- tools/patch.c | 37 +++++++++++++++++++-- user/android/android_user.c | 16 ++++----- 4 files changed, 78 insertions(+), 52 deletions(-) diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index e8f45747..36395023 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -35,22 +35,19 @@ const char origin_rc_file[] = "/system/etc/init/atrace.rc"; const char replace_rc_file[] = "/dev/.atrace.rc"; static const char patch_rc[] = "" - "on early-init\n" - " echo 'testabc'\n" "on late-init\n" " rm %s \n" - // " rm " KPATCH_DEV_PATH "\n" "on post-fs-data\n" " start logd\n" - " cp " KPATCH_DEV_PATH " " KPATCH_PATH "\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user init -k\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user post-fs-data -k'\n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user init -k --path " KPATCH_DEV_PATH + " \n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user post-fs-data -k \n" "on nonencrypted\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k'\n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k \n" "on property:vold.decrypt=trigger_restart_framework\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k'\n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k \n" "on property:sys.boot_completed=1\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user boot-completed -k'\n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user boot-completed -k \n" "\n" ""; @@ -84,43 +81,37 @@ static void kernel_write_file(const char *path, const void *data, loff_t len) kernel_write(fp, data, len, &off); if (off != len) { log_boot("write file %s error: %x\n", path, off); - goto out; + goto free; } -out: +free: filp_close(fp, 0); +out: set_priv_selinx_allow(current, 0); } -static void load_config() +static int extract_kpatch_call_back(const patch_extra_item_t *extra, const char *arg, const void *con, void *udata) { + const char *path = (const char *)udata; + if (extra->type == EXTRA_TYPE_EXEC && !strcmp("kpatch", extra->name)) { + log_boot("write kpatch to %s\n", path); + kernel_write_file(path, con, extra->con_size); + } + return 0; } -static void on_post_fs_data() +static void on_first_stage() { - static int done = 0; - if (done) return; - done = 1; - set_priv_selinx_allow(current, 1); - load_config(); - set_priv_selinx_allow(current, 0); } static void on_second_stage() { + log_boot("on_second_stage\n"); + const char *path = KPATCH_DEV_PATH; + on_each_extra_item(extract_kpatch_call_back, (void *)path); } -static int extra_call_back(const patch_extra_item_t *extra, const char *arg, const void *con, void *udata) -{ - if (extra->type == EXTRA_TYPE_EXEC && !strcmp("kpatch", extra->name)) { - log_boot("write kpatch to /dev/\n"); - kernel_write_file("/dev/kpatch", con, extra->con_size); - } - return 0; -} - -static void before_first_stage() +static void on_post_fs_data() { - on_each_extra_item(extra_call_back, 0); } // int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) @@ -152,8 +143,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) // if (!init_first_stage_executed) { init_first_stage_executed = 1; - before_first_stage(); - return; + on_first_stage(); } if (!init_second_stage_executed) { @@ -181,14 +171,13 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) if (!up || IS_ERR(up)) break; char env[256]; if (strncpy_from_user_nofault(env, up, sizeof(env)) <= 0) break; - char *env_name = env; char *env_value = strchr(env, '='); if (env_value) { *env_value = '\0'; env_value++; if (!strcmp(env_name, "INIT_SECOND_STAGE") && - (!strcmp(env_value, "1") || !strcmp(env_value, "1"))) { + (!strcmp(env_value, "1") || !strcmp(env_value, "true"))) { log_boot("1 exec %s second_stage\n", filename->name); on_second_stage(); init_second_stage_executed = 1; diff --git a/kernel/patch/android/sucompat.c b/kernel/patch/android/sucompat.c index 314b3561..e37c3487 100644 --- a/kernel/patch/android/sucompat.c +++ b/kernel/patch/android/sucompat.c @@ -325,18 +325,22 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) if (superkey_auth(arg1)) return; commit_su(0, 0); strcpy((char *)filename->name, kpatch_path); - // log - char log_buf[512]; - int log_off = 0; - for (int i = 2; i < 6; i++) { + // args + char option[128]; + for (int i = 2; i < 10; i++) { const char *pn = get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); if (!pn || IS_ERR(pn)) break; - log_off += strncpy_from_user_nofault(log_buf + log_off, pn, sizeof(log_buf) - log_off); - log_buf[log_off - 1] = ' '; + strncpy_from_user_nofault(option, pn, sizeof(option)); + if (!strcmp("--path", option)) { + i++; + pn = + get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); + if (!pn || IS_ERR(pn)) break; + strncpy_from_user_nofault(option, pn, sizeof(option)); + strcpy((char *)filename->name, option); + } } - log_buf[log_off > 0 ? log_off - 1 : 0] = '\0'; - logkfd("%s ****** %s\n", filename->name, log_buf); } return; diff --git a/tools/patch.c b/tools/patch.c index 1d06ddcd..7c812741 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -355,7 +355,33 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * extra_num++; } - extra_size += sizeof(patch_extra_item_t); + // embed kpatch executable + if (kpatch_path) { + char *con; + int len; + read_file_align(kpatch_path, &con, &len, EXTRA_ALIGN); + + struct extra_items_wrap *item_wrap = extra_items + extra_num; + patch_extra_item_t *kpatch_item = &item_wrap->item; + item_wrap->name = "kpatch"; + item_wrap->data = con; + item_wrap->data_len = len; + strcpy(kpatch_item->name, "kpatch"); + kpatch_item->type = EXTRA_TYPE_EXEC; + kpatch_item->priority = __INT32_MAX__; + kpatch_item->con_size = len; + kpatch_item->args_size = 0; + if ((is_be() ^ kinfo->is_be)) { + kpatch_item->priority = i32swp(kpatch_item->priority); + kpatch_item->type = i32swp(kpatch_item->type); + kpatch_item->con_size = i32swp(kpatch_item->con_size); + kpatch_item->args_size = i32swp(kpatch_item->args_size); + } + extra_num++; + extra_size += len; + } + + extra_size += sizeof(patch_extra_item_t); // ending with empty item // copy to out image int ori_kimg_len = pimg.ori_kimg_len; @@ -394,7 +420,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * setup->page_shift = kinfo->page_shift; setup->setup_offset = align_kimg_len; setup->start_offset = align_kernel_size; - setup->extra_size = extra_size; // ending with empty item + setup->extra_size = extra_size; int map_start, map_max_size; select_map_area(&kallsym, kallsym_kimg, &map_start, &map_max_size); @@ -474,7 +500,14 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * case EXTRA_TYPE_SHELL: type = "shell"; break; + case EXTRA_TYPE_EXEC: + type = "exec"; + break; + case EXTRA_TYPE_RAW: + type = "raw"; + break; default: + type = "none"; break; } diff --git a/user/android/android_user.c b/user/android/android_user.c index b2195163..fad1778d 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -197,12 +197,6 @@ static void fork_for_result(const char *exec, char *const *argv) } } -static void load_magisk_policy() -{ - char *argv[] = { magiskpolicy_path, "--magisk", "--live", NULL }; - fork_for_result(magiskpolicy_path, argv); -} - static void init() { struct su_profile profile = { .uid = getuid() }; @@ -215,13 +209,19 @@ static void init() if (from_kernel) save_dmegs(boot0_log_path); - log_kernel("%d load selinux policy.\n", getpid()); - load_magisk_policy(); log_kernel("%d reset su path.\n", getpid()); load_config_su_path(); log_kernel("%d load allow uids.\n", getpid()); load_config_allow_uids(); + char current_path[32] = { '\0' }; + if (readlink("/proc/self/exe", current_path, sizeof(current_path) - 1)) { + char *const argv[] = { "/system/bin/cp", "-f", current_path, KPATCH_PATH, NULL }; + fork_for_result(argv[0], argv); + char *const rm_argv[] = { "/system/bin/rm", "-f", current_path, NULL }; + fork_for_result(rm_argv[0], rm_argv); + } + log_kernel("%d finished android user init.\n", getpid()); if (from_kernel) save_dmegs(boot1_log_path); From 4f6641aa33ae17818131bf8eed12d14a68072d9d Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 6 Feb 2024 17:44:05 +0800 Subject: [PATCH 17/51] a --- user/android/android_user.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/user/android/android_user.c b/user/android/android_user.c index fad1778d..917dd2d2 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -216,10 +216,12 @@ static void init() char current_path[32] = { '\0' }; if (readlink("/proc/self/exe", current_path, sizeof(current_path) - 1)) { - char *const argv[] = { "/system/bin/cp", "-f", current_path, KPATCH_PATH, NULL }; - fork_for_result(argv[0], argv); - char *const rm_argv[] = { "/system/bin/rm", "-f", current_path, NULL }; - fork_for_result(rm_argv[0], rm_argv); + if (!strcmp(current_path, KPATCH_DEV_PATH)) { + char *const argv[] = { "/system/bin/cp", "-f", current_path, KPATCH_PATH, NULL }; + fork_for_result(argv[0], argv); + char *const rm_argv[] = { "/system/bin/rm", "-f", current_path, NULL }; + fork_for_result(rm_argv[0], rm_argv); + } } log_kernel("%d finished android user init.\n", getpid()); From e71a8d76ffaa95f8d74f55f10c2b82d817d257a3 Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 6 Feb 2024 22:59:46 +0800 Subject: [PATCH 18/51] x --- kernel/patch/android/kpuserd.c | 25 +++++++++++-------------- tools/patch.c | 1 - user/android/android_user.c | 34 ++++++++++++++++++++-------------- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index 36395023..17bf0b0f 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -31,14 +31,12 @@ #include #include -const char origin_rc_file[] = "/system/etc/init/atrace.rc"; -const char replace_rc_file[] = "/dev/.atrace.rc"; +#define ORIGIN_RC_FILE "/system/etc/init/atrace.rc" +#define REPLACE_RC_FILE "/dev/.atrace.rc" -static const char patch_rc[] = "" - "on late-init\n" - " rm %s \n" +static const char patch_rc[] = "on late-init\n" + " rm " REPLACE_RC_FILE " \n" "on post-fs-data\n" - " start logd\n" " exec -- " KPATCH_SHADOW_PATH " %s android_user init -k --path " KPATCH_DEV_PATH " \n" " exec -- " KPATCH_SHADOW_PATH " %s android_user post-fs-data -k \n" @@ -208,23 +206,23 @@ static void before_openat(hook_fargs4_t *args, void *udata) const char __user *filename = (typeof(filename))syscall_argn(args, 1); char buf[32]; strncpy_from_user_nofault(buf, filename, sizeof(buf)); - if (strcmp(origin_rc_file, buf)) return; + if (strcmp(ORIGIN_RC_FILE, buf)) return; replaced = 1; set_priv_selinx_allow(current, 1); // create replace file and redirect loff_t ori_len = 0; - struct file *newfp = filp_open(replace_rc_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); + struct file *newfp = filp_open(REPLACE_RC_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (IS_ERR(newfp)) { log_boot("create replace rc error: %d\n", PTR_ERR(newfp)); goto out; } - const char *ori_rc_data = kernel_read_file(origin_rc_file, &ori_len); + const char *ori_rc_data = kernel_read_file(ORIGIN_RC_FILE, &ori_len); if (!ori_rc_data) goto out; - char *replace_rc_data = vmalloc(sizeof(patch_rc) + sizeof(replace_rc_file) + 5 * SUPER_KEY_LEN); + char *replace_rc_data = vmalloc(sizeof(patch_rc) + 5 * SUPER_KEY_LEN); const char *superkey = get_superkey(); - sprintf(replace_rc_data, patch_rc, replace_rc_file, superkey, superkey, superkey, superkey, superkey); + sprintf(replace_rc_data, patch_rc, superkey, superkey, superkey, superkey, superkey); loff_t off = 0; kernel_write(newfp, replace_rc_data, strlen(replace_rc_data), &off); kernel_write(newfp, ori_rc_data, ori_len, &off); @@ -233,7 +231,7 @@ static void before_openat(hook_fargs4_t *args, void *udata) goto free; } // yes, filename is not read only - args->local.data0 = seq_copy_to_user((void *)filename, replace_rc_file, sizeof(replace_rc_file)); + args->local.data0 = seq_copy_to_user((void *)filename, REPLACE_RC_FILE, sizeof(REPLACE_RC_FILE)); log_boot("redirect rc file: %x\n", args->local.data0); free: filp_close(newfp, 0); @@ -249,9 +247,8 @@ static void after_openat(hook_fargs4_t *args, void *udata) { if (args->local.data0) { const char __user *filename = (typeof(filename))syscall_argn(args, 1); - int len = seq_copy_to_user((void *)filename, origin_rc_file, sizeof(origin_rc_file)); + int len = seq_copy_to_user((void *)filename, ORIGIN_RC_FILE, sizeof(ORIGIN_RC_FILE)); log_boot("restore rc file: %x\n", len); - // todo: fp_unhook_syscall(__NR_openat, before_openat, after_openat); } } diff --git a/tools/patch.c b/tools/patch.c index 7c812741..ededa434 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -538,7 +538,6 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * kpatch_item.con_size = i32swp(kpatch_item.con_size); kpatch_item.args_size = i32swp(kpatch_item.args_size); } - tools_logi("embedding kpatch executable, size: 0x%x\n", len); write_file(out_path, (void *)&kpatch_item, sizeof(kpatch_item), true); write_file(out_path, (void *)con, len, true); } diff --git a/user/android/android_user.c b/user/android/android_user.c index 917dd2d2..f8c9a985 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -112,7 +112,7 @@ static void load_config_allow_uids() FILE *fallow = fopen(pkg_cfg_path, "r"); if (fallow == NULL) { - log_kernel("%d open %s error: %s", getpid(), pkg_cfg_path, strerror(errno)); + log_kernel("%d open %s error: %s\n", getpid(), pkg_cfg_path, strerror(errno)); return; } @@ -166,7 +166,7 @@ static void load_config_su_path() { FILE *file = fopen(su_path_path, "rb"); if (file == NULL) { - log_kernel("%d open %s error: %s", getpid(), su_path_path, strerror(errno)); + log_kernel("%d open %s error: %s\n", getpid(), su_path_path, strerror(errno)); return; } char linebuf[SU_PATH_MAX_LEN] = { '\0' }; @@ -204,26 +204,32 @@ static void init() log_kernel("%d starting android user init, from kernel: %d\n", getpid(), from_kernel); - if (!opendir(APATCH_FLODER)) mkdir(APATCH_FLODER, 0700); - if (!opendir(APATCH_LOG_FLODER)) mkdir(APATCH_LOG_FLODER, 0700); + bool init_apatch = true; + + if (!access(APATCH_FLODER, F_OK)) mkdir(APATCH_FLODER, 0700); + if (!access(APATCH_LOG_FLODER, F_OK)) mkdir(APATCH_LOG_FLODER, 0700); if (from_kernel) save_dmegs(boot0_log_path); - log_kernel("%d reset su path.\n", getpid()); - load_config_su_path(); - log_kernel("%d load allow uids.\n", getpid()); - load_config_allow_uids(); + char current_exe[32] = { '\0' }; + if (readlink("/proc/self/exe", current_exe, sizeof(current_exe) - 1)) { + if (!strcmp(current_exe, KPATCH_DEV_PATH)) { + log_kernel("%d copy %s to %s.\n", getpid(), current_exe, KPATCH_PATH); + + char *const cp_argv[] = { "/system/bin/cp", current_exe, KPATCH_PATH, NULL }; + fork_for_result(cp_argv[0], cp_argv); - char current_path[32] = { '\0' }; - if (readlink("/proc/self/exe", current_path, sizeof(current_path) - 1)) { - if (!strcmp(current_path, KPATCH_DEV_PATH)) { - char *const argv[] = { "/system/bin/cp", "-f", current_path, KPATCH_PATH, NULL }; - fork_for_result(argv[0], argv); - char *const rm_argv[] = { "/system/bin/rm", "-f", current_path, NULL }; + char *const rm_argv[] = { "/system/bin/rm", current_exe, NULL }; fork_for_result(rm_argv[0], rm_argv); } } + char *argv[] = { magiskpolicy_path, "--magisk", "--live", NULL }; + fork_for_result(magiskpolicy_path, argv); + + load_config_su_path(); + load_config_allow_uids(); + log_kernel("%d finished android user init.\n", getpid()); if (from_kernel) save_dmegs(boot1_log_path); From 40fc30856c2cad04e7406451d7cda13016e16631 Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 7 Feb 2024 10:10:56 +0800 Subject: [PATCH 19/51] x --- kernel/patch/android/kpuserd.c | 23 ++++++++++++----------- kernel/patch/common/supercall.c | 1 - tools/patch.c | 4 +++- user/android/android_user.c | 24 +++++++++++++++++------- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index 17bf0b0f..91887ee5 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -34,19 +34,20 @@ #define ORIGIN_RC_FILE "/system/etc/init/atrace.rc" #define REPLACE_RC_FILE "/dev/.atrace.rc" -static const char patch_rc[] = "on late-init\n" - " rm " REPLACE_RC_FILE " \n" +static const char patch_rc[] = "" + "\n" + "on late-init\n" + " rm " REPLACE_RC_FILE "\n" "on post-fs-data\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user init -k --path " KPATCH_DEV_PATH - " \n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user post-fs-data -k \n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user init -k --path " KPATCH_DEV_PATH "\n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user post-fs-data -k\n" "on nonencrypted\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k \n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k\n" "on property:vold.decrypt=trigger_restart_framework\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k \n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k\n" "on property:sys.boot_completed=1\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user boot-completed -k \n" - "\n" + " exec -- " KPATCH_SHADOW_PATH " %s android_user boot-completed -k\n" + "\n\n" ""; static const void *kernel_read_file(const char *path, loff_t *len) @@ -108,7 +109,7 @@ static void on_second_stage() on_each_extra_item(extract_kpatch_call_back, (void *)path); } -static void on_post_fs_data() +static void on_zygote_start() { } @@ -188,7 +189,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) if (unlikely(first_app_process && !memcmp(filename->name, app_process, sizeof(app_process) - 1))) { first_app_process = 0; log_boot("exec app_process, /data prepared, second_stage: %d\n", init_second_stage_executed); - on_post_fs_data(); + on_zygote_start(); remove_execv_hook(before_do_execve, 0); } } diff --git a/kernel/patch/common/supercall.c b/kernel/patch/common/supercall.c index 0335cb5d..7a16812b 100644 --- a/kernel/patch/common/supercall.c +++ b/kernel/patch/common/supercall.c @@ -159,7 +159,6 @@ static long supercall(long cmd, long arg1, long arg2, long arg3, long arg4) case SUPERCALL_KERNEL_VER: return kver; } - logkd("supercall with cmd: %x\n", cmd); switch (cmd) { case SUPERCALL_SU: return call_su((struct su_profile * __user) arg1); diff --git a/tools/patch.c b/tools/patch.c index ededa434..dc7a499b 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -216,6 +216,7 @@ int print_image_patch_info_path(const char *kimg_path) return rc; } +// todo: opt int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey, const char *kpatch_path, const char **embed_kpm_path, const char **embed_kpm_args, const char **detach_kpm_names, const char **additional) @@ -255,7 +256,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * int extra_size = 0; int extra_num = 0; - struct extra_items_wrap + struct extra_items_wrap // todo: opt { patch_extra_item_t item; const char *name; @@ -363,6 +364,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * struct extra_items_wrap *item_wrap = extra_items + extra_num; patch_extra_item_t *kpatch_item = &item_wrap->item; + item_wrap->type = EXTRA_TYPE_EXEC; item_wrap->name = "kpatch"; item_wrap->data = con; item_wrap->data_len = len; diff --git a/user/android/android_user.c b/user/android/android_user.c index f8c9a985..8d83cd19 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -32,6 +32,7 @@ struct allow_pkg_info static char magiskpolicy_path[] = APATCH_BIN_FLODER "magiskpolicy"; static char pkg_cfg_path[] = APATCH_FLODER "package_config"; static char su_path_path[] = APATCH_FLODER "su_path"; +static char skip_sepolicy_path[] = APATCH_FLODER "skip_sepolicy"; static char boot0_log_path[] = APATCH_LOG_FLODER "kpatch_0.log"; static char boot1_log_path[] = APATCH_LOG_FLODER "kpatch_1.log"; @@ -178,6 +179,12 @@ static void load_config_su_path() static void fork_for_result(const char *exec, char *const *argv) { + char cmd[512] = { '\0' }; + for (int i = 0;; i++) { + if (!argv[i]) break; + strncat(cmd, argv[i], sizeof(cmd) - strlen(cmd) - 1); + } + pid_t pid = fork(); if (pid < 0) { log_kernel("%d fork %s error: %d\n", getpid(), exec, pid); @@ -189,11 +196,11 @@ static void fork_for_result(const char *exec, char *const *argv) sprintf(kver, "%x", sc_k_ver(key)); setenv("KERNEL_VER", kver, 1); int rc = execv(exec, argv); - log_kernel("%d exec %s error: %s\n", getpid(), exec, strerror(errno)); + log_kernel("%d exec %s error: %s\n", getpid(), cmd, strerror(errno)); } else { int status; wait(&status); - log_kernel("%d wait %s status: 0x%x\n", getpid(), exec, status); + log_kernel("%d wait %s status: 0x%x\n", getpid(), cmd, status); } } @@ -204,8 +211,6 @@ static void init() log_kernel("%d starting android user init, from kernel: %d\n", getpid(), from_kernel); - bool init_apatch = true; - if (!access(APATCH_FLODER, F_OK)) mkdir(APATCH_FLODER, 0700); if (!access(APATCH_LOG_FLODER, F_OK)) mkdir(APATCH_LOG_FLODER, 0700); @@ -224,8 +229,10 @@ static void init() } } - char *argv[] = { magiskpolicy_path, "--magisk", "--live", NULL }; - fork_for_result(magiskpolicy_path, argv); + if (!access(skip_sepolicy_path, F_OK)) { + char *argv[] = { magiskpolicy_path, "--magisk", "--live", NULL }; + fork_for_result(magiskpolicy_path, argv); + } load_config_su_path(); load_config_allow_uids(); @@ -235,7 +242,10 @@ static void init() if (from_kernel) save_dmegs(boot1_log_path); } -static struct option const longopts[] = { { "kernel", no_argument, NULL, 'k' }, { NULL, 0, NULL, 0 } }; +static struct option const longopts[] = { + { "kernel", no_argument, NULL, 'k' }, + { NULL, 0, NULL, 0 }, +}; int android_user(int argc, char **argv) { From cf984828577e1edaacce0e6c5c9a0ebabb95cfd8 Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 15 Feb 2024 23:15:33 +0800 Subject: [PATCH 20/51] tmp save --- kernel/include/preset.h | 16 +- kernel/patch/android/kpuserd.c | 14 +- tools/kptools.c | 111 ++++++----- tools/patch.c | 331 ++++++++++++++------------------- tools/patch.h | 25 ++- 5 files changed, 252 insertions(+), 245 deletions(-) diff --git a/kernel/include/preset.h b/kernel/include/preset.h index f830f218..69d4d35a 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -32,7 +32,7 @@ #define ADDITIONAL_LEN (256) -#define PATCH_EXTRA_ITEM_LEN (64) +#define PATCH_EXTRA_ITEM_LEN (128) #define VERSION(major, minor, patch) (((major) << 16) + ((minor) << 8) + (patch)) @@ -138,6 +138,7 @@ _Static_assert(sizeof(patch_symbol_t) == PATCH_SYMBOL_LEN, "sizeof patch_symbol_ #define EXTRA_ALIGN 0x10 #define EXTRA_NAME_LEN 0x20 +#define EXTRA_EVENT_LEN 0x20 typedef int32_t extra_item_type; @@ -146,6 +147,14 @@ typedef int32_t extra_item_type; #define EXTRA_TYPE_SHELL 2 #define EXTRA_TYPE_EXEC 3 #define EXTRA_TYPE_RAW 4 +#define EXTRA_TYPE_ANDROID_RC 5 + +#define EXTRA_TYPE_NONE_STR "none" +#define EXTRA_TYPE_KPM_STR "kpm" +#define EXTRA_TYPE_SHELL_STR "shell" +#define EXTRA_TYPE_EXEC_STR "exec" +#define EXTRA_TYPE_RAW_STR "raw" +#define EXTRA_TYPE_ANDROID_RC_STR "android_rc" struct _patch_extra_item { @@ -153,11 +162,12 @@ struct _patch_extra_item { struct { - char name[EXTRA_NAME_LEN]; extra_item_type type; + char name[EXTRA_NAME_LEN]; + char event[EXTRA_EVENT_LEN]; int32_t priority; - int32_t con_size; int32_t args_size; + int32_t con_size; }; char _cap[PATCH_EXTRA_ITEM_LEN]; }; diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index 91887ee5..866a677d 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -37,7 +37,7 @@ static const char patch_rc[] = "" "\n" "on late-init\n" - " rm " REPLACE_RC_FILE "\n" + // " rm " REPLACE_RC_FILE "\n" "on post-fs-data\n" " exec -- " KPATCH_SHADOW_PATH " %s android_user init -k --path " KPATCH_DEV_PATH "\n" " exec -- " KPATCH_SHADOW_PATH " %s android_user post-fs-data -k\n" @@ -100,11 +100,12 @@ static int extract_kpatch_call_back(const patch_extra_item_t *extra, const char static void on_first_stage() { + // const char *path = KPATCH_DEV_PATH; + // on_each_extra_item(extract_kpatch_call_back, (void *)path); } static void on_second_stage() { - log_boot("on_second_stage\n"); const char *path = KPATCH_DEV_PATH; on_each_extra_item(extract_kpatch_call_back, (void *)path); } @@ -131,9 +132,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) const char app_process[] = "/system/bin/app_process"; static int first_app_process = 1; - // Android 10+ static const char system_bin_init[] = "/system/bin/init"; - // Android 6 ~ 9 static const char old_system_init[] = "/init"; static int init_second_stage_executed = 0; @@ -142,6 +141,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) // if (!init_first_stage_executed) { init_first_stage_executed = 1; + log_boot("exec %s first stage\n", filename->name); on_first_stage(); } @@ -153,8 +153,8 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) if (!IS_ERR(p1)) { char arg[16] = { '\0' }; if (strncpy_from_user_nofault(arg, p1, sizeof(arg)) <= 0) break; - if (!strcmp(arg, "second_stage")) { - log_boot("0 exec %s second_stage\n", filename->name); + if (!strcmp(arg, "second stage")) { + log_boot("exec %s second stage 0\n", filename->name); on_second_stage(); init_second_stage_executed = 1; } @@ -177,7 +177,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) env_value++; if (!strcmp(env_name, "INIT_SECOND_STAGE") && (!strcmp(env_value, "1") || !strcmp(env_value, "true"))) { - log_boot("1 exec %s second_stage\n", filename->name); + log_boot("exec %s second stage 1\n", filename->name); on_second_stage(); init_second_stage_executed = 1; } diff --git a/tools/kptools.c b/tools/kptools.c index a8708823..1c841130 100644 --- a/tools/kptools.c +++ b/tools/kptools.c @@ -36,28 +36,34 @@ void print_usage(char **argv) "Usage: %s COMMAND [Options...]\n" "\n" "COMMAND:\n" - " -h, --help Print this message.\n" - " -v, --version Print version number. Print kpimg version if -k specified.\n" + " -h, --help Print this message.\n" + " -v, --version Print version number. Print kpimg version if -k specified.\n" - " -p, --patch Patch or Update patch of kernel image(-i) with specified kpimg(-k) and superkey(-s).\n" - " -u, --unpatch Unpatch patched kernel image(-i).\n" - " -r, --resetkey Reset superkey of patched image(-i).\n" - " -d, --dump Dump kallsyms infomations of kernel image(-i).\n" - " -l, --list Print all patch informations of kernel image if -i specified.\n" - " Print KPM informations if -M specified.\n" - " Print KernelPatch image informations if -k specified.\n" + " -p, --patch Patch or Update patch of kernel image(-i) with specified kpimg(-k) and superkey(-s).\n" + " -u, --unpatch Unpatch patched kernel image(-i).\n" + " -r, --reset-skey Reset superkey of patched image(-i).\n" + " -d, --dump Dump kallsyms infomations of kernel image(-i).\n" + " -l, --list Print all patch informations of kernel image if (-i) specified.\n" + " Print extra item informations if (-M) specified.\n" + " Print KernelPatch image informations if (-k) specified.\n" "Options:\n" - " -i, --image PATH Kernel image path.\n" - " -k, --kpimg PATH KernelPatch image path.\n" - " -o, --out PATH Patched image path.\n" - " -K, --kpatch PATH Embed kpatch executable binary into patches.\n" - - " -E, --embed-kpm PATH Embed KPM into patches.\n" - " -A, --embed-kpm-args ARGS Arguments will be passed to previous KPM(-E).\n" - " -D, --detach-kpm NAME Detach embeded KPM from patches.\n" - " -M, --kpm PATH Specify KPM path.\n" - " -a --addition KEY=VALUE Add additional information.\n" + " -i, --image PATH Kernel image path.\n" + " -k, --kpimg PATH KernelPatch image path.\n" + " -s, --skey PATH Set superkey.\n" + " -o, --out PATH Patched image path.\n" + " -a --addition KEY=VALUE Add additional information.\n" + + " -K, --kpatch PATH Embed kpatch executable binary into patches.\n" + + " -M, --embed-extra-path PATH Embed new extra item.\n" + " -E, --embeded-extra-name NAME Preserve and modifiy embedded extra item.\n" + + " -T, --extra-type TYPE Set type of previous extra item.\n" + " -N, --extra-name NAME Set name of previous extra item.\n" + " -V, --extra-event EVENT Set trigger event of previous extra item.\n" + " -A, --extra-args ARGS Set arguments of previous extra item.\n" + " -D, --extra-detach Detach previous extra item from patches.\n" "\n"; fprintf(stdout, c, version, program_name); } @@ -74,21 +80,25 @@ int main(int argc, char *argv[]) { "unpatch", no_argument, NULL, 'u' }, { "resetkey", no_argument, NULL, 'r' }, { "dump", no_argument, NULL, 'd' }, + { "list", no_argument, NULL, 'l' }, { "image", required_argument, NULL, 'i' }, { "kpimg", required_argument, NULL, 'k' }, { "skey", required_argument, NULL, 's' }, { "out", required_argument, NULL, 'o' }, + { "addition", required_argument, NULL, 'a' }, { "kpatch", required_argument, NULL, 'K' }, - { "embed-kpm", required_argument, NULL, 'E' }, - { "embed-kpm-args", required_argument, NULL, 'A' }, - { "detach-kpm", required_argument, NULL, 'D' }, - { "kpm", required_argument, NULL, 'M' }, - { "addition", required_argument, NULL, 'a' }, + { "embed-extra-path", required_argument, NULL, 'M' }, + { "embeded-extra-name", required_argument, NULL, 'E' }, + { "extra-type", required_argument, NULL, 'T' }, + { "extra-name", required_argument, NULL, 'N' }, + { "extra-event", required_argument, NULL, 'V' }, + { "extra-args", required_argument, NULL, 'A' }, + { "extra-detach", no_argument, NULL, 'D' }, { 0, 0, 0, 0 } }; - char *optstr = "hvpurdli:s:k:o:K:E:A:D:M:a:"; + char *optstr = "hvpurdli:s:k:o:K:M:E:T:N:V:A:D"; char *kimg_path = NULL; char *kpimg_path = NULL; @@ -96,17 +106,12 @@ int main(int argc, char *argv[]) char *superkey = NULL; char *kpatch_path = NULL; - int embed_kpm_num = 0; - const char *embed_kpms_path[EXTRA_ITEM_MAX_NUM] = { 0 }; - const char *embed_kpms_args[EXTRA_ITEM_MAX_NUM] = { 0 }; - - int detach_kpm_num = 0; - const char *detach_kpms_name[EXTRA_ITEM_MAX_NUM] = { 0 }; - int additional_num = 0; const char *additional[16] = { 0 }; - char *alone_kpm_path = NULL; + int extra_config_num = 0; + extra_config_t extra_configs[EXTRA_ITEM_MAX_NUM] = { 0 }; + extra_config_t *config = NULL; char cmd = '\0'; int opt = -1; @@ -135,23 +140,39 @@ int main(int argc, char *argv[]) case 'o': out_path = optarg; break; + case 'a': + additional[additional_num++] = optarg; + break; case 'K': kpatch_path = optarg; break; + case 'M': + config = &extra_configs[extra_config_num++]; + config->is_path = true; + config->path = optarg; + break; case 'E': - embed_kpms_path[embed_kpm_num++] = optarg; + config = &extra_configs[extra_config_num++]; + config->is_path = false; + config->name = optarg; break; - case 'A': - embed_kpms_args[embed_kpm_num - 1] = optarg; + case 'T': + config->extra_type = extra_str_type(optarg); + if (config->extra_type == EXTRA_TYPE_NONE) { + tools_loge_exit("invalid extra type: %s\n", optarg); + } break; - case 'D': - detach_kpms_name[detach_kpm_num++] = optarg; + case 'V': + config->set_event = optarg; break; - case 'M': - alone_kpm_path = optarg; + case 'N': + config->name = optarg; break; - case 'a': - additional[additional_num++] = optarg; + case 'A': + config->set_args = optarg; + break; + case 'D': + config->set_detach = true; break; default: break; @@ -167,8 +188,8 @@ int main(int argc, char *argv[]) else fprintf(stdout, "%x\n", version); } else if (cmd == 'p') { - ret = patch_update_img(kimg_path, kpimg_path, out_path, superkey, kpatch_path, embed_kpms_path, embed_kpms_args, - detach_kpms_name, additional); + ret = patch_update_img(kimg_path, kpimg_path, out_path, superkey, additional, kpatch_path, extra_configs, + extra_config_num); } else if (cmd == 'd') { ret = dump_kallsym(kimg_path); } else if (cmd == 'u') { @@ -177,7 +198,7 @@ int main(int argc, char *argv[]) ret = reset_key(kimg_path, out_path, superkey); } else if (cmd == 'l') { if (kimg_path) return print_image_patch_info_path(kimg_path); - if (alone_kpm_path) return print_kpm_info_path(alone_kpm_path); + if (config && config->path) return print_kpm_info_path(config->path); if (kpimg_path) return print_kp_image_info_path(kpimg_path); } diff --git a/tools/patch.c b/tools/patch.c index dc7a499b..3210b236 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -41,6 +41,42 @@ uint32_t get_kpimg_version(const char *kpimg_path) return version; } +int extra_str_type(const char *extra_str) +{ + int extra_type = EXTRA_TYPE_NONE; + if (!strcmp(extra_str, EXTRA_TYPE_KPM_STR)) { + extra_type = EXTRA_TYPE_KPM; + } else if (!strcmp(extra_str, EXTRA_TYPE_EXEC_STR)) { + extra_type = EXTRA_TYPE_EXEC; + } else if (!strcmp(extra_str, EXTRA_TYPE_SHELL_STR)) { + extra_type = EXTRA_TYPE_SHELL; + } else if (!strcmp(extra_str, EXTRA_TYPE_RAW_STR)) { + extra_type = EXTRA_TYPE_RAW; + } else if (!strcmp(extra_str, EXTRA_TYPE_ANDROID_RC_STR)) { + extra_type = EXTRA_TYPE_ANDROID_RC; + } else { + } + return extra_type; +} + +const char *extra_type_str(extra_item_type extra_type) +{ + switch (extra_type) { + case EXTRA_TYPE_KPM: + return EXTRA_TYPE_KPM_STR; + case EXTRA_TYPE_EXEC: + return EXTRA_TYPE_EXEC_STR; + case EXTRA_TYPE_SHELL: + return EXTRA_TYPE_SHELL_STR; + case EXTRA_TYPE_RAW: + return EXTRA_TYPE_RAW_STR; + case EXTRA_TYPE_ANDROID_RC: + return EXTRA_TYPE_ANDROID_RC_STR; + default: + return EXTRA_TYPE_NONE_STR; + } +} + void print_preset_info(preset_t *preset) { setup_header_t *header = &preset->header; @@ -172,24 +208,13 @@ int print_image_patch_info(patched_kimg_t *pimg) for (int i = 0; i < pimg->embed_item_num; i++) { patch_extra_item_t *item = pimg->embed_item[i]; - const char *type = "none"; - switch (item->type) { - case EXTRA_TYPE_KPM: - type = "kpm"; - break; - case EXTRA_TYPE_SHELL: - type = "shell"; - break; - case EXTRA_TYPE_EXEC: - type = "exec"; - break; - case EXTRA_TYPE_RAW: - type = "raw"; - break; - } + const char *type = extra_type_str(item->type); fprintf(stdout, INFO_EXTRA_SESSION_N "\n", i); fprintf(stdout, "index=%d\n", i); fprintf(stdout, "type=%s\n", type); + fprintf(stdout, "name=%s\n", item->name); + fprintf(stdout, "event=%s\n", item->event); + fprintf(stdout, "priority=%d\n", item->priority); fprintf(stdout, "con_size=0x%x\n", item->con_size); fprintf(stdout, "args_size=0x%x\n", item->args_size); if (item->type == EXTRA_TYPE_KPM) { @@ -216,10 +241,16 @@ int print_image_patch_info_path(const char *kimg_path) return rc; } -// todo: opt +static int extra_compare(const void *a, const void *b) +{ + extra_config_t *pa = (extra_config_t *)a; + extra_config_t *pb = (extra_config_t *)b; + return -(pa->priority - pb->priority); +} + int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey, - const char *kpatch_path, const char **embed_kpm_path, const char **embed_kpm_args, - const char **detach_kpm_names, const char **additional) + const char **additional, const char *kpatch_path, extra_config_t *extra_configs, + int extra_config_num) { set_log_enable(true); @@ -252,139 +283,98 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * int kpimg_len = 0; read_file_align(kpimg_path, &kpimg, &kpimg_len, 0x10); + // embed kpatch executable + if (kpatch_path) { + // add new + extra_config_t *config = extra_configs + extra_config_num; + extra_config_num++; + config->extra_type = EXTRA_TYPE_EXEC; + config->is_path = true; + config->path = kpatch_path; + config->priority = __INT32_MAX__; + config->set_name = "kpatch"; + } + // extra int extra_size = 0; int extra_num = 0; - struct extra_items_wrap // todo: opt - { - patch_extra_item_t item; - const char *name; - extra_item_type type; - const char *data; - const char *args; - int data_len; - int args_len; - } *extra_items = (struct extra_items_wrap *)malloc(sizeof(struct extra_items_wrap) * EXTRA_ITEM_MAX_NUM); - - memset(extra_items, 0, sizeof(struct extra_items_wrap) * EXTRA_ITEM_MAX_NUM); - - // reserved patched extra - for (int i = 0; i < pimg.embed_item_num; i++) { - struct extra_items_wrap *item_wrap = extra_items + extra_num; - patch_extra_item_t *item = pimg.embed_item[i]; - - item_wrap->type = item->type; - if ((is_be() ^ kinfo->is_be)) item_wrap->type = i32swp(item_wrap->type); - - bool detach = false; - - if (item_wrap->type == EXTRA_TYPE_KPM) { - kpm_info_t kpm_info = { 0 }; - void *kpm = (kpm_info_t *)((uintptr_t)item + sizeof(patch_extra_item_t) + item->args_size); - get_kpm_info(kpm, item->con_size, &kpm_info); - for (int j = 0;; j++) { - if (!detach_kpm_names[j]) break; - if (!strcmp(detach_kpm_names[j], kpm_info.name)) { - detach = true; - break; + for (int i = 0; i < extra_config_num; i++) { + extra_config_t *config = extra_configs + i; + if (config->is_path && config->extra_type == EXTRA_TYPE_NONE) { + tools_loge_exit("extra type none\n"); + } + if (config->set_event && strnlen(config->set_event, EXTRA_EVENT_LEN) >= EXTRA_EVENT_LEN) { + tools_loge_exit("extra event too long: %s\n", config->set_event); + } + if (config->set_name && strnlen(config->set_name, EXTRA_NAME_LEN) >= EXTRA_NAME_LEN) { + tools_loge_exit("extra name too long: %s\n", config->set_event); + } + + patch_extra_item_t *item = NULL; + if (config->is_path) { + item = (patch_extra_item_t *)malloc(sizeof(patch_extra_item_t)); + const char *path = config->path; + char *data; + int len = 0; + read_file_align(path, &data, &len, EXTRA_ALIGN); + config->data = data; + item->con_size = len; + // if name not set + if (!config->set_name) { + if (config->extra_type == EXTRA_TYPE_KPM) { + kpm_info_t kpm_info = { 0 }; + int rc = get_kpm_info(data, len, &kpm_info); + if (rc) tools_loge_exit("can get infomation of kpm, path: %s\n", path); + strcpy(item->name, kpm_info.name); + } else { + char *rsp = strrchr(path, '/'); + strncpy(item->name, rsp ? rsp + 1 : path, EXTRA_NAME_LEN - 1); } } - if (!detach) { - memcpy(&item_wrap->item, item, sizeof(*item)); - item_wrap->data = (const char *)kpm; - item_wrap->args = (const char *)item + sizeof(*item); - item_wrap->data_len = item->con_size; - item_wrap->args_len = item->args_size; - if ((is_be() ^ kinfo->is_be)) { - item_wrap->data_len = i32swp(item_wrap->data_len); - item_wrap->args_len = i32swp(item_wrap->args_len); + } else { + const char *name = config->name; + for (int j = 0; j < pimg.embed_item_num; j++) { + if (config->set_detach) continue; + if (strcmp(name, config->item->name)) continue; + item = pimg.embed_item[j]; + if (is_be() ^ kinfo->is_be) { + item->type = i32swp(item->type); + item->priority = i32swp(item->priority); + item->con_size = i32swp(item->con_size); + item->args_size = i32swp(item->args_size); } - item_wrap->name = kpm_info.name; - - extra_size += sizeof(*item) + item_wrap->data_len + item_wrap->args_len; - extra_num++; - tools_logi("reserved embeded kpm: %s\n", kpm_info.name); - } else { - tools_logi("detact embeded kpm: %s\n", kpm_info.name); + if (!config->set_args && item->args_size > 0) { + config->set_args = (char *)item + sizeof(*item); + } + config->extra_type = item->type; + config->data = (char *)item + sizeof(*item) + item->args_size; + break; } - } else { - // todo } + if (!item) tools_loge_exit("empty extra item\n"); + config->item = item; + item->type = config->extra_type; + if (config->set_args) item->args_size = align_ceil(strlen(config->set_args), EXTRA_ALIGN); + if (config->set_name) strcpy(item->name, config->set_name); + if (config->set_event) strcpy(item->event, config->set_event); + if (config->priority) item->priority = config->priority; } - // new extra - for (int i = 0; extra_num < EXTRA_ITEM_MAX_NUM; i++) { - if (!embed_kpm_path[i]) break; - - char *kpm_data; - int kpm_len = 0; - int args_len = 0; - read_file_align(embed_kpm_path[i], &kpm_data, &kpm_len, EXTRA_ALIGN); - - kpm_info_t kpm_info = { 0 }; - int rc = get_kpm_info(kpm_data, kpm_len, &kpm_info); - if (rc) tools_loge_exit("can get infomation of kpm, path: %s\n", embed_kpm_path[i]); - - struct extra_items_wrap *item_wrap = extra_items + extra_num; - patch_extra_item_t *item = &item_wrap->item; - - // set wrap - const char *args = embed_kpm_args[i]; - if (args) args_len = align_ceil(strlen(args), EXTRA_ALIGN); - item_wrap->type = EXTRA_TYPE_KPM; - item_wrap->data = kpm_data; - item_wrap->data_len = kpm_len; - item_wrap->args = args; - item_wrap->args_len = args_len; - item_wrap->name = kpm_info.name; - - // set runtime item - strcpy(item->name, kpm_info.name); - item->priority = 0; - item->type = EXTRA_TYPE_KPM; - item->con_size = kpm_len; - item->args_size = args_len; - if ((is_be() ^ kinfo->is_be)) { - item->priority = i32swp(item->priority); - item->type = i32swp(item->type); - item->con_size = i32swp(item->con_size); - item->args_size = i32swp(item->args_size); - } + qsort(extra_configs, extra_config_num, sizeof(extra_config_t), extra_compare); - extra_size += (kpm_len + args_len + sizeof(patch_extra_item_t)); - extra_num++; - } + extra_size += sizeof(patch_extra_item_t); // ending with empty item - // embed kpatch executable - if (kpatch_path) { - char *con; - int len; - read_file_align(kpatch_path, &con, &len, EXTRA_ALIGN); - - struct extra_items_wrap *item_wrap = extra_items + extra_num; - patch_extra_item_t *kpatch_item = &item_wrap->item; - item_wrap->type = EXTRA_TYPE_EXEC; - item_wrap->name = "kpatch"; - item_wrap->data = con; - item_wrap->data_len = len; - strcpy(kpatch_item->name, "kpatch"); - kpatch_item->type = EXTRA_TYPE_EXEC; - kpatch_item->priority = __INT32_MAX__; - kpatch_item->con_size = len; - kpatch_item->args_size = 0; - if ((is_be() ^ kinfo->is_be)) { - kpatch_item->priority = i32swp(kpatch_item->priority); - kpatch_item->type = i32swp(kpatch_item->type); - kpatch_item->con_size = i32swp(kpatch_item->con_size); - kpatch_item->args_size = i32swp(kpatch_item->args_size); - } + for (int i = 0; i < extra_config_num; i++) { + extra_config_t *config = extra_configs + i; + if (config->set_detach) continue; extra_num++; - extra_size += len; + extra_size += sizeof(patch_extra_item_t); + extra_size += config->item->args_size; + extra_size += config->item->con_size; + tools_logi("extra item num: %d, size: 0x%x\n", extra_num, extra_size); } - extra_size += sizeof(patch_extra_item_t); // ending with empty item - // copy to out image int ori_kimg_len = pimg.ori_kimg_len; int align_kimg_len = align_ceil(ori_kimg_len, SZ_4K); @@ -492,68 +482,33 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * write_file(out_path, out_img, out_img_len, false); // write extra - for (int i = 0; i < extra_num; i++) { - struct extra_items_wrap *item_wrap = &extra_items[i]; - const char *type = EXTRA_TYPE_NONE; - switch (item_wrap->type) { - case EXTRA_TYPE_KPM: - type = "kpm"; - break; - case EXTRA_TYPE_SHELL: - type = "shell"; - break; - case EXTRA_TYPE_EXEC: - type = "exec"; - break; - case EXTRA_TYPE_RAW: - type = "raw"; - break; - default: - type = "none"; - break; - } + for (int i = 0; i < extra_config_num; i++) { + extra_config_t *config = extra_configs + i; + patch_extra_item_t *item = config->item; + const char *type = extra_type_str(item->type); + tools_logi("embedding %s, name: %s, priority: %d, event: %s, size: 0x%x+0x%x+0x%x\n", type, item->name, + item->priority, item->event, (int)sizeof(*item), item->args_size, item->con_size); - patch_extra_item_t *item = &item_wrap->item; - tools_logi("embedding %s, name: %s, size: 0x%x + 0x%x + 0x%x\n", type, item_wrap->name, (int)sizeof(*item), - item_wrap->args_len, item_wrap->data_len); + int args_len = item->args_size; + int con_len = item->con_size; - write_file(out_path, (void *)item, sizeof(*item), true); - if (item_wrap->args_len > 0) write_file(out_path, (void *)item_wrap->args, item_wrap->args_len, true); - write_file(out_path, (void *)item_wrap->data, item_wrap->data_len, true); - } - - // embed kpatch executable - if (kpatch_path) { - char *con; - int len; - read_file_align(kpatch_path, &con, &len, EXTRA_ALIGN); - patch_extra_item_t kpatch_item = { - .name = "kpatch", - .type = EXTRA_TYPE_EXEC, - .priority = __INT32_MAX__, - .con_size = len, - .args_size = 0, - }; - if ((is_be() ^ kinfo->is_be)) { - kpatch_item.priority = i32swp(kpatch_item.priority); - kpatch_item.type = i32swp(kpatch_item.type); - kpatch_item.con_size = i32swp(kpatch_item.con_size); - kpatch_item.args_size = i32swp(kpatch_item.args_size); + if (is_be() ^ kinfo->is_be) { + item->type = i32swp(item->type); + item->priority = i32swp(item->priority); + item->con_size = i32swp(item->con_size); + item->args_size = i32swp(item->args_size); } - write_file(out_path, (void *)&kpatch_item, sizeof(kpatch_item), true); - write_file(out_path, (void *)con, len, true); + + write_file(out_path, (void *)item, sizeof(*item), true); + if (args_len > 0) write_file(out_path, (void *)config->set_args, args_len, true); + write_file(out_path, (void *)config->data, con_len, true); } // guard extra - patch_extra_item_t empty_item = { - .type = EXTRA_TYPE_NONE, - .priority = 0, - .con_size = 0, - }; + patch_extra_item_t empty_item = { 0 }; write_file(out_path, (void *)&empty_item, sizeof(empty_item), true); // free - free(extra_items); free(kallsym_kimg); free(kpimg); free(out_img); diff --git a/tools/patch.h b/tools/patch.h index 067b04fc..23a54a7a 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -8,6 +8,7 @@ #include #include +#include #include "preset.h" #include "image.h" @@ -32,12 +33,32 @@ typedef struct patch_extra_item_t *embed_item[EXTRA_ITEM_MAX_NUM]; } patched_kimg_t; +typedef struct +{ + int extra_type; + bool is_path; + union + { + const char *path; + const char *name; + }; + const char *set_args; + const char *set_name; + const char *set_event; + int priority; + bool set_detach; + const char *data; + patch_extra_item_t *item; +} extra_config_t; + preset_t *get_preset(const char *kimg, int kimg_len); uint32_t get_kpimg_version(const char *kpimg_path); +int extra_str_type(const char *extra_str); +const char *extra_type_str(extra_item_type extra_type); int patch_update_img(const char *kimg_path, const char *kpimg_path, const char *out_path, const char *superkey, - const char *kpatch_path, const char **embed_kpm_path, const char **embed_kpm_args, - const char **detach_kpm_names, const char **additional); + const char **additional, const char *kpatch_path, extra_config_t *extra_configs, + int extra_config_num); int unpatch_img(const char *kimg_path, const char *out_path); int reset_key(const char *kimg_path, const char *out_path, const char *key); int dump_kallsym(const char *kimg_path); From 311dfd3523abba8e551f36c8043750b4fcd225dc Mon Sep 17 00:00:00 2001 From: bmax Date: Fri, 16 Feb 2024 22:14:18 +0800 Subject: [PATCH 21/51] x --- kernel/linux/include/linux/fs.h | 49 ++++++--------- kernel/linux/include/uapi/linux/limits.h | 21 +++++++ kernel/patch/android/kpuserd.c | 79 ++++++++++++------------ kernel/patch/android/sucompat.c | 69 +++++++++++++++------ kernel/patch/common/taskob.c | 2 +- kernel/patch/include/ksyms.h | 2 + kernel/patch/include/uapi/scdefs.h | 7 +++ kernel/patch/ksyms/misc.c | 8 ++- user/android/android_user.c | 16 ++--- 9 files changed, 154 insertions(+), 99 deletions(-) create mode 100644 kernel/linux/include/uapi/linux/limits.h diff --git a/kernel/linux/include/linux/fs.h b/kernel/linux/include/linux/fs.h index ead837a7..799980a8 100644 --- a/kernel/linux/include/linux/fs.h +++ b/kernel/linux/include/linux/fs.h @@ -240,6 +240,8 @@ extern int kfunc_def(filp_close)(struct file *, fl_owner_t id); extern struct filename *kfunc_def(getname)(const char __user *); extern struct filename *kfunc_def(getname_kernel)(const char *); +extern void kfunc_def(putname)(struct filename *name); +extern void kfunc_def(final_putname)(struct filename *name); extern loff_t kfunc_def(vfs_llseek)(struct file *file, loff_t offset, int whence); @@ -248,25 +250,21 @@ extern loff_t kfunc_def(vfs_llseek)(struct file *file, loff_t offset, int whence static inline void inc_nlink(struct inode *inode) { kfunc_call_void(inc_nlink, inode); - kfunc_not_found(); } static inline void drop_nlink(struct inode *inode) { kfunc_call_void(drop_nlink, inode); - kfunc_not_found(); } static inline void clear_nlink(struct inode *inode) { kfunc_call_void(clear_nlink, inode); - kfunc_not_found(); } static inline void set_nlink(struct inode *inode, unsigned int nlink) { kfunc_call_void(set_nlink, inode, nlink); - kfunc_not_found(); } static inline ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos) @@ -315,66 +313,55 @@ static inline ssize_t kernel_write(struct file *file, const void *buf, size_t co static inline struct file *open_exec(const char *name) { - kfunc_call(open_exec, name); - kfunc_not_found(); - return 0; + kfunc_direct_call(open_exec, name); } static inline struct file *file_open_name(struct filename *name, int flags, umode_t mode) { - kfunc_call(file_open_name, name, flags, mode); - kfunc_not_found(); - return 0; + kfunc_direct_call(file_open_name, name, flags, mode); } static inline struct file *filp_open(const char *filename, int flags, umode_t mode) { - kfunc_call(filp_open, filename, flags, mode); - kfunc_not_found(); - return 0; + kfunc_direct_call(filp_open, filename, flags, mode); } static inline struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt, const char *filename, int flags, umode_t mode) { - kfunc_call(file_open_root, dentry, mnt, filename, flags, mode); - kfunc_not_found(); - return 0; + kfunc_direct_call(file_open_root, dentry, mnt, filename, flags, mode); } static inline struct file *dentry_open(const struct path *path, int flags, const struct cred *cred) { - kfunc_call(dentry_open, path, flags, cred); - kfunc_not_found(); - return 0; + kfunc_direct_call(dentry_open, path, flags, cred); } static inline int filp_close(struct file *filp, fl_owner_t id) { - kfunc_call(filp_close, filp, id); - kfunc_not_found(); - return 0; + kfunc_direct_call(filp_close, filp, id); } static inline struct filename *getname(const char __user *filename) { - kfunc_call(getname, filename); - kfunc_not_found(); - return 0; + kfunc_direct_call(getname, filename); } static inline struct filename *getname_kernel(const char *filename) { - kfunc_call(getname_kernel, filename); - kfunc_not_found(); - return 0; + kfunc_direct_call(getname_kernel, filename); } static inline loff_t vfs_llseek(struct file *file, loff_t offset, int whence) { - kfunc_call(vfs_llseek, file, offset, whence); - kfunc_not_found(); - return 0; + kfunc_direct_call(vfs_llseek, file, offset, whence); +} + +static inline void putname(struct filename *name) +{ + // logkd("aaaaaaaaaaa %llx\n", kfunc(putname)); + kfunc_direct_call_void(putname, name); + // kfunc_direct_call_void(final_putname, name); } #endif \ No newline at end of file diff --git a/kernel/linux/include/uapi/linux/limits.h b/kernel/linux/include/uapi/linux/limits.h new file mode 100644 index 00000000..5842f28e --- /dev/null +++ b/kernel/linux/include/uapi/linux/limits.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_LIMITS_H +#define _UAPI_LINUX_LIMITS_H + +#define NR_OPEN 1024 + +#define NGROUPS_MAX 65536 /* supplemental group IDs are available */ +#define ARG_MAX 131072 /* # bytes of args + environ for exec() */ +#define LINK_MAX 127 /* # links a file may have */ +#define MAX_CANON 255 /* size of the canonical input queue */ +#define MAX_INPUT 255 /* size of the type-ahead buffer */ +#define NAME_MAX 255 /* # chars in a file name */ +#define PATH_MAX 4096 /* # chars in a path name including nul */ +#define PIPE_BUF 4096 /* # bytes in atomic write to a pipe */ +#define XATTR_NAME_MAX 255 /* # chars in an extended attribute name */ +#define XATTR_SIZE_MAX 65536 /* size of an extended attribute value (64k) */ +#define XATTR_LIST_MAX 65536 /* size of extended attribute namelist (64k) */ + +#define RTSIG_MAX 32 + +#endif \ No newline at end of file diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index 866a677d..248ddcbb 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -34,21 +34,22 @@ #define ORIGIN_RC_FILE "/system/etc/init/atrace.rc" #define REPLACE_RC_FILE "/dev/.atrace.rc" -static const char patch_rc[] = "" - "\n" - "on late-init\n" - // " rm " REPLACE_RC_FILE "\n" - "on post-fs-data\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user init -k --path " KPATCH_DEV_PATH "\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user post-fs-data -k\n" - "on nonencrypted\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k\n" - "on property:vold.decrypt=trigger_restart_framework\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user services -k\n" - "on property:sys.boot_completed=1\n" - " exec -- " KPATCH_SHADOW_PATH " %s android_user boot-completed -k\n" - "\n\n" - ""; +static const char patch_rc[] = + "" + "\n" + "on late-init\n" + " rm " REPLACE_RC_FILE "\n" + "on post-fs-data\n" + " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_DEV_PATH " %s android_user post-fs-data-init -k\n" + " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_PATH " %s android_user post-fs-data -k\n" + "on nonencrypted\n" + " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_PATH " %s android_user services -k\n" + "on property:vold.decrypt=trigger_restart_framework\n" + " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_PATH " %s android_user services -k\n" + "on property:sys.boot_completed=1\n" + " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_PATH " %s android_user boot-completed -k\n" + "\n\n" + ""; static const void *kernel_read_file(const char *path, loff_t *len) { @@ -68,10 +69,10 @@ static const void *kernel_read_file(const char *path, loff_t *len) return data; } -static void kernel_write_file(const char *path, const void *data, loff_t len) +static void kernel_write_file(const char *path, const void *data, loff_t len, umode_t mode) { set_priv_selinx_allow(current, 1); - struct file *fp = filp_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0744); + struct file *fp = filp_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode); if (IS_ERR(fp)) { log_boot("create file %s error: %d\n", path, PTR_ERR(fp)); goto out; @@ -88,26 +89,29 @@ static void kernel_write_file(const char *path, const void *data, loff_t len) set_priv_selinx_allow(current, 0); } +static void kernel_write_exec(const char *path, const void *data, loff_t len) +{ + kernel_write_file(path, data, len, 0744); +} + static int extract_kpatch_call_back(const patch_extra_item_t *extra, const char *arg, const void *con, void *udata) { const char *path = (const char *)udata; if (extra->type == EXTRA_TYPE_EXEC && !strcmp("kpatch", extra->name)) { log_boot("write kpatch to %s\n", path); - kernel_write_file(path, con, extra->con_size); + kernel_write_exec(path, con, extra->con_size); } return 0; } -static void on_first_stage() +static void before_first_stage() { - // const char *path = KPATCH_DEV_PATH; - // on_each_extra_item(extract_kpatch_call_back, (void *)path); + const char *path = KPATCH_DEV_PATH; + on_each_extra_item(extract_kpatch_call_back, (void *)path); } -static void on_second_stage() +static void before_second_stage() { - const char *path = KPATCH_DEV_PATH; - on_each_extra_item(extract_kpatch_call_back, (void *)path); } static void on_zygote_start() @@ -127,22 +131,20 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) struct filename *filename = (struct filename *)args->args[filename_index]; if (!filename || IS_ERR(filename)) return; - static int init_first_stage_executed = 0; - const char app_process[] = "/system/bin/app_process"; static int first_app_process = 1; static const char system_bin_init[] = "/system/bin/init"; - static const char old_system_init[] = "/init"; + static const char root_init[] = "/init"; + static int init_first_stage_executed = 0; static int init_second_stage_executed = 0; - if (!memcmp(filename->name, system_bin_init, sizeof(system_bin_init) - 1) || - !memcmp(filename->name, old_system_init, sizeof(old_system_init) - 1)) { + if (!strcmp(system_bin_init, filename->name) || !strcmp(root_init, filename->name)) { // if (!init_first_stage_executed) { init_first_stage_executed = 1; log_boot("exec %s first stage\n", filename->name); - on_first_stage(); + before_first_stage(); } if (!init_second_stage_executed) { @@ -153,9 +155,9 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) if (!IS_ERR(p1)) { char arg[16] = { '\0' }; if (strncpy_from_user_nofault(arg, p1, sizeof(arg)) <= 0) break; - if (!strcmp(arg, "second stage")) { + if (!strcmp(arg, "second_stage") || !strcmp(arg, "--second-stage")) { log_boot("exec %s second stage 0\n", filename->name); - on_second_stage(); + before_second_stage(); init_second_stage_executed = 1; } } @@ -167,7 +169,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) for (int i = 0;; i++) { const char *__user up = get_user_arg_ptr((void *)args->args[envp_index], (void *)args->args[envp_index + 1], i); - if (!up || IS_ERR(up)) break; + if (IS_ERR(up)) break; char env[256]; if (strncpy_from_user_nofault(env, up, sizeof(env)) <= 0) break; char *env_name = env; @@ -178,7 +180,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) if (!strcmp(env_name, "INIT_SECOND_STAGE") && (!strcmp(env_value, "1") || !strcmp(env_value, "true"))) { log_boot("exec %s second stage 1\n", filename->name); - on_second_stage(); + before_second_stage(); init_second_stage_executed = 1; } } @@ -186,7 +188,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) } } - if (unlikely(first_app_process && !memcmp(filename->name, app_process, sizeof(app_process) - 1))) { + if (unlikely(first_app_process && !strcmp(app_process, filename->name))) { first_app_process = 0; log_boot("exec app_process, /data prepared, second_stage: %d\n", init_second_stage_executed); on_zygote_start(); @@ -221,9 +223,10 @@ static void before_openat(hook_fargs4_t *args, void *udata) } const char *ori_rc_data = kernel_read_file(ORIGIN_RC_FILE, &ori_len); if (!ori_rc_data) goto out; - char *replace_rc_data = vmalloc(sizeof(patch_rc) + 5 * SUPER_KEY_LEN); + char *replace_rc_data = vmalloc(sizeof(patch_rc) + 10 * SUPER_KEY_LEN); const char *superkey = get_superkey(); - sprintf(replace_rc_data, patch_rc, superkey, superkey, superkey, superkey, superkey); + sprintf(replace_rc_data, patch_rc, superkey, superkey, superkey, superkey, superkey, superkey, superkey, superkey, + superkey, superkey); loff_t off = 0; kernel_write(newfp, replace_rc_data, strlen(replace_rc_data), &off); kernel_write(newfp, ori_rc_data, ori_len, &off); @@ -270,7 +273,7 @@ static void before_input_handle_event(hook_fargs4_t *args, void *udata) if (volumedown_pressed_count == 3) { log_boot("entering safemode ..."); struct file *filp = filp_open(SAFE_MODE_FLAG_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0666); - if (filp && !IS_ERR(filp)) filp_close(filp, 0); + if (!IS_ERR(filp)) filp_close(filp, 0); } } } diff --git a/kernel/patch/android/sucompat.c b/kernel/patch/android/sucompat.c index e37c3487..33b7b338 100644 --- a/kernel/patch/android/sucompat.c +++ b/kernel/patch/android/sucompat.c @@ -33,13 +33,14 @@ #include #include #include +#include #include +#include static const char sh_path[] = ANDROID_SH_PATH; static const char default_su_path[] = ANDROID_SU_PATH; static const char *current_su_path = 0; static const char apd_path[] = APD_PATH; -static const char kpatch_path[] = KPATCH_PATH; static const char kpatch_shadow_path[] = KPATCH_SHADOW_PATH; struct allow_uid @@ -289,7 +290,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) } filename = (struct filename *)args->args[filename_index]; - if (!filename || IS_ERR(filename)) return; + if (IS_ERR(filename)) return; if (!strcmp(current_su_path, filename->name)) { uid_t uid = current_uid(); @@ -317,30 +318,58 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) } kvfree(profile); } else if (!strcmp(kpatch_shadow_path, filename->name)) { - const char __user *p1 = - get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], 1); - if (!p1 || IS_ERR(p1)) return; + void *ua0 = (void *)args->args[filename_index + 1]; + void *ua1 = (void *)args->args[filename_index + 2]; + // key + const char __user *p1 = get_user_arg_ptr(ua0, ua1, 1); + if (IS_ERR(p1)) return; + + // auth skey char arg1[SUPER_KEY_LEN]; if (strncpy_from_user_nofault(arg1, p1, sizeof(arg1)) <= 0) return; if (superkey_auth(arg1)) return; + commit_su(0, 0); - strcpy((char *)filename->name, kpatch_path); - // args - char option[128]; - for (int i = 2; i < 10; i++) { - const char *pn = - get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); - if (!pn || IS_ERR(pn)) break; - strncpy_from_user_nofault(option, pn, sizeof(option)); - if (!strcmp("--path", option)) { - i++; - pn = - get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); - if (!pn || IS_ERR(pn)) break; - strncpy_from_user_nofault(option, pn, sizeof(option)); - strcpy((char *)filename->name, option); + + // real exec + const char __user *p2 = get_user_arg_ptr(ua0, ua1, 2); + + if (IS_ERR(p2)) { + strcpy((char *)filename->name, sh_path); + return; + } + +#define EMBEDDED_NAME_MAX (PATH_MAX - sizeof(*filename) - 128) // enough + + int len = strncpy_from_user_nofault((char *)filename->name, p2, EMBEDDED_NAME_MAX); + if (unlikely(len < 0)) return; + + // user_arg_ptr + if (has_config_compat) { + if (ua0) { + args->args[filename_index + 2] += 2 * 4; + } else { + args->args[filename_index + 2] += 2 * 8; } + } else { + args->args[filename_index + 1] += 2 * 8; } + + // char option[128]; + // for (int i = 3; i < 10; i++) { + // const char *pn = + // get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); + // if (IS_ERR(pn)) break; + // strncpy_from_user_nofault(option, pn, sizeof(option)); + // if (!strcmp("--path", option)) { + // i++; + // pn = + // get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); + // if (IS_ERR(pn)) break; + // strncpy_from_user_nofault(option, pn, sizeof(option)); + // strcpy((char *)filename->name, option); + // } + // } } return; diff --git a/kernel/patch/common/taskob.c b/kernel/patch/common/taskob.c index e272fb30..07f790e0 100644 --- a/kernel/patch/common/taskob.c +++ b/kernel/patch/common/taskob.c @@ -56,7 +56,7 @@ static struct task_struct *(*backup_copy_process)(void *a0, void *a1, void *a2, struct task_struct *replace_copy_process(void *a0, void *a1, void *a2, void *a3, void *a4, void *a5, void *a6, void *a7) { struct task_struct *new = backup_copy_process(a0, a1, a2, a3, a4, a5, a6, a7); - if (unlikely(IS_ERR_VALUE(new))) return new; + if (unlikely(IS_ERR(new))) return new; prepare_task_ext(new, current); return new; } diff --git a/kernel/patch/include/ksyms.h b/kernel/patch/include/ksyms.h index dcbab95d..a325f426 100644 --- a/kernel/patch/include/ksyms.h +++ b/kernel/patch/include/ksyms.h @@ -46,6 +46,8 @@ int _ksym_local_strcmp(const char *s1, const char *s2); #define kfunc_call_void(func, ...) \ if (kf_##func) kf_##func(__VA_ARGS__); +#define kfunc_direct_call_void(func, ...) kf_##func(__VA_ARGS__); + // todo #define kfunc_not_found() logke("kfunc: %s not found\n", __func__); diff --git a/kernel/patch/include/uapi/scdefs.h b/kernel/patch/include/uapi/scdefs.h index 1bc2d448..762b08e4 100644 --- a/kernel/patch/include/uapi/scdefs.h +++ b/kernel/patch/include/uapi/scdefs.h @@ -37,6 +37,13 @@ static inline long hash_key(const char *key) #define SUPERCALL_KPM_LIST 0x1031 #define SUPERCALL_KPM_INFO 0x1032 +#define SUPERCALL_MEM_USER_PHYS 0x1041 +#define SUPERCALL_MEM_KERNEL_PHYS 0x1042 +#define SUPERCALL_MEM_MAP_KERNEL 0x1048 +#define SUPERCALL_MEM_MAP_USER 0x1049 +#define SUPERCALL_MEM_PROT 0x1049 +#define SUPERCALL_MEM_CACHE_FLUSH 0x1049 + #define SUPERCALL_BOOTLOG 0x10fd #define SUPERCALL_PANIC 0x10fe #define SUPERCALL_TEST 0x10ff diff --git a/kernel/patch/ksyms/misc.c b/kernel/patch/ksyms/misc.c index 1df424fd..72d6bfa5 100644 --- a/kernel/patch/ksyms/misc.c +++ b/kernel/patch/ksyms/misc.c @@ -438,6 +438,8 @@ int kfunc_def(filp_close)(struct file *, fl_owner_t id) = 0; struct filename *kfunc_def(getname)(const char __user *) = 0; struct filename *kfunc_def(getname_kernel)(const char *) = 0; +void kfunc_def(putname)(struct filename *name) = 0; +void kfunc_def(final_putname)(struct filename *name) = 0; loff_t kfunc_def(vfs_llseek)(struct file *file, loff_t offset, int whence) = 0; @@ -455,8 +457,10 @@ static void _linux_fs_sym_match(const char *name, unsigned long addr) // kfunc_match(file_open_root, name, addr); // kfunc_match(dentry_open, name, addr); kfunc_match(filp_close, name, addr); - // kfunc_match(getname, name, addr); - // kfunc_match(getname_kernel, name, addr); + kfunc_match(getname, name, addr); + kfunc_match(getname_kernel, name, addr); + kfunc_match(putname, name, addr); + kfunc_match(final_putname, name, addr); kfunc_match(vfs_llseek, name, addr); } diff --git a/user/android/android_user.c b/user/android/android_user.c index 8d83cd19..cf6adab4 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -179,10 +179,11 @@ static void load_config_su_path() static void fork_for_result(const char *exec, char *const *argv) { - char cmd[512] = { '\0' }; + char cmd[4096] = { '\0' }; for (int i = 0;; i++) { if (!argv[i]) break; strncat(cmd, argv[i], sizeof(cmd) - strlen(cmd) - 1); + strncat(cmd, " ", sizeof(cmd) - strlen(cmd) - 1); } pid_t pid = fork(); @@ -204,19 +205,19 @@ static void fork_for_result(const char *exec, char *const *argv) } } -static void init() +static void post_fs_data_init() { struct su_profile profile = { .uid = getuid() }; sc_su(key, &profile); - log_kernel("%d starting android user init, from kernel: %d\n", getpid(), from_kernel); + log_kernel("%d starting android user post_fs_data_init, from kernel: %d\n", getpid(), from_kernel); if (!access(APATCH_FLODER, F_OK)) mkdir(APATCH_FLODER, 0700); if (!access(APATCH_LOG_FLODER, F_OK)) mkdir(APATCH_LOG_FLODER, 0700); if (from_kernel) save_dmegs(boot0_log_path); - char current_exe[32] = { '\0' }; + char current_exe[1024] = { '\0' }; if (readlink("/proc/self/exe", current_exe, sizeof(current_exe) - 1)) { if (!strcmp(current_exe, KPATCH_DEV_PATH)) { log_kernel("%d copy %s to %s.\n", getpid(), current_exe, KPATCH_PATH); @@ -237,7 +238,7 @@ static void init() load_config_su_path(); load_config_allow_uids(); - log_kernel("%d finished android user init.\n", getpid()); + log_kernel("%d finished android user post_fs_data_init.\n", getpid()); if (from_kernel) save_dmegs(boot1_log_path); } @@ -265,9 +266,10 @@ int android_user(int argc, char **argv) } } - if (!strcmp("init", scmd)) { - init(); + if (!strcmp("post_fs_data_init", scmd)) { + post_fs_data_init(); } else if (!strcmp("post-fs-data", scmd) || !strcmp("services", scmd) || !strcmp("boot-completed", scmd)) { + // todo: move to apd struct su_profile profile = { .uid = getuid(), .to_uid = 0, From cef1fa0deae2f1cf0679a04624d6256138627cbd Mon Sep 17 00:00:00 2001 From: bmax Date: Fri, 16 Feb 2024 22:19:47 +0800 Subject: [PATCH 22/51] x --- user/android/android_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user/android/android_user.c b/user/android/android_user.c index cf6adab4..d8e1b63a 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -266,7 +266,7 @@ int android_user(int argc, char **argv) } } - if (!strcmp("post_fs_data_init", scmd)) { + if (!strcmp("post-fs-data-init", scmd)) { post_fs_data_init(); } else if (!strcmp("post-fs-data", scmd) || !strcmp("services", scmd) || !strcmp("boot-completed", scmd)) { // todo: move to apd From 45f32373e3efac6d82533aa57d355d52e65e411b Mon Sep 17 00:00:00 2001 From: bmax Date: Sun, 18 Feb 2024 22:52:35 +0800 Subject: [PATCH 23/51] x --- kernel/base/start.c | 45 ++-- kernel/include/pgtable.h | 10 +- kernel/linux/include/linux/mm_types.h | 325 ++++++++++++++++++++++++ kernel/linux/include/linux/sched.h | 25 +- kernel/linux/include/linux/sched/mm.h | 34 +++ kernel/linux/include/linux/sched/task.h | 17 +- kernel/patch/common/accctl.c | 4 +- kernel/patch/common/pidmem.c | 75 ++++++ kernel/patch/common/supercall.c | 17 +- kernel/patch/include/pidmem.h | 15 ++ kernel/patch/include/uapi/scdefs.h | 2 +- kernel/patch/ksyms/misc.c | 22 +- kernel/patch/ksyms/task_cred.c | 64 ++++- kpm-demo/phys_access/.gitignore | 19 ++ kpm-demo/phys_access/Makefile | 30 +++ kpm-demo/phys_access/link.lds | 5 + kpm-demo/phys_access/main.c | 43 ++++ user/kpatch.c | 3 +- user/supercall.h | 7 + version | 2 +- 20 files changed, 705 insertions(+), 59 deletions(-) create mode 100644 kernel/linux/include/linux/mm_types.h create mode 100644 kernel/linux/include/linux/sched/mm.h create mode 100644 kernel/patch/common/pidmem.c create mode 100644 kernel/patch/include/pidmem.h create mode 100644 kpm-demo/phys_access/.gitignore create mode 100644 kpm-demo/phys_access/Makefile create mode 100644 kpm-demo/phys_access/link.lds create mode 100644 kpm-demo/phys_access/main.c diff --git a/kernel/base/start.c b/kernel/base/start.c index f4f2d7ca..4a901b84 100644 --- a/kernel/base/start.c +++ b/kernel/base/start.c @@ -15,6 +15,7 @@ #include #include +#include "../banner" #include "start.h" #include "hook.h" #include "tlsf.h" @@ -42,14 +43,6 @@ KP_EXPORT_SYMBOL(printk); int (*vsprintf)(char *buf, const char *fmt, va_list args) = 0; -const char kernel_patch_logo[] = "\n" - " _ __ _ ____ _ _ \n" - "| |/ /___ _ __ _ __ ___| | _ \\ __ _| |_ ___| |__ \n" - "| ' // _ \\ '__| '_ \\ / _ \\ | |_) / _` | __/ __| '_ \\ \n" - "| . \\ __/ | | | | | __/ | __/ (_| | || (__| | | |\n" - "|_|\\_\\___|_| |_| |_|\\___|_|_| \\__,_|\\__\\___|_| |_|\n"; -KP_EXPORT_SYMBOL(kernel_patch_logo); - static struct vm_struct { struct vm_struct *next; @@ -93,6 +86,9 @@ int64_t kernel_size = 0; int64_t page_shift = 0; int64_t page_size = 0; int64_t va_bits = 0; +int64_t page_level; +uint64_t pgd_pa; +uint64_t pgd_va; // int64_t pa_bits = 0; uint64_t kernel_stext_va = 0; @@ -126,26 +122,18 @@ void log_boot(const char *fmt, ...) boot_log_offset += ret; } -uint64_t *pgtable_entry_kernel(uint64_t va) +uint64_t *pgtable_entry(uint64_t pgd, uint64_t va) { - uint64_t page_level = (va_bits - 4) / (page_shift - 3); uint64_t pxd_bits = page_shift - 3; uint64_t pxd_ptrs = 1u << pxd_bits; - uint64_t ttbr1_el1; - asm volatile("mrs %0, ttbr1_el1" : "=r"(ttbr1_el1)); - - uint64_t baddr = ttbr1_el1 & 0xFFFFFFFFFFFE; - uint64_t page_size = 1 << page_shift; - uint64_t page_size_mask = ~(page_size - 1); - uint64_t pxd_pa = baddr & page_size_mask; - uint64_t pxd_va = phys_to_virt(pxd_pa); + uint64_t pxd_va = pgd; + uint64_t pxd_pa = virt_to_phys(pxd_va); uint64_t pxd_entry_va = 0; uint64_t block_lv = 0; // ================ - // todo: - // branch to some function (even empty) will work, but I don't know why, - // if anyone knows, please let me know. thank you very much. + // Branch to some function (even empty), It can work, + // I don't know why, if anyone knows, please let me know. thank you very much. // ================ __flush_dcache_area((void *)pxd_va, page_size); @@ -171,7 +159,7 @@ uint64_t *pgtable_entry_kernel(uint64_t va) break; } } -#if 1 +#if 0 uint64_t left_bit = page_shift + (block_lv ? (3 - block_lv) * pxd_bits : 0); uint64_t tpa = pxd_pa + (va & ((1u << left_bit) - 1)); uint64_t tlva = phys_to_virt(tpa); @@ -182,7 +170,7 @@ uint64_t *pgtable_entry_kernel(uint64_t va) #endif return (uint64_t *)pxd_entry_va; } -KP_EXPORT_SYMBOL(pgtable_entry_kernel); +KP_EXPORT_SYMBOL(pgtable_entry); static void prot_myself() { @@ -403,7 +391,7 @@ static void start_init(uint64_t kimage_voff, uint64_t linear_voff) vsprintf = (typeof(vsprintf))kallsyms_lookup_name("vsprintf"); - log_boot(kernel_patch_logo); + log_boot(KERNEL_PATCH_BANNER); endian = *(unsigned char *)&(uint16_t){ 1 } ? little : big; setup_header_t *header = &start_preset.header; @@ -435,6 +423,15 @@ static void start_init(uint64_t kimage_voff, uint64_t linear_voff) page_shift = 16; } page_size = 1 << page_shift; + + page_level = (va_bits - 4) / (page_shift - 3); + + uint64_t ttbr1_el1; + asm volatile("mrs %0, ttbr1_el1" : "=r"(ttbr1_el1)); + uint64_t baddr = ttbr1_el1 & 0xFFFFFFFFFFFE; + uint64_t page_size_mask = ~(page_size - 1); + pgd_pa = baddr & page_size_mask; + pgd_va = phys_to_virt(pgd_pa); } static int nice_zone() diff --git a/kernel/include/pgtable.h b/kernel/include/pgtable.h index aa0ccf42..89447543 100644 --- a/kernel/include/pgtable.h +++ b/kernel/include/pgtable.h @@ -102,6 +102,9 @@ extern int64_t kernel_size; extern int64_t page_shift; extern int64_t page_size; extern int64_t va_bits; +extern int64_t page_level; +extern uint64_t pgd_pa; +extern uint64_t pgd_va; // extern int64_t pa_bits; static inline uint64_t phys_to_virt(uint64_t phys) @@ -159,6 +162,11 @@ static inline int is_kimg_range(uint64_t addr) return addr >= kernel_va && addr < (kernel_va + kernel_size); } -uint64_t *pgtable_entry_kernel(uint64_t va); +uint64_t *pgtable_entry(uint64_t pgd, uint64_t va); + +static inline uint64_t *pgtable_entry_kernel(uint64_t va) +{ + return pgtable_entry(pgd_va, va); +} #endif \ No newline at end of file diff --git a/kernel/linux/include/linux/mm_types.h b/kernel/linux/include/linux/mm_types.h new file mode 100644 index 00000000..fe274dbe --- /dev/null +++ b/kernel/linux/include/linux/mm_types.h @@ -0,0 +1,325 @@ +#ifndef _LINUX_MM_TYPES_H +#define _LINUX_MM_TYPES_H + +#include + +struct address_space; +struct mem_cgroup; + +struct page +{ +}; + +/* + * This struct describes a virtual memory area. There is one of these + * per VM-area/task. A VM area is any part of the process virtual memory + * space that has a special rule for the page-fault handlers (ie a shared + * library, the executable area etc). + */ +struct vm_area_struct +{ + // /* The first cache line has the info for VMA tree walking. */ + + // unsigned long vm_start; /* Our start address within vm_mm. */ + // unsigned long vm_end; /* The first byte after our end address + // within vm_mm. */ + + // struct mm_struct *vm_mm; /* The address space we belong to. */ + + // /* + // * Access permissions of this VMA. + // * See vmf_insert_mixed_prot() for discussion. + // */ + // pgprot_t vm_page_prot; + // unsigned long vm_flags; /* Flags, see mm.h. */ + + // /* + // * For areas with an address space and backing store, + // * linkage into the address_space->i_mmap interval tree. + // * + // * For private anonymous mappings, a pointer to a null terminated string + // * containing the name given to the vma, or NULL if unnamed. + // */ + + // union + // { + // struct + // { + // struct rb_node rb; + // unsigned long rb_subtree_last; + // } shared; + // /* + // * Serialized by mmap_sem. Never use directly because it is + // * valid only when vm_file is NULL. Use anon_vma_name instead. + // */ + // struct anon_vma_name *anon_name; + // }; + + // /* + // * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma + // * list, after a COW of one of the file pages. A MAP_SHARED vma + // * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack + // * or brk vma (with NULL file) can only be in an anon_vma list. + // */ + // struct list_head anon_vma_chain; /* Serialized by mmap_lock & + // * page_table_lock */ + // struct anon_vma *anon_vma; /* Serialized by page_table_lock */ + + // /* Function pointers to deal with this struct. */ + // const struct vm_operations_struct *vm_ops; + + // /* Information about our backing store: */ + // unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE + // units */ + // struct file *vm_file; /* File we map to (can be NULL). */ + // void *vm_private_data; /* was vm_pte (shared mem) */ + + // #ifdef CONFIG_SWAP + // atomic_long_t swap_readahead_info; + // #endif + // #ifndef CONFIG_MMU + // struct vm_region *vm_region; /* NOMMU mapping region */ + // #endif + // #ifdef CONFIG_NUMA + // struct mempolicy *vm_policy; /* NUMA policy for the VMA */ + // #endif + // struct vm_userfaultfd_ctx vm_userfaultfd_ctx; +}; //__randomize_layout + +struct mm_struct +{ + // struct + // { + // struct maple_tree mm_mt; + // #ifdef CONFIG_MMU + // unsigned long (*get_unmapped_area)(struct file *filp, unsigned long addr, unsigned long len, + // unsigned long pgoff, unsigned long flags); + // #endif + // unsigned long mmap_base; /* base of mmap area */ + // unsigned long mmap_legacy_base; /* base of mmap area in bottom-up allocations */ + // #ifdef CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES + // /* Base addresses for compatible mmap() */ + // unsigned long mmap_compat_base; + // unsigned long mmap_compat_legacy_base; + // #endif + // unsigned long task_size; /* size of task vm space */ + // pgd_t *pgd; + + // #ifdef CONFIG_MEMBARRIER + // /** + // * @membarrier_state: Flags controlling membarrier behavior. + // * + // * This field is close to @pgd to hopefully fit in the same + // * cache-line, which needs to be touched by switch_mm(). + // */ + // atomic_t membarrier_state; + // #endif + + // /** + // * @mm_users: The number of users including userspace. + // * + // * Use mmget()/mmget_not_zero()/mmput() to modify. When this + // * drops to 0 (i.e. when the task exits and there are no other + // * temporary reference holders), we also release a reference on + // * @mm_count (which may then free the &struct mm_struct if + // * @mm_count also drops to 0). + // */ + // atomic_t mm_users; + + // /** + // * @mm_count: The number of references to &struct mm_struct + // * (@mm_users count as 1). + // * + // * Use mmgrab()/mmdrop() to modify. When this drops to 0, the + // * &struct mm_struct is freed. + // */ + // atomic_t mm_count; + + // #ifdef CONFIG_MMU + // atomic_long_t pgtables_bytes; /* PTE page table pages */ + // #endif + // int map_count; /* number of VMAs */ + + // spinlock_t page_table_lock; /* Protects page tables and some + // * counters + // */ + // /* + // * With some kernel config, the current mmap_lock's offset + // * inside 'mm_struct' is at 0x120, which is very optimal, as + // * its two hot fields 'count' and 'owner' sit in 2 different + // * cachelines, and when mmap_lock is highly contended, both + // * of the 2 fields will be accessed frequently, current layout + // * will help to reduce cache bouncing. + // * + // * So please be careful with adding new fields before + // * mmap_lock, which can easily push the 2 fields into one + // * cacheline. + // */ + // struct rw_semaphore mmap_lock; + + // struct list_head mmlist; /* List of maybe swapped mm's. These + // * are globally strung together off + // * init_mm.mmlist, and are protected + // * by mmlist_lock + // */ + + // unsigned long hiwater_rss; /* High-watermark of RSS usage */ + // unsigned long hiwater_vm; /* High-water virtual memory usage */ + + // unsigned long total_vm; /* Total pages mapped */ + // unsigned long locked_vm; /* Pages that have PG_mlocked set */ + // atomic64_t pinned_vm; /* Refcount permanently increased */ + // unsigned long data_vm; /* VM_WRITE & ~VM_SHARED & ~VM_STACK */ + // unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE & ~VM_STACK */ + // unsigned long stack_vm; /* VM_STACK */ + // unsigned long def_flags; + + // /** + // * @write_protect_seq: Locked when any thread is write + // * protecting pages mapped by this mm to enforce a later COW, + // * for instance during page table copying for fork(). + // */ + // seqcount_t write_protect_seq; + + // spinlock_t arg_lock; /* protect the below fields */ + + // unsigned long start_code, end_code, start_data, end_data; + // unsigned long start_brk, brk, start_stack; + // unsigned long arg_start, arg_end, env_start, env_end; + + // unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ + + // /* + // * Special counters, in some configurations protected by the + // * page_table_lock, in other configurations by being atomic. + // */ + // struct mm_rss_stat rss_stat; + + // struct linux_binfmt *binfmt; + + // /* Architecture-specific MM context */ + // mm_context_t context; + + // unsigned long flags; /* Must use atomic bitops to access */ + + // #ifdef CONFIG_AIO + // spinlock_t ioctx_lock; + // struct kioctx_table __rcu *ioctx_table; + // #endif + // #ifdef CONFIG_MEMCG + // /* + // * "owner" points to a task that is regarded as the canonical + // * user/owner of this mm. All of the following must be true in + // * order for it to be changed: + // * + // * current == mm->owner + // * current->mm != mm + // * new_owner->mm == mm + // * new_owner->alloc_lock is held + // */ + // struct task_struct __rcu *owner; + // #endif + // struct user_namespace *user_ns; + + // /* store ref to file /proc//exe symlink points to */ + // struct file __rcu *exe_file; + // #ifdef CONFIG_MMU_NOTIFIER + // struct mmu_notifier_subscriptions *notifier_subscriptions; + // #endif + // #if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS + // pgtable_t pmd_huge_pte; /* protected by page_table_lock */ + // #endif + // #ifdef CONFIG_NUMA_BALANCING + // /* + // * numa_next_scan is the next time that PTEs will be remapped + // * PROT_NONE to trigger NUMA hinting faults; such faults gather + // * statistics and migrate pages to new nodes if necessary. + // */ + // unsigned long numa_next_scan; + + // /* Restart point for scanning and remapping PTEs. */ + // unsigned long numa_scan_offset; + + // /* numa_scan_seq prevents two threads remapping PTEs. */ + // int numa_scan_seq; + // #endif + // /* + // * An operation with batched TLB flushing is going on. Anything + // * that can move process memory needs to flush the TLB when + // * moving a PROT_NONE mapped page. + // */ + // atomic_t tlb_flush_pending; + // #ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH + // /* See flush_tlb_batched_pending() */ + // atomic_t tlb_flush_batched; + // #endif + // struct uprobes_state uprobes_state; + // #ifdef CONFIG_PREEMPT_RT + // struct rcu_head delayed_drop; + // #endif + // #ifdef CONFIG_HUGETLB_PAGE + // atomic_long_t hugetlb_usage; + // #endif + // struct work_struct async_put_work; + + // #ifdef CONFIG_IOMMU_SVA + // u32 pasid; + // #endif + // #ifdef CONFIG_KSM + // /* + // * Represent how many pages of this process are involved in KSM + // * merging. + // */ + // unsigned long ksm_merging_pages; + // /* + // * Represent how many pages are checked for ksm merging + // * including merged and not merged. + // */ + // unsigned long ksm_rmap_items; + // #endif + // #ifdef CONFIG_LRU_GEN + // struct + // { + // /* this mm_struct is on lru_gen_mm_list */ + // struct list_head list; + // /* + // * Set when switching to this mm_struct, as a hint of + // * whether it has been used since the last time per-node + // * page table walkers cleared the corresponding bits. + // */ + // unsigned long bitmap; + // #ifdef CONFIG_MEMCG + // /* points to the memcg of "owner" above */ + // struct mem_cgroup *memcg; + // #endif + // } lru_gen; + // #endif /* CONFIG_LRU_GEN */ + // } __randomize_layout; + + // /* + // * The mm_cpumask needs to be at the end of mm_struct, because it + // * is dynamically sized based on nr_cpu_ids. + // */ + // unsigned long cpu_bitmap[]; +}; + +struct mm_struct_offset +{ + int16_t mmap_base_offset; + int16_t task_size_offset; + int16_t pgd_offset; + int16_t map_count_offset; + int16_t total_vm_offset; + int16_t locked_vm_offset; + int16_t pinned_vm_offset; + int16_t data_vm_offset; + int16_t exec_vm_offset; + int16_t stack_vm_offset; + int16_t start_code_offset, end_code_offset, start_data_offset, end_data_offset; + int16_t start_brk_offset, brk_offset, start_stack_offset; + int16_t arg_start_offset, arg_end_offset, env_start_offset, env_end_offset; +}; + +extern struct mm_struct_offset mm_struct_offset; + +#endif \ No newline at end of file diff --git a/kernel/linux/include/linux/sched.h b/kernel/linux/include/linux/sched.h index 3fda1dac..67dc5d23 100644 --- a/kernel/linux/include/linux/sched.h +++ b/kernel/linux/include/linux/sched.h @@ -40,7 +40,6 @@ extern void io_schedule_finish(int token); extern long io_schedule_timeout(long timeout); extern void io_schedule(void); -// todo: struct task_struct_offset { int16_t pid_offset; @@ -58,6 +57,8 @@ struct task_struct_offset int16_t security_offset; int16_t stack_offset; int16_t tasks_offset; + int16_t mm_offset; + int16_t active_mm_offset; }; extern struct task_struct_offset task_struct_offset; @@ -145,9 +146,7 @@ extern struct task_struct *kfunc_def(find_get_task_by_vpid)(pid_t nr); static inline pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, struct pid_namespace *ns) { - kfunc_call(__task_pid_nr_ns, task, type, ns); - kfunc_not_found(); - return 0; + kfunc_direct_call(__task_pid_nr_ns, task, type, ns); } static inline pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) @@ -162,28 +161,22 @@ static inline pid_t task_pid_vnr(struct task_struct *tsk) static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) { - kfunc_call(task_active_pid_ns, tsk); - kfunc_not_found(); - return 0; + kfunc_direct_call(task_active_pid_ns, tsk); } static inline struct task_struct *find_task_by_vpid(pid_t nr) { - kfunc_call(find_task_by_vpid, nr); - kfunc_not_found(); - return 0; + kfunc_direct_call(find_task_by_vpid, nr); } + static inline struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) { - kfunc_call(find_task_by_pid_ns, nr, ns); - kfunc_not_found(); - return 0; + kfunc_direct_call(find_task_by_pid_ns, nr, ns); } + static inline struct task_struct *find_get_task_by_vpid(pid_t nr) { - kfunc_call(find_get_task_by_vpid, nr); - kfunc_not_found(); - return 0; + kfunc_direct_call(find_get_task_by_vpid, nr); } #endif \ No newline at end of file diff --git a/kernel/linux/include/linux/sched/mm.h b/kernel/linux/include/linux/sched/mm.h new file mode 100644 index 00000000..4c96e2d5 --- /dev/null +++ b/kernel/linux/include/linux/sched/mm.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_SCHED_MM_H +#define _LINUX_SCHED_MM_H + +#include +#include + +/* mmput gets rid of the mappings and all user-space */ +extern void kfunc_def(mmput)(struct mm_struct *); + +/* same as above but performs the slow path from the async context. Can + * be called from the atomic context as well + */ +extern void kfunc_def(mmput_async)(struct mm_struct *); + +/* Grab a reference to a task's mm, if it is not already going away */ +extern struct mm_struct *kfunc_def(get_task_mm)(struct task_struct *task); + +static inline void mmput(struct mm_struct *mm) +{ + kfunc_direct_call_void(mmput, mm); +} + +static inline void mmput_async(struct mm_struct *mm) +{ + kfunc_direct_call_void(mmput_async, mm); +} + +struct mm_struct *get_task_mm(struct task_struct *task) +{ + kfunc_direct_call(get_task_mm, task); +} + +#endif \ No newline at end of file diff --git a/kernel/linux/include/linux/sched/task.h b/kernel/linux/include/linux/sched/task.h index 5c3f5037..689e0241 100644 --- a/kernel/linux/include/linux/sched/task.h +++ b/kernel/linux/include/linux/sched/task.h @@ -47,71 +47,83 @@ extern void kfunc_def(sched_exec)(void); static inline void __put_task_struct(struct task_struct *t) { - kfunc_call(__put_task_struct, t); - kfunc_not_found(); + kfunc_direct_call(__put_task_struct, t); } + static inline int lockdep_tasklist_lock_is_held(void) { kfunc_call(lockdep_tasklist_lock_is_held); kfunc_not_found(); return 0; } + static inline asmlinkage void schedule_tail(struct task_struct *prev) { kfunc_call(schedule_tail, prev); kfunc_not_found(); } + static inline void init_idle(struct task_struct *idle, int cpu) { kfunc_call(init_idle, idle, cpu); kfunc_not_found(); } + static inline int sched_fork(unsigned long clone_flags, struct task_struct *p) { kfunc_call(sched_fork, clone_flags, p); kfunc_not_found(); return 0; } + static inline void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs) { kfunc_call(sched_cgroup_fork, p, kargs); kfunc_not_found(); } + static inline void sched_post_fork(struct task_struct *p) { kfunc_call(sched_post_fork, p); kfunc_not_found(); } + static inline void sched_dead(struct task_struct *p) { kfunc_call(sched_dead, p); kfunc_not_found(); } + static inline void __noreturn do_task_dead(void) { kfunc_call_void(do_task_dead); kfunc_not_found(); } + static inline void __noreturn make_task_dead(int signr) { kfunc_call_void(make_task_dead, signr); kfunc_not_found(); } + static inline void proc_caches_init(void) { kfunc_call(proc_caches_init); kfunc_not_found(); } + static inline void fork_init(void) { kfunc_call(fork_init); kfunc_not_found(); } + static inline void release_task(struct task_struct *p) { kfunc_call(release_task, p); kfunc_not_found(); } + static inline int copy_thread(unsigned long clone_flags, unsigned long stack_start, unsigned long stk_sz, struct task_struct *p, unsigned long tls) { @@ -119,6 +131,7 @@ static inline int copy_thread(unsigned long clone_flags, unsigned long stack_sta kfunc_not_found(); return 0; } + static inline void flush_thread(void) { kfunc_call(flush_thread); diff --git a/kernel/patch/common/accctl.c b/kernel/patch/common/accctl.c index fe22d572..dd2acd31 100644 --- a/kernel/patch/common/accctl.c +++ b/kernel/patch/common/accctl.c @@ -111,8 +111,7 @@ int task_su(pid_t pid, uid_t to_uid, const char *sctx) struct task_struct *task = find_get_task_by_vpid(pid); if (!task) { logkfe("no such pid: %d\n", pid); - rc = -ENOENT; - goto out; + return -ESRCH; } struct task_ext *ext = get_task_ext(task); @@ -147,6 +146,5 @@ int task_su(pid_t pid, uid_t to_uid, const char *sctx) logkfi("pid: %d, tgid: %d, to_uid: %d, sctx: %s, via_hook: %d\n", ext->pid, ext->tgid, to_uid, sctx, ext->priv_selinux_allow); out: - __put_task_struct(task); return rc; } diff --git a/kernel/patch/common/pidmem.c b/kernel/patch/common/pidmem.c new file mode 100644 index 00000000..b75ecec2 --- /dev/null +++ b/kernel/patch/common/pidmem.c @@ -0,0 +1,75 @@ +#include "pidmem.h" + +#include +#include +#include +#include +#include +#include +#include + +uintptr_t pgtable_walker_entry(uintptr_t pgd_addr, uintptr_t va) +{ + uint64_t pxd_bits = page_shift - 3; + uint64_t pxd_ptrs = 1u << pxd_bits; + uint64_t pxd_va = pgd_addr; + uint64_t pxd_pa = virt_to_phys(pxd_va); + uint64_t pxd_entry_va = 0; + uint64_t block_lv = 0; + + for (int64_t lv = 4 - page_level; lv < 4; lv++) { + uint64_t pxd_shift = (page_shift - 3) * (4 - lv) + 3; + uint64_t pxd_index = (va >> pxd_shift) & (pxd_ptrs - 1); + pxd_entry_va = pxd_va + pxd_index * 8; + if (!pxd_entry_va) return 0; + uint64_t pxd_desc = *((uint64_t *)pxd_entry_va); + if ((pxd_desc & 0b11) == 0b11) { // table + pxd_pa = pxd_desc & (((1ul << (48 - page_shift)) - 1) << page_shift); + } else if ((pxd_desc & 0b11) == 0b01) { // block + // 4k page: lv1, lv2. 16k and 64k page: only lv2. + uint64_t block_bits = (3 - lv) * pxd_bits + page_shift; + pxd_pa = pxd_desc & (((1ul << (48 - block_bits)) - 1) << block_bits); + block_lv = lv; + } else { // invalid + return 0; + } + // + pxd_va = phys_to_virt(pxd_pa); + if (block_lv) { + break; + } + } + return pxd_entry_va; +} + +phys_addr_t pid_virt_to_phys(pid_t pid, uintptr_t vaddr) +{ + if (mm_struct_offset.pgd_offset < 0) { + return -EFAULT; + } + + struct task_struct *task = find_get_task_by_vpid(pid); + if (!task) { + logkfe("no such pid: %d\n", pid); + return -ESRCH; + } + + int rc = 0; + + struct mm_struct *mm = get_task_mm(task); + if (IS_ERR(mm)) { + // todo + } + logkd("aaaaaaaaaaaaa %llx\n", mm); + uintptr_t pgd = *(uintptr_t *)((uintptr_t)mm + mm_struct_offset.pgd_offset); + logkd("aaaaaaaaaaaaa %llx\n", pgd); + + uintptr_t entry = pgtable_walker_entry(pgd, vaddr); + logkd("aaaaaaaaaaaaa %llx\n", entry); + logkd("aaaaaaaaaaaaa %llx\n", *(uintptr_t *)entry); + + mmput(mm); + +out: + return rc; +} \ No newline at end of file diff --git a/kernel/patch/common/supercall.c b/kernel/patch/common/supercall.c index 7a16812b..785a1c42 100644 --- a/kernel/patch/common/supercall.c +++ b/kernel/patch/common/supercall.c @@ -26,6 +26,7 @@ #include #include #include +#include #define MAX_KEY_LEN 128 @@ -126,6 +127,11 @@ static long call_kpm_info(const char *__user uname, char *__user out_info, int o return sz; } +static unsigned long call_pid_virt_to_phys(pid_t pid, uintptr_t vaddr) +{ + return pid_virt_to_phys(pid, vaddr); +} + static long call_su(struct su_profile *__user uprofile) { struct su_profile *profile = memdup_user(uprofile, sizeof(struct su_profile)); @@ -176,6 +182,9 @@ static long supercall(long cmd, long arg1, long arg2, long arg3, long arg4) return call_kpm_list((char *__user)arg1, (int)arg2); case SUPERCALL_KPM_INFO: return call_kpm_info((const char *__user)arg1, (char *__user)arg2, (int)arg3); + case SUPERCALL_MEM_PHYS: + return call_pid_virt_to_phys((pid_t)arg1, (uintptr_t)arg2); + case SUPERCALL_BOOTLOG: return call_bootlog(); case SUPERCALL_PANIC: @@ -189,6 +198,8 @@ static long supercall(long cmd, long arg1, long arg2, long arg3, long arg4) return NO_SYSCALL; } +static long hash_key_val = 0; + static void before(hook_fargs6_t *args, void *udata) { const char *__user ukey = (const char *__user)syscall_argn(args, 0); @@ -201,12 +212,12 @@ static void before(hook_fargs6_t *args, void *udata) long cmd = hash_cmd & 0xFFFF; long hash = hash_cmd & 0xFFFF0000; + if ((hash_key_val & 0xFFFF0000) != hash) return; + char key[MAX_KEY_LEN]; long len = strncpy_from_user_nofault(key, ukey, MAX_KEY_LEN); - if (len <= 0) return; if (superkey_auth(key)) return; - if ((hash_key(key) & 0xFFFF0000) != hash) return; args->skip_origin = 1; args->ret = supercall(cmd, a1, a2, a3, a4); @@ -215,6 +226,8 @@ static void before(hook_fargs6_t *args, void *udata) int supercall_install() { int rc = 0; + hash_key_val = hash_key(get_superkey()); + // hook_err_t err = inline_hook_syscalln(__NR_supercall, 6, before, 0, 0); hook_err_t err = fp_hook_syscalln(__NR_supercall, 6, before, 0, 0); if (err) { diff --git a/kernel/patch/include/pidmem.h b/kernel/patch/include/pidmem.h new file mode 100644 index 00000000..5cb10c2e --- /dev/null +++ b/kernel/patch/include/pidmem.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024 bmax121. All Rights Reserved. + */ + +#ifndef _KP_PIDMEM_H_ +#define _KP_PIDMEM_H_ + +#include + +phys_addr_t pid_virt_to_phys(pid_t pid, uintptr_t vaddr); + +// void *pid_map_mem(pid_t pid, void *mem, size_t size, ) + +#endif diff --git a/kernel/patch/include/uapi/scdefs.h b/kernel/patch/include/uapi/scdefs.h index 762b08e4..cda6c693 100644 --- a/kernel/patch/include/uapi/scdefs.h +++ b/kernel/patch/include/uapi/scdefs.h @@ -37,7 +37,7 @@ static inline long hash_key(const char *key) #define SUPERCALL_KPM_LIST 0x1031 #define SUPERCALL_KPM_INFO 0x1032 -#define SUPERCALL_MEM_USER_PHYS 0x1041 +#define SUPERCALL_MEM_PHYS 0x1041 #define SUPERCALL_MEM_KERNEL_PHYS 0x1042 #define SUPERCALL_MEM_MAP_KERNEL 0x1048 #define SUPERCALL_MEM_MAP_USER 0x1049 diff --git a/kernel/patch/ksyms/misc.c b/kernel/patch/ksyms/misc.c index 72d6bfa5..1d30b3d6 100644 --- a/kernel/patch/ksyms/misc.c +++ b/kernel/patch/ksyms/misc.c @@ -175,7 +175,7 @@ static void _linux_kernel_fork_sym_match(const char *name, unsigned long addr) // kfunc_match(pidfd_pid, name, addr); // kfunc_match(get_mm_exe_file, name, addr); // kfunc_match(free_task, name, addr); - kfunc_match(__put_task_struct, name, addr); + // kfunc_match(__put_task_struct, name, addr); // kfunc_match(fork_init, name, addr); // kfunc_match(set_mm_exe_file, name, addr); // kfunc_match(get_mm_exe_file, name, addr); @@ -457,10 +457,10 @@ static void _linux_fs_sym_match(const char *name, unsigned long addr) // kfunc_match(file_open_root, name, addr); // kfunc_match(dentry_open, name, addr); kfunc_match(filp_close, name, addr); - kfunc_match(getname, name, addr); - kfunc_match(getname_kernel, name, addr); - kfunc_match(putname, name, addr); - kfunc_match(final_putname, name, addr); + // kfunc_match(getname, name, addr); + // kfunc_match(getname_kernel, name, addr); + // kfunc_match(putname, name, addr); + // kfunc_match(final_putname, name, addr); kfunc_match(vfs_llseek, name, addr); } @@ -817,6 +817,17 @@ static void _linux_rcu_symbol_init(const char *name, unsigned long addr) // kfunc_match(exit_tasks_rcu_finish, name, addr); } +void kfunc_def(mmput)(struct mm_struct *); +void kfunc_def(mmput_async)(struct mm_struct *); +struct mm_struct *kfunc_def(get_task_mm)(struct task_struct *task); + +static void _linux_sched_mm_init(const char *name, unsigned long addr) +{ + kfunc_match(mmput, name, addr); + kfunc_match(mmput_async, name, addr); + kfunc_match(get_task_mm, name, addr); +} + static int _linux_misc_symbol_init(void *data, const char *name, struct module *m, unsigned long addr) { _linux_kernel_cred_sym_match(name, addr); @@ -834,6 +845,7 @@ static int _linux_misc_symbol_init(void *data, const char *name, struct module * _linux_kernel_fork_sym_match(name, addr); _linux_rcu_symbol_init(name, addr); _linux_seccomp_sym_match(name, addr); + _linux_sched_mm_init(name, addr); return 0; } diff --git a/kernel/patch/ksyms/task_cred.c b/kernel/patch/ksyms/task_cred.c index 723f4949..e8c1eb98 100644 --- a/kernel/patch/ksyms/task_cred.c +++ b/kernel/patch/ksyms/task_cred.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #define TASK_COMM_LEN 16 @@ -28,6 +29,32 @@ #define TASK_STRUCT_MAX_SIZE 0x1800 #define THREAD_INFO_MAX_SIZE 0x90 #define CRED_MAX_SIZE 0x100 +#define MM_STRUCT_MAX_SIZE 0xb0 + +struct mm_struct_offset mm_struct_offset = { + .mmap_base_offset = -1, + .task_size_offset = -1, + .pgd_offset = -1, + .map_count_offset = -1, + .total_vm_offset = -1, + .locked_vm_offset = -1, + .pinned_vm_offset = -1, + .data_vm_offset = -1, + .exec_vm_offset = -1, + .stack_vm_offset = -1, + .start_code_offset = -1, + .end_code_offset = -1, + .start_data_offset = -1, + .end_data_offset = -1, + .start_brk_offset = -1, + .brk_offset = -1, + .start_stack_offset = -1, + .arg_start_offset = -1, + .arg_end_offset = -1, + .env_start_offset = -1, + .env_end_offset = -1, +}; +KP_EXPORT_SYMBOL(mm_struct_offset); struct task_struct_offset task_struct_offset = { .pid_offset = -1, @@ -45,6 +72,8 @@ struct task_struct_offset task_struct_offset = { .security_offset = -1, .stack_offset = -1, .tasks_offset = -1, + .mm_offset = -1, + .active_mm_offset = -1, }; KP_EXPORT_SYMBOL(task_struct_offset); @@ -84,10 +113,8 @@ struct cred_offset cred_offset = { KP_EXPORT_SYMBOL(cred_offset); struct task_struct *init_task = 0; -KP_EXPORT_SYMBOL(init_task); - const struct cred *init_cred = 0; -KP_EXPORT_SYMBOL(init_cred); +const struct mm_struct *init_mm = 0; int thread_size = 0; KP_EXPORT_SYMBOL(thread_size); @@ -412,6 +439,21 @@ int resolve_task_offset() } log_boot(" seccomp offset: %x\n", task_struct_offset.seccomp_offset); + // active_mm + init_mm = (struct mm_struct *)kallsyms_lookup_name("init_mm"); + if (init_mm) { + for (uintptr_t i = (uintptr_t)task; i < (uintptr_t)task + TASK_STRUCT_MAX_SIZE; i += sizeof(uintptr_t)) { + uintptr_t active_mm = *(uintptr_t *)i; + if (active_mm == (uintptr_t)init_mm) { + task_struct_offset.active_mm_offset = i - (uintptr_t)task; + break; + } + } + } else { + // todo + } + log_boot(" active_mm offset: %x\n", task_struct_offset.active_mm_offset); + revert_current(backup); vfree(task); return 0; @@ -542,6 +584,20 @@ int resolve_current() return 0; } +int resolve_mm_struct_offset() +{ + log_boot("struct mm_struct: \n"); + uintptr_t init_mm_addr = (uintptr_t)init_mm; + for (uintptr_t i = init_mm_addr; i < init_mm_addr + MM_STRUCT_MAX_SIZE; i += sizeof(uintptr_t)) { + uint64_t pgd = *(uintptr_t *)i; + if (pgd == phys_to_kimg(pgd_pa)) { + mm_struct_offset.pgd_offset = i - init_mm_addr; + } + } + log_boot(" pgd offset: %x\n", mm_struct_offset.pgd_offset); + return 0; +} + int resolve_struct() { full_cap = CAP_FULL_SET; @@ -551,6 +607,8 @@ int resolve_struct() if ((err = resolve_task_offset())) goto out; if ((err = resolve_cred_offset())) goto out; + resolve_mm_struct_offset(); + out: return err; } diff --git a/kpm-demo/phys_access/.gitignore b/kpm-demo/phys_access/.gitignore new file mode 100644 index 00000000..2085cbfc --- /dev/null +++ b/kpm-demo/phys_access/.gitignore @@ -0,0 +1,19 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Libraries +*.lib +*.a +*.la +*.lo + +*.bin +*.elf + +*.kpm diff --git a/kpm-demo/phys_access/Makefile b/kpm-demo/phys_access/Makefile new file mode 100644 index 00000000..1e25bdbf --- /dev/null +++ b/kpm-demo/phys_access/Makefile @@ -0,0 +1,30 @@ +ifndef TARGET_COMPILE + $(error TARGET_COMPILE not set) +endif + +ifndef KP_DIR + KP_DIR = ../.. +endif + + +CC = $(TARGET_COMPILE)gcc +LD = $(TARGET_COMPILE)ld + +INCLUDE_DIRS := . include patch/include linux/include linux/arch/arm64/include linux/tools/arch/arm64/include + +INCLUDE_FLAGS := $(foreach dir,$(INCLUDE_DIRS),-I$(KP_DIR)/kernel/$(dir)) + +objs := main.o + +all: phys_access.kpm + +phys_access.kpm: ${objs} + ${CC} -r -o $@ $^ + +%.o: %.c + ${CC} $(CFLAGS) $(INCLUDE_FLAGS) -Tlink.lds -c -O2 -o $@ $< + +.PHONY: clean +clean: + rm -rf *.kpm + find . -name "*.o" | xargs rm -f \ No newline at end of file diff --git a/kpm-demo/phys_access/link.lds b/kpm-demo/phys_access/link.lds new file mode 100644 index 00000000..d599a67a --- /dev/null +++ b/kpm-demo/phys_access/link.lds @@ -0,0 +1,5 @@ +SECTIONS { + .plt (NOLOAD) : { BYTE(0) } + .init.plt (NOLOAD) : { BYTE(0) } + .text.ftrace_trampoline (NOLOAD) : { BYTE(0) } +} \ No newline at end of file diff --git a/kpm-demo/phys_access/main.c b/kpm-demo/phys_access/main.c new file mode 100644 index 00000000..b33b6ac8 --- /dev/null +++ b/kpm-demo/phys_access/main.c @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024 bmax121. All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include + +KPM_NAME("phys-access"); +KPM_VERSION("1.0.0"); +KPM_LICENSE("GPL v2"); +KPM_AUTHOR("bmax121"); +KPM_DESCRIPTION("Expose APIs for accessing process physical memory."); + +static int init(const char *args, void *__user reserved) +{ + pr_info("kpm hello init, args: %s\n", args); + pr_info("kernelpatch version: %x\n", kpver); + return 0; +} + +static int control(const char *args, char *__user out_msg, int outlen) +{ + pr_info("kpm hello control, args: %s\n", args); + char echo[64] = "echo: "; + strncat(echo, args, 48); + seq_copy_to_user(out_msg, echo, sizeof(echo)); + return 0; +} + +static int exit(void *__user reserved) +{ + pr_info("kpm hello exit\n"); + return 0; +} + +KPM_INIT(init); +KPM_CTL(control); +KPM_EXIT(exit); diff --git a/user/kpatch.c b/user/kpatch.c index 752f6e34..33d8ae7d 100644 --- a/user/kpatch.c +++ b/user/kpatch.c @@ -56,5 +56,6 @@ void panic(const char *key) int __test(const char *key) { - return __sc_test(key, 0, 0, 0); + // return __sc_test(key, 0, 0, 0); + return sc_pid_virt_to_phys(key, getpid(), (unsigned long)__test); } diff --git a/user/supercall.h b/user/supercall.h index 50ea8fa8..b09a55be 100644 --- a/user/supercall.h +++ b/user/supercall.h @@ -118,6 +118,13 @@ static inline long sc_kpm_info(const char *key, const char *name, char *buf, int return ret; } +static inline long sc_pid_virt_to_phys(const char *key, pid_t pid, unsigned long vaddr) +{ + if (!key || !key[0]) return -EINVAL; + long ret = syscall(__NR_supercall, key, hash_key_cmd(key, SUPERCALL_MEM_PHYS), pid, vaddr); + return ret; +} + static inline long sc_bootlog(const char *key) { long ret = syscall(__NR_supercall, key, hash_key_cmd(key, SUPERCALL_BOOTLOG)); diff --git a/version b/version index 20e59d60..f8645495 100644 --- a/version +++ b/version @@ -1,3 +1,3 @@ #define MAJOR 0 #define MINOR 9 -#define PATCH 1 +#define PATCH 2 From 0e5ddb9cc15ed601f5dc16c525bc3540da74a33e Mon Sep 17 00:00:00 2001 From: bmax Date: Mon, 19 Feb 2024 10:13:01 +0800 Subject: [PATCH 24/51] x --- kernel/patch/common/hotpatch.c | 1 - kernel/patch/common/pidmem.c | 42 ++-------------------------------- kpm-demo/phys_access/main.c | 9 +------- 3 files changed, 3 insertions(+), 49 deletions(-) diff --git a/kernel/patch/common/hotpatch.c b/kernel/patch/common/hotpatch.c index 05853324..0cc30405 100644 --- a/kernel/patch/common/hotpatch.c +++ b/kernel/patch/common/hotpatch.c @@ -39,7 +39,6 @@ int patch_verify_safety() // do_each_thread(p) // { - // logkd("ggg: %llx\n", p); // trace.nr_entries = 0; // save_stack_trace_tsk(t, &trace); diff --git a/kernel/patch/common/pidmem.c b/kernel/patch/common/pidmem.c index b75ecec2..d4c7d3e5 100644 --- a/kernel/patch/common/pidmem.c +++ b/kernel/patch/common/pidmem.c @@ -8,40 +8,6 @@ #include #include -uintptr_t pgtable_walker_entry(uintptr_t pgd_addr, uintptr_t va) -{ - uint64_t pxd_bits = page_shift - 3; - uint64_t pxd_ptrs = 1u << pxd_bits; - uint64_t pxd_va = pgd_addr; - uint64_t pxd_pa = virt_to_phys(pxd_va); - uint64_t pxd_entry_va = 0; - uint64_t block_lv = 0; - - for (int64_t lv = 4 - page_level; lv < 4; lv++) { - uint64_t pxd_shift = (page_shift - 3) * (4 - lv) + 3; - uint64_t pxd_index = (va >> pxd_shift) & (pxd_ptrs - 1); - pxd_entry_va = pxd_va + pxd_index * 8; - if (!pxd_entry_va) return 0; - uint64_t pxd_desc = *((uint64_t *)pxd_entry_va); - if ((pxd_desc & 0b11) == 0b11) { // table - pxd_pa = pxd_desc & (((1ul << (48 - page_shift)) - 1) << page_shift); - } else if ((pxd_desc & 0b11) == 0b01) { // block - // 4k page: lv1, lv2. 16k and 64k page: only lv2. - uint64_t block_bits = (3 - lv) * pxd_bits + page_shift; - pxd_pa = pxd_desc & (((1ul << (48 - block_bits)) - 1) << block_bits); - block_lv = lv; - } else { // invalid - return 0; - } - // - pxd_va = phys_to_virt(pxd_pa); - if (block_lv) { - break; - } - } - return pxd_entry_va; -} - phys_addr_t pid_virt_to_phys(pid_t pid, uintptr_t vaddr) { if (mm_struct_offset.pgd_offset < 0) { @@ -60,16 +26,12 @@ phys_addr_t pid_virt_to_phys(pid_t pid, uintptr_t vaddr) if (IS_ERR(mm)) { // todo } - logkd("aaaaaaaaaaaaa %llx\n", mm); uintptr_t pgd = *(uintptr_t *)((uintptr_t)mm + mm_struct_offset.pgd_offset); - logkd("aaaaaaaaaaaaa %llx\n", pgd); + uintptr_t entry = pgtable_entry(pgd, vaddr); - uintptr_t entry = pgtable_walker_entry(pgd, vaddr); - logkd("aaaaaaaaaaaaa %llx\n", entry); - logkd("aaaaaaaaaaaaa %llx\n", *(uintptr_t *)entry); + // remap_pfn_range or direct modify pgtable mmput(mm); - out: return rc; } \ No newline at end of file diff --git a/kpm-demo/phys_access/main.c b/kpm-demo/phys_access/main.c index b33b6ac8..fab5cef2 100644 --- a/kpm-demo/phys_access/main.c +++ b/kpm-demo/phys_access/main.c @@ -14,27 +14,20 @@ KPM_NAME("phys-access"); KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("bmax121"); -KPM_DESCRIPTION("Expose APIs for accessing process physical memory."); +KPM_DESCRIPTION("Expose APIs for access process physical memory."); static int init(const char *args, void *__user reserved) { - pr_info("kpm hello init, args: %s\n", args); - pr_info("kernelpatch version: %x\n", kpver); return 0; } static int control(const char *args, char *__user out_msg, int outlen) { - pr_info("kpm hello control, args: %s\n", args); - char echo[64] = "echo: "; - strncat(echo, args, 48); - seq_copy_to_user(out_msg, echo, sizeof(echo)); return 0; } static int exit(void *__user reserved) { - pr_info("kpm hello exit\n"); return 0; } From 04509cfd1e50f661a98d915faf9f4ae159f65bbd Mon Sep 17 00:00:00 2001 From: bmax Date: Mon, 19 Feb 2024 10:14:43 +0800 Subject: [PATCH 25/51] a --- kernel/patch/common/pidmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/patch/common/pidmem.c b/kernel/patch/common/pidmem.c index d4c7d3e5..fd6c8618 100644 --- a/kernel/patch/common/pidmem.c +++ b/kernel/patch/common/pidmem.c @@ -27,7 +27,7 @@ phys_addr_t pid_virt_to_phys(pid_t pid, uintptr_t vaddr) // todo } uintptr_t pgd = *(uintptr_t *)((uintptr_t)mm + mm_struct_offset.pgd_offset); - uintptr_t entry = pgtable_entry(pgd, vaddr); + uintptr_t *entry = pgtable_entry(pgd, vaddr); // remap_pfn_range or direct modify pgtable From 145094ff034f4ae546de11af3c50df2aed395cce Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 21 Feb 2024 14:04:07 +0800 Subject: [PATCH 26/51] a --- doc/{ => en}/build.md | 3 +- doc/{ => en}/guide.md | 0 doc/{ => en}/inline-hook.md | 0 doc/en/module.md | 1 + doc/{ => en}/super-syscall.md | 0 doc/{ => en}/syscall-hook.md | 0 doc/{ => zh-CN}/module.md | 2 +- kernel/include/kpmodule.h | 14 +- kernel/patch/android/supercall.c | 1 - kernel/patch/common/extrainit.c | 2 +- kernel/patch/common/supercall.c | 2 +- kernel/patch/include/module.h | 12 +- kernel/patch/include/uapi/scdefs.h | 3 +- kernel/patch/module/module.c | 161 +++++++++++---------- kpm-demo/hello/hello.c | 19 ++- kpm-demo/inlinehook/inlinehook.c | 8 +- kpm-demo/phys_access/main.c | 36 ----- kpm-demo/{phys_access => shmem}/.gitignore | 0 kpm-demo/{phys_access => shmem}/Makefile | 4 +- kpm-demo/{phys_access => shmem}/link.lds | 0 kpm-demo/shmem/main.c | 43 ++++++ kpm-demo/syscallhook/syscallhook.c | 8 +- user/android/sumgr.c | 2 +- user/kpm.c | 6 +- user/main.c | 1 - 25 files changed, 175 insertions(+), 153 deletions(-) rename doc/{ => en}/build.md (92%) rename doc/{ => en}/guide.md (100%) rename doc/{ => en}/inline-hook.md (100%) create mode 100644 doc/en/module.md rename doc/{ => en}/super-syscall.md (100%) rename doc/{ => en}/syscall-hook.md (100%) rename doc/{ => zh-CN}/module.md (96%) delete mode 100644 kpm-demo/phys_access/main.c rename kpm-demo/{phys_access => shmem}/.gitignore (100%) rename kpm-demo/{phys_access => shmem}/Makefile (91%) rename kpm-demo/{phys_access => shmem}/link.lds (100%) create mode 100644 kpm-demo/shmem/main.c diff --git a/doc/build.md b/doc/en/build.md similarity index 92% rename from doc/build.md rename to doc/en/build.md index a003b979..ade898bc 100644 --- a/doc/build.md +++ b/doc/en/build.md @@ -8,7 +8,7 @@ Require a bare-metal cross compiler ```shell export TARGET_COMPILE=aarch64-none-elf- cd kernel -# export ANDROID=1 # Android version, including support for the 'su' command +export ANDROID=1 # Android version, including support for the 'su' command make ``` @@ -19,6 +19,7 @@ kptools can run anywhere, just compile it. - Using Makefile ```shell +export ANDROID=1 cd tools make ``` diff --git a/doc/guide.md b/doc/en/guide.md similarity index 100% rename from doc/guide.md rename to doc/en/guide.md diff --git a/doc/inline-hook.md b/doc/en/inline-hook.md similarity index 100% rename from doc/inline-hook.md rename to doc/en/inline-hook.md diff --git a/doc/en/module.md b/doc/en/module.md new file mode 100644 index 00000000..bd186728 --- /dev/null +++ b/doc/en/module.md @@ -0,0 +1 @@ +# KernelPatch Module diff --git a/doc/super-syscall.md b/doc/en/super-syscall.md similarity index 100% rename from doc/super-syscall.md rename to doc/en/super-syscall.md diff --git a/doc/syscall-hook.md b/doc/en/syscall-hook.md similarity index 100% rename from doc/syscall-hook.md rename to doc/en/syscall-hook.md diff --git a/doc/module.md b/doc/zh-CN/module.md similarity index 96% rename from doc/module.md rename to doc/zh-CN/module.md index e73f34d3..4213794f 100644 --- a/doc/module.md +++ b/doc/zh-CN/module.md @@ -1,6 +1,6 @@ # KernelPatch Module -## What is KernelPatch Module (KPM) +## 什么是 KernelPatch Module (KPM) **KPM is an ELF file that can be loaded and run within the kernel space by KernelPatch.** diff --git a/kernel/include/kpmodule.h b/kernel/include/kpmodule.h index cc7cd2fe..6553a081 100644 --- a/kernel/include/kpmodule.h +++ b/kernel/include/kpmodule.h @@ -24,15 +24,19 @@ #define KPM_AUTHOR(x) KPM_INFO(author, x, KPM_AUTHOR_LEN) #define KPM_DESCRIPTION(x) KPM_INFO(description, x, KPM_DESCRIPTION_LEN) -typedef int (*mod_initcall_t)(const char *args, void *reserved); -typedef int (*mod_ctlcall_t)(const char *ctl_args, char *__user out_msg, int outlen); -typedef int (*mod_exitcall_t)(void *reserved); +typedef long (*mod_initcall_t)(const char *args, const char *event, void *reserved); +typedef long (*mod_ctl0call_t)(const char *ctl_args, char *__user out_msg, int outlen); +typedef long (*mod_ctl1call_t)(void *a1, void *a2, void *a3); +typedef long (*mod_exitcall_t)(void *reserved); #define KPM_INIT(fn) \ static mod_initcall_t __kpm_initcall_##fn __attribute__((__used__)) __attribute__((__section__(".kpm.init"))) = fn -#define KPM_CTL(fn) \ - static mod_ctlcall_t __kpm_ctlmodule_##fn __attribute__((__used__)) __attribute__((__section__(".kpm.ctl"))) = fn +#define KPM_CTL0(fn) \ + static mod_ctl0call_t __kpm_ctlmodule_##fn __attribute__((__used__)) __attribute__((__section__(".kpm.ctl0"))) = fn + +#define KPM_CTL1(fn) \ + static mod_ctl1call_t __kpm_ctlmodule_##fn __attribute__((__used__)) __attribute__((__section__(".kpm.ctl1"))) = fn #define KPM_EXIT(fn) \ static mod_exitcall_t __kpm_exitcall_##fn __attribute__((__used__)) __attribute__((__section__(".kpm.exit"))) = fn diff --git a/kernel/patch/android/supercall.c b/kernel/patch/android/supercall.c index 8bc95f42..493f27bb 100644 --- a/kernel/patch/android/supercall.c +++ b/kernel/patch/android/supercall.c @@ -53,7 +53,6 @@ static long call_reset_su_path(const char *__user upath) { char path[SU_PATH_MAX_LEN]; strncpy_from_user_nofault(path, upath, sizeof(path)); - if (strlen(path) < SU_PATH_MIN_LEN - 1) return -EINVAL; return su_reset_path(path); } diff --git a/kernel/patch/common/extrainit.c b/kernel/patch/common/extrainit.c index eb95aaa9..b3965090 100644 --- a/kernel/patch/common/extrainit.c +++ b/kernel/patch/common/extrainit.c @@ -13,7 +13,7 @@ static int extra_callback(const patch_extra_item_t *extra, const char *args, con { int *num = (int *)udata; if (extra->type == EXTRA_TYPE_KPM) { - int rc = load_module(data, extra->con_size, args, 0); + int rc = load_module(data, extra->con_size, args, "pre-kinit", 0); log_boot("loading extra %d kpm return: %d\n", *num, rc); } (*num)++; diff --git a/kernel/patch/common/supercall.c b/kernel/patch/common/supercall.c index 785a1c42..9f3e155e 100644 --- a/kernel/patch/common/supercall.c +++ b/kernel/patch/common/supercall.c @@ -87,7 +87,7 @@ static long call_kpm_control(const char __user *arg1, const char *__user arg2, v long namelen = strncpy_from_user_nofault(name, arg1, sizeof(name)); if (namelen <= 0) return -EINVAL; long arglen = strncpy_from_user_nofault(args, arg2, sizeof(args)); - return control_module(name, arglen <= 0 ? 0 : args, out_msg, outlen); + return module_control0(name, arglen <= 0 ? 0 : args, out_msg, outlen); } static long call_kpm_unload(const char *__user arg1, void *__user reserved) diff --git a/kernel/patch/include/module.h b/kernel/patch/include/module.h index 27842762..dff41462 100644 --- a/kernel/patch/include/module.h +++ b/kernel/patch/include/module.h @@ -38,7 +38,8 @@ struct module char *args, *ctl_args; mod_initcall_t *init; - mod_ctlcall_t *ctl; + mod_ctl0call_t *ctl0; + mod_ctl1call_t *ctl1; mod_exitcall_t *exit; unsigned int size; @@ -50,10 +51,11 @@ struct module struct list_head list; }; -int load_module(const void *data, int len, const char *args, void *__user reserved); -int load_module_path(const char *path, const char *args, void *__user reserved); -int control_module(const char *name, const char *ctl_args, char *__user out_msg, int outlen); -int unload_module(const char *name, void *__user reserved); +long load_module(const void *data, int len, const char *args, const char *event, void *__user reserved); +long load_module_path(const char *path, const char *args, void *__user reserved); +long module_control0(const char *name, const char *ctl_args, char *__user out_msg, int outlen); +long module_control1(const char *name, void *a1, void *a2, void *a3); +long unload_module(const char *name, void *__user reserved); struct module *find_module(const char *name); int get_module_nums(); diff --git a/kernel/patch/include/uapi/scdefs.h b/kernel/patch/include/uapi/scdefs.h index cda6c693..fb13d807 100644 --- a/kernel/patch/include/uapi/scdefs.h +++ b/kernel/patch/include/uapi/scdefs.h @@ -61,8 +61,7 @@ struct su_profile #ifdef ANDROID #define ANDROID_SH_PATH "/system/bin/sh" -#define SU_PATH_MIN_LEN sizeof(ANDROID_SH_PATH) -#define SU_PATH_MAX_LEN 64 +#define SU_PATH_MAX_LEN 128 #define ANDROID_SU_PATH "/system/bin/kp" #define KPATCH_PATH "/data/adb/kpatch" diff --git a/kernel/patch/module/module.c b/kernel/patch/module/module.c index 6368e1d0..7d30bfbc 100644 --- a/kernel/patch/module/module.c +++ b/kernel/patch/module/module.c @@ -207,20 +207,20 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) static int apply_relocations(struct module *mod, const struct load_info *info) { - int err = 0; + int rc = 0; unsigned int i; for (i = 1; i < info->hdr->e_shnum; i++) { unsigned int infosec = info->sechdrs[i].sh_info; if (infosec >= info->hdr->e_shnum) continue; if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC)) continue; if (info->sechdrs[i].sh_type == SHT_REL) { - err = apply_relocate(info->sechdrs, info->strtab, info->index.sym, i, mod); + rc = apply_relocate(info->sechdrs, info->strtab, info->index.sym, i, mod); } else if (info->sechdrs[i].sh_type == SHT_RELA) { - err = apply_relocate_add(info->sechdrs, info->strtab, info->index.sym, i, mod); + rc = apply_relocate_add(info->sechdrs, info->strtab, info->index.sym, i, mod); } - if (err < 0) break; + if (rc < 0) break; } - return err; + return rc; } // todo: free .strtab and .symtab after relocation @@ -302,24 +302,18 @@ static int move_module(struct module *mod, struct load_info *info) logkd(" %s %llx %llx\n", sname, dest, shdr->sh_size); - if (shdr->sh_type != SHT_NOBITS) { - memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size); - } + if (shdr->sh_type != SHT_NOBITS) memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size); shdr->sh_addr = (unsigned long)dest; - if (!mod->init && !strcmp(".kpm.init", sname)) { - mod->init = (mod_initcall_t *)dest; - } - if (!mod->ctl && !strcmp(".kpm.ctl", sname)) { - mod->ctl = (mod_ctlcall_t *)dest; - } - if (!mod->exit && !strcmp(".kpm.exit", sname)) { - mod->exit = (mod_exitcall_t *)dest; - } - if (!mod->info.base && !strcmp(".kpm.info", sname)) { - mod->info.base = (const char *)dest; - } + if (!mod->init && !strcmp(".kpm.init", sname)) mod->init = (mod_initcall_t *)dest; + + if (!strcmp(".kpm.ctl0", sname)) mod->ctl0 = (mod_ctl0call_t *)dest; + if (!strcmp(".kpm.ctl1", sname)) mod->ctl1 = (mod_ctl1call_t *)dest; + + if (!mod->exit && !strcmp(".kpm.exit", sname)) mod->exit = (mod_exitcall_t *)dest; + + if (!mod->info.base && !strcmp(".kpm.info", sname)) mod->info.base = (const char *)dest; } mod->info.name = info->info.name - info->info.base + mod->info.base; mod->info.version = info->info.version - info->info.base + mod->info.base; @@ -332,13 +326,13 @@ static int move_module(struct module *mod, struct load_info *info) static int setup_load_info(struct load_info *info) { - int err = 0; + int rc = 0; info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; info->secstrings = (void *)info->hdr + info->sechdrs[info->hdr->e_shstrndx].sh_offset; - if ((err = rewrite_section_headers(info))) { + if ((rc = rewrite_section_headers(info))) { logke("rewrite section error\n"); - return err; + return rc; } if (!find_sec(info, ".kpm.init") || !find_sec(info, ".kpm.exit")) { @@ -346,10 +340,6 @@ static int setup_load_info(struct load_info *info) return -ENOEXEC; } - if (!find_sec(info, ".kpm.ctl")) { - logkw("no .kpm.ctl section\n"); - } - info->index.info = find_sec(info, ".kpm.info"); if (!info->index.info) { logke("no .kpm.info section\n"); @@ -420,22 +410,18 @@ static int elf_header_check(struct load_info *info) struct module modules = { 0 }; static spinlock_t module_lock; -int load_module(const void *data, int len, const char *args, void *__user reserved) +long load_module(const void *data, int len, const char *args, const char *event, void *__user reserved) { struct load_info load_info = { .len = len, .hdr = data }; struct load_info *info = &load_info; - int err = 0; + long rc = 0; - if ((err = elf_header_check(info))) { - goto out; - } - if ((err = setup_load_info(info))) { - goto out; - } + if ((rc = elf_header_check(info))) goto out; + if ((rc = setup_load_info(info))) goto out; if (find_module(info->info.name)) { logkfd("%s exist\n", info->info.name); - err = -EEXIST; + rc = -EEXIST; goto out; } @@ -446,7 +432,7 @@ int load_module(const void *data, int len, const char *args, void *__user reserv if (args) { mod->args = vmalloc(strlen(args) + 1); if (!mod->args) { - err = -ENOMEM; + rc = -ENOMEM; goto free1; } strcpy(mod->args, args); @@ -455,57 +441,47 @@ int load_module(const void *data, int len, const char *args, void *__user reserv layout_sections(mod, info); layout_symtab(mod, info); - if ((err = move_module(mod, info))) { - goto free; - } - - if ((err = simplify_symbols(mod, info))) { - goto free; - } - - if ((err = apply_relocations(mod, info))) { - goto free; - } + if ((rc = move_module(mod, info))) goto free; + if ((rc = simplify_symbols(mod, info))) goto free; + if ((rc = apply_relocations(mod, info))) goto free; flush_icache_all(); - err = (*mod->init)(mod->args, reserved); + rc = (*mod->init)(mod->args, event, reserved); - if (!err) { + if (!rc) { logkfi("[%s] succeed with [%s] \n", mod->info.name, args); list_add_tail(&mod->list, &modules.list); goto out; } else { - logkfi("[%s] failed with [%s] error: %d, try exit ...\n", mod->info.name, args, err); + logkfi("[%s] failed with [%s] error: %d, try exit ...\n", mod->info.name, args, rc); (*mod->exit)(reserved); } free: if (mod->args) kvfree(mod->args); kp_free_exec(mod->start); - free1: kvfree(mod); - out: - return err; + return rc; } -// lock -int unload_module(const char *name, void *__user reserved) +// todo: lock +long unload_module(const char *name, void *__user reserved) { logkfe("name: %s\n", name); rcu_read_lock(); - int err = 0; + long rc = 0; struct module *mod = find_module(name); if (!mod) { - err = -ENOENT; + rc = -ENOENT; goto out; } list_del(&mod->list); - err = (*mod->exit)(reserved); + rc = (*mod->exit)(reserved); if (mod->args) kvfree(mod->args); if (mod->ctl_args) kvfree(mod->ctl_args); @@ -513,23 +489,22 @@ int unload_module(const char *name, void *__user reserved) kp_free_exec(mod->start); kvfree(mod); - logkfi("name: %s, rc: %d\n", name, err); + logkfi("name: %s, rc: %d\n", name, rc); out: rcu_read_unlock(); - return err; + return rc; } -// lock -int load_module_path(const char *path, const char *args, void *__user reserved) +long load_module_path(const char *path, const char *args, void *__user reserved) { - long err = 0; + long rc = 0; logkfd("%s\n", path); struct file *filp = filp_open(path, O_RDONLY, 0); if (unlikely(IS_ERR(filp))) { logkfe("open module: %s error\n", path); - err = PTR_ERR(filp); + rc = PTR_ERR(filp); goto out; } loff_t len = vfs_llseek(filp, 0, SEEK_END); @@ -538,7 +513,7 @@ int load_module_path(const char *path, const char *args, void *__user reserved) void *data = vmalloc(len); if (!data) { - err = -ENOMEM; + rc = -ENOMEM; goto out; } memset(data, 0, len); @@ -549,19 +524,18 @@ int load_module_path(const char *path, const char *args, void *__user reserved) if (pos != len) { logkfe("read module: %s error\n", path); - err = -EIO; + rc = -EIO; goto free; } - err = load_module(data, len, args, reserved); - + rc = load_module(data, len, args, "load-file", reserved); free: kvfree(data); out: - return err; + return rc; } -int control_module(const char *name, const char *ctl_args, char *__user out_msg, int outlen) +long module_control0(const char *name, const char *ctl_args, char *__user out_msg, int outlen) { if (!ctl_args) return -EINVAL; int args_len = strlen(ctl_args); @@ -569,34 +543,63 @@ int control_module(const char *name, const char *ctl_args, char *__user out_msg, logkfi("name %s, args: %s\n", name, ctl_args); - int err = 0; + long rc = 0; rcu_read_lock(); struct module *mod = find_module(name); if (!mod) { - err = -ENOENT; + rc = -ENOENT; goto out; } - if (mod->ctl_args) { - kvfree(mod->ctl_args); + if (!*mod->ctl0) { + logkfe("no ctl0\n"); + rc = -ENOSYS; + goto out; } + if (mod->ctl_args) kvfree(mod->ctl_args); + mod->ctl_args = vmalloc(args_len + 1); if (!mod->ctl_args) { - err = -ENOMEM; + rc = -ENOMEM; goto out; } strcpy(mod->ctl_args, ctl_args); - err = (*mod->ctl)(mod->ctl_args, out_msg, outlen); + rc = (*mod->ctl0)(mod->ctl_args, out_msg, outlen); + + logkfi("name: %s, rc: %d\n", name, rc); +out: + rcu_read_unlock(); + return rc; +} + +long module_control1(const char *name, void *a1, void *a2, void *a3) +{ + logkfi("name %s, a1: %llx, a2: %llx, a3: %llx\n", name, a1, a2, a3); + long rc = 0; + rcu_read_lock(); + + struct module *mod = find_module(name); + if (!mod) { + rc = -ENOENT; + goto out; + } + + if (!*mod->ctl1) { + logkfe("no ctl1\n"); + rc = -ENOSYS; + goto out; + } - logkfi("name: %s, rc: %d\n", name, err); + rc = (*mod->ctl1)(a1, a2, a3); + logkfi("name: %s, rc: %d\n", name, rc); out: rcu_read_unlock(); - return err; + return rc; } struct module *find_module(const char *name) diff --git a/kpm-demo/hello/hello.c b/kpm-demo/hello/hello.c index 392e4d6c..c3a55319 100644 --- a/kpm-demo/hello/hello.c +++ b/kpm-demo/hello/hello.c @@ -33,28 +33,35 @@ KPM_DESCRIPTION("KernelPatch Module Example"); * @param reserved * @return int */ -static int hello_init(const char *args, void *__user reserved) +static long hello_init(const char *args, const char *event, void *__user reserved) { - pr_info("kpm hello init, args: %s\n", args); + pr_info("kpm hello init, event: %s, args: %s\n", event, args); pr_info("kernelpatch version: %x\n", kpver); return 0; } -static int hello_control(const char *args, char *__user out_msg, int outlen) +static long hello_control0(const char *args, char *__user out_msg, int outlen) { - pr_info("kpm hello control, args: %s\n", args); + pr_info("kpm hello control0, args: %s\n", args); char echo[64] = "echo: "; strncat(echo, args, 48); seq_copy_to_user(out_msg, echo, sizeof(echo)); return 0; } -static int hello_exit(void *__user reserved) +static long hello_control1(void *a1, void *a2, void *a3) +{ + pr_info("kpm hello control1, a1: %llx, a2: %llx, a3: %llx\n", a1, a2, a3); + return 0; +} + +static long hello_exit(void *__user reserved) { pr_info("kpm hello exit\n"); return 0; } KPM_INIT(hello_init); -KPM_CTL(hello_control); +KPM_CTL0(hello_control0); +KPM_CTL1(hello_control1); KPM_EXIT(hello_exit); diff --git a/kpm-demo/inlinehook/inlinehook.c b/kpm-demo/inlinehook/inlinehook.c index 26e82812..065337ab 100644 --- a/kpm-demo/inlinehook/inlinehook.c +++ b/kpm-demo/inlinehook/inlinehook.c @@ -33,7 +33,7 @@ void after_add(hook_fargs2_t *args, void *udata) args->ret = 100; } -int inline_hook_demo_init(const char *args, void *__user reserved) +static long inline_hook_demo_init(const char *args, const char *event, void *__user reserved) { logkd("kpm inline-hook-demo init\n"); @@ -52,13 +52,13 @@ int inline_hook_demo_init(const char *args, void *__user reserved) return 0; } -int inline_hook_control(const char *args, char *__user out_msg, int outlen) +static long inline_hook_control0(const char *args, char *__user out_msg, int outlen) { pr_info("kpm control, args: %s\n", args); return 0; } -int inline_hook_demo_exit(void *__user reserved) +static long inline_hook_demo_exit(void *__user reserved) { unhook((void *)add); @@ -72,5 +72,5 @@ int inline_hook_demo_exit(void *__user reserved) } KPM_INIT(inline_hook_demo_init); -KPM_CTL(inline_hook_control); +KPM_CTL0(inline_hook_control0); KPM_EXIT(inline_hook_demo_exit); \ No newline at end of file diff --git a/kpm-demo/phys_access/main.c b/kpm-demo/phys_access/main.c deleted file mode 100644 index fab5cef2..00000000 --- a/kpm-demo/phys_access/main.c +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2024 bmax121. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include - -KPM_NAME("phys-access"); -KPM_VERSION("1.0.0"); -KPM_LICENSE("GPL v2"); -KPM_AUTHOR("bmax121"); -KPM_DESCRIPTION("Expose APIs for access process physical memory."); - -static int init(const char *args, void *__user reserved) -{ - return 0; -} - -static int control(const char *args, char *__user out_msg, int outlen) -{ - return 0; -} - -static int exit(void *__user reserved) -{ - return 0; -} - -KPM_INIT(init); -KPM_CTL(control); -KPM_EXIT(exit); diff --git a/kpm-demo/phys_access/.gitignore b/kpm-demo/shmem/.gitignore similarity index 100% rename from kpm-demo/phys_access/.gitignore rename to kpm-demo/shmem/.gitignore diff --git a/kpm-demo/phys_access/Makefile b/kpm-demo/shmem/Makefile similarity index 91% rename from kpm-demo/phys_access/Makefile rename to kpm-demo/shmem/Makefile index 1e25bdbf..8b0ffa18 100644 --- a/kpm-demo/phys_access/Makefile +++ b/kpm-demo/shmem/Makefile @@ -16,9 +16,9 @@ INCLUDE_FLAGS := $(foreach dir,$(INCLUDE_DIRS),-I$(KP_DIR)/kernel/$(dir)) objs := main.o -all: phys_access.kpm +all: shmem.kpm -phys_access.kpm: ${objs} +shmem.kpm: ${objs} ${CC} -r -o $@ $^ %.o: %.c diff --git a/kpm-demo/phys_access/link.lds b/kpm-demo/shmem/link.lds similarity index 100% rename from kpm-demo/phys_access/link.lds rename to kpm-demo/shmem/link.lds diff --git a/kpm-demo/shmem/main.c b/kpm-demo/shmem/main.c new file mode 100644 index 00000000..da54b19d --- /dev/null +++ b/kpm-demo/shmem/main.c @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024 bmax121. All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include + +KPM_NAME("kpm-shmem"); +KPM_VERSION("1.0.0"); +KPM_LICENSE("GPL v2"); +KPM_AUTHOR("bmax121"); +KPM_DESCRIPTION("Share memory between processes"); + +/* + * This module's main functionality is to map any address of any process to any other process. + * Of course, this means you can easily manipulate data of other processes. + * However, this is too powerful and ... + * so let's leave it aside for now. Perhaps it will be developed someday ...... +*/ + +static long init(const char *args, const char *event, void *__user reserved) +{ + return 0; +} + +static long control0(const char *args, char *__user out_msg, int outlen) +{ + return 0; +} + +static long exit(void *__user reserved) +{ + return 0; +} + +KPM_INIT(init); +KPM_CTL0(control0); +KPM_EXIT(exit); diff --git a/kpm-demo/syscallhook/syscallhook.c b/kpm-demo/syscallhook/syscallhook.c index a061cdb2..a719e968 100644 --- a/kpm-demo/syscallhook/syscallhook.c +++ b/kpm-demo/syscallhook/syscallhook.c @@ -69,7 +69,7 @@ void after_openat_1(hook_fargs4_t *args, void *udata) pr_info("hook_chain_1 after openat task: %llx\n", args->local.data0); } -int syscall_hook_demo_init(const char *args, void *__user reserved) +static long syscall_hook_demo_init(const char *args, const char *event, void *__user reserved) { margs = args; pr_info("kpm-syscall-hook-demo init ..., args: %s\n", margs); @@ -108,13 +108,13 @@ int syscall_hook_demo_init(const char *args, void *__user reserved) return 0; } -int syscall_hook_control(const char *args, char *__user out_msg, int outlen) +static long syscall_hook_control0(const char *args, char *__user out_msg, int outlen) { pr_info("syscall_hook control, args: %s\n", args); return 0; } -int syscall_hook_demo_exit(void *__user reserved) +static long syscall_hook_demo_exit(void *__user reserved) { pr_info("kpm-syscall-hook-demo exit ...\n"); @@ -129,5 +129,5 @@ int syscall_hook_demo_exit(void *__user reserved) } KPM_INIT(syscall_hook_demo_init); -KPM_CTL(syscall_hook_control); +KPM_CTL0(syscall_hook_control0); KPM_EXIT(syscall_hook_demo_exit); \ No newline at end of file diff --git a/user/android/sumgr.c b/user/android/sumgr.c index dc31070c..68fac734 100644 --- a/user/android/sumgr.c +++ b/user/android/sumgr.c @@ -101,7 +101,7 @@ void usage(int status) "num Get the number of uids with the aforementioned permissions.\n" "list List aforementioned uids.\n" "profile Get the profile of the uid configuration.\n" - "reset Reset '/system/bin/kp' to PATH. The length of PATH must be between 14-63.\n" + "reset Reset '/system/bin/kp' to PATH. The length of PATH must be between 1-127.\n" "path Get current su PATH.\n" ""); } diff --git a/user/kpm.c b/user/kpm.c index 98b4aacc..79bd65a8 100644 --- a/user/kpm.c +++ b/user/kpm.c @@ -3,13 +3,13 @@ * Copyright (C) 2023 bmax121. All Rights Reserved. */ -#include "kpm.h" #include #include #include #include #include +#include "kpm.h" #include "supercall.h" int kpm_load(const char *key, const char *path, const char *args) @@ -75,7 +75,7 @@ static void usage(int status) "\n" "help Print this help message. \n" "load [KPM_ARGS] Load KernelPatch Module with KPM_PATH and KPM_ARGS.\n" - "ctl Control KernelPatch Module named KPM_PATH with CTL_ARGS.\n" + "ctl0 Control KernelPatch Module named KPM_PATH with CTL_ARGS.\n" "unload Unload KernelPatch Module named KPM_NAME.\n" "num Get the number of modules that have been loaded.\n" "list List names of all loaded modules.\n" @@ -98,7 +98,7 @@ int kpm_main(int argc, char **argv) int cmd; } cmd_arr[] = { { "load", SUPERCALL_KPM_LOAD }, - { "ctl", SUPERCALL_KPM_CONTROL }, + { "ctl0", SUPERCALL_KPM_CONTROL }, { "unload", SUPERCALL_KPM_UNLOAD }, { "num", SUPERCALL_KPM_NUMS }, { "list", SUPERCALL_KPM_LIST }, diff --git a/user/main.c b/user/main.c index 0d9c7d81..d8cf2b40 100644 --- a/user/main.c +++ b/user/main.c @@ -134,7 +134,6 @@ int main(int argc, char **argv) case 'k': strcat(program_name, " kpm"); return kpm_main(argc - 2, argv + 2); - case 'l': bootlog(key); break; From e13fe6ed6812f1ee66eed39b8ea056e5c6d37818 Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 21 Feb 2024 14:18:30 +0800 Subject: [PATCH 27/51] a --- user/android/sumgr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/user/android/sumgr.c b/user/android/sumgr.c index 68fac734..3f168829 100644 --- a/user/android/sumgr.c +++ b/user/android/sumgr.c @@ -40,9 +40,8 @@ int su_nums(const char *key) int su_list(const char *key) { - int nums = sc_su_uid_nums(key); - uid_t uids[nums]; - int rc = sc_su_allow_uids(key, uids, nums); + uid_t uids[256]; + int rc = sc_su_allow_uids(key, uids, sizeof(uids) / sizeof(uids[0])); if (rc > 0) { for (int i = 0; i < rc; i++) { fprintf(stdout, "%d\n", uids[i]); From a00b6c593f2f2b767b70f32c3e71d78d703950f2 Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 21 Feb 2024 14:30:21 +0800 Subject: [PATCH 28/51] a --- kernel/patch/common/extrainit.c | 12 +++++------- kernel/patch/patch.c | 5 ++--- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/kernel/patch/common/extrainit.c b/kernel/patch/common/extrainit.c index b3965090..f56d4bdc 100644 --- a/kernel/patch/common/extrainit.c +++ b/kernel/patch/common/extrainit.c @@ -11,18 +11,16 @@ static int extra_callback(const patch_extra_item_t *extra, const char *args, const void *data, void *udata) { - int *num = (int *)udata; + const char *event = (const char *)udata; if (extra->type == EXTRA_TYPE_KPM) { - int rc = load_module(data, extra->con_size, args, "pre-kinit", 0); - log_boot("loading extra %d kpm return: %d\n", *num, rc); + int rc = load_module(data, extra->con_size, args, event, 0); + log_boot("%s loading extra kpm return: %d\n", event, rc); } - (*num)++; return 0; } -int extra_init() +int extra_init(const char *event) { - int num = 0; - on_each_extra_item(extra_callback, &num); + on_each_extra_item(extra_callback, (void *)event); return 0; } diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index 9d84a699..54fb3b91 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -87,9 +87,6 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) log_boot("su_compat_init done: %d\n", rc); #endif - if ((rc = extra_init())) goto out; - log_boot("supercall_install done: %d\n", rc); - out: return; } @@ -97,6 +94,8 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) static void before_kernel_init(hook_fargs4_t *args, void *udata) { log_boot("before kernel_init ...\n"); + int rc = extra_init("pre-kernel-init"); + log_boot("extra_init done: %d\n", rc); } static void after_kernel_init(hook_fargs4_t *args, void *udata) From 959a89687ce3ec669f6a801f3143f07c6bcbbe3e Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 21 Feb 2024 16:51:20 +0800 Subject: [PATCH 29/51] a --- tools/patch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/patch.c b/tools/patch.c index 3210b236..42c14a22 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -217,6 +217,11 @@ int print_image_patch_info(patched_kimg_t *pimg) fprintf(stdout, "priority=%d\n", item->priority); fprintf(stdout, "con_size=0x%x\n", item->con_size); fprintf(stdout, "args_size=0x%x\n", item->args_size); + if (item->args_size > 0) { + fprintf(stdout, "args=%s\n", (char *)item + sizeof(*item)); + } else { + fprintf(stdout, "args=\n"); + } if (item->type == EXTRA_TYPE_KPM) { kpm_info_t kpm_info = { 0 }; void *kpm = (kpm_info_t *)((uintptr_t)item + sizeof(patch_extra_item_t) + item->args_size); From 3c624dc541c76fb4b5e1c3510d00aac5381d95c9 Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 21 Feb 2024 21:40:45 +0800 Subject: [PATCH 30/51] a --- kernel/include/preset.h | 11 +++++++++++ kernel/patch/android/kpuserd.c | 31 +++++++++++++++--------------- kernel/patch/android/sucompat.c | 4 ++-- kernel/patch/include/uapi/scdefs.h | 4 ++-- kernel/patch/patch.c | 4 +++- user/android/android_user.c | 4 ++-- 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/kernel/include/preset.h b/kernel/include/preset.h index 69d4d35a..33817656 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -156,6 +156,17 @@ typedef int32_t extra_item_type; #define EXTRA_TYPE_RAW_STR "raw" #define EXTRA_TYPE_ANDROID_RC_STR "android_rc" +// todo +#define EXTRA_EVENT_PAGING_INIT "paging-init" +#define EXTRA_EVENT_PRE_KERNEL_INIT "pre-kernel-init" +#define EXTRA_EVENT_POST_KERNEL_INIT "post-kernel-init" +#define EXTRA_EVENT_PRE_INIT "pre-init" +#define EXTRA_EVENT_POST_INIT "post-init" +#define EXTRA_EVENT_PRE_SECOND_STAGE "pre-second-stage" +#define EXTRA_EVENT_POST_SECOND_STAGE "post-second-stage" +#define EXTRA_EVENT_PRE_ZYGOTE_START "pre-zygote-start" +#define EXTRA_EVENT_POST_ZYGOTE_START "post-zygote-start" + struct _patch_extra_item { union diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index 248ddcbb..e26d036c 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -34,22 +34,21 @@ #define ORIGIN_RC_FILE "/system/etc/init/atrace.rc" #define REPLACE_RC_FILE "/dev/.atrace.rc" -static const char patch_rc[] = - "" - "\n" - "on late-init\n" - " rm " REPLACE_RC_FILE "\n" - "on post-fs-data\n" - " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_DEV_PATH " %s android_user post-fs-data-init -k\n" - " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_PATH " %s android_user post-fs-data -k\n" - "on nonencrypted\n" - " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_PATH " %s android_user services -k\n" - "on property:vold.decrypt=trigger_restart_framework\n" - " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_PATH " %s android_user services -k\n" - "on property:sys.boot_completed=1\n" - " exec -- " KPATCH_SHADOW_PATH " %s " KPATCH_PATH " %s android_user boot-completed -k\n" - "\n\n" - ""; +static const char patch_rc[] = "" + "\n" + "on late-init\n" + " rm " REPLACE_RC_FILE "\n" + "on post-fs-data\n" + " exec -- " SUPERCMD " %s " KPATCH_DEV_PATH " %s android_user post-fs-data-init -k\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user post-fs-data -k\n" + "on nonencrypted\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" + "on property:vold.decrypt=trigger_restart_framework\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" + "on property:sys.boot_completed=1\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user boot-completed -k\n" + "\n\n" + ""; static const void *kernel_read_file(const char *path, loff_t *len) { diff --git a/kernel/patch/android/sucompat.c b/kernel/patch/android/sucompat.c index 33b7b338..343e65c7 100644 --- a/kernel/patch/android/sucompat.c +++ b/kernel/patch/android/sucompat.c @@ -41,7 +41,7 @@ static const char sh_path[] = ANDROID_SH_PATH; static const char default_su_path[] = ANDROID_SU_PATH; static const char *current_su_path = 0; static const char apd_path[] = APD_PATH; -static const char kpatch_shadow_path[] = KPATCH_SHADOW_PATH; +static const char kpatch_supercmd[] = SUPERCMD; struct allow_uid { @@ -317,7 +317,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) } } kvfree(profile); - } else if (!strcmp(kpatch_shadow_path, filename->name)) { + } else if (!strcmp(kpatch_supercmd, filename->name)) { void *ua0 = (void *)args->args[filename_index + 1]; void *ua1 = (void *)args->args[filename_index + 2]; // key diff --git a/kernel/patch/include/uapi/scdefs.h b/kernel/patch/include/uapi/scdefs.h index fb13d807..576ab4ea 100644 --- a/kernel/patch/include/uapi/scdefs.h +++ b/kernel/patch/include/uapi/scdefs.h @@ -64,10 +64,10 @@ struct su_profile #define SU_PATH_MAX_LEN 128 #define ANDROID_SU_PATH "/system/bin/kp" -#define KPATCH_PATH "/data/adb/kpatch" +#define KPATCH_DATA_PATH "/data/adb/kpatch" #define KPATCH_DEV_PATH "/dev/kpatch" #define APD_PATH "/data/adb/apd" -#define KPATCH_SHADOW_PATH "/system/bin/truncate" +#define SUPERCMD "/system/bin/truncate" #define ADB_FLODER "/data/adb/" #define APATCH_FLODER "/data/adb/ap/" diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index 54fb3b91..61fdf046 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -94,13 +94,15 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) static void before_kernel_init(hook_fargs4_t *args, void *udata) { log_boot("before kernel_init ...\n"); - int rc = extra_init("pre-kernel-init"); + int rc = extra_init(EXTRA_EVENT_PRE_KERNEL_INIT); log_boot("extra_init done: %d\n", rc); } static void after_kernel_init(hook_fargs4_t *args, void *udata) { log_boot("after kernel_init ...\n"); + // int rc = extra_init(EXTRA_EVENT_POST_KERNEL_INIT); + // log_boot("extra_init done: %d\n", rc); } int patch() diff --git a/user/android/android_user.c b/user/android/android_user.c index d8e1b63a..c7a24c98 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -220,9 +220,9 @@ static void post_fs_data_init() char current_exe[1024] = { '\0' }; if (readlink("/proc/self/exe", current_exe, sizeof(current_exe) - 1)) { if (!strcmp(current_exe, KPATCH_DEV_PATH)) { - log_kernel("%d copy %s to %s.\n", getpid(), current_exe, KPATCH_PATH); + log_kernel("%d copy %s to %s.\n", getpid(), current_exe, KPATCH_DATA_PATH); - char *const cp_argv[] = { "/system/bin/cp", current_exe, KPATCH_PATH, NULL }; + char *const cp_argv[] = { "/system/bin/cp", current_exe, KPATCH_DATA_PATH, NULL }; fork_for_result(cp_argv[0], cp_argv); char *const rm_argv[] = { "/system/bin/rm", current_exe, NULL }; From a504d31740fdfba2ed1e73be0b58cf1217ab5124 Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 22 Feb 2024 10:31:16 +0800 Subject: [PATCH 31/51] a --- kernel/include/preset.h | 1 + kernel/patch/common/extrainit.c | 13 ++++++++----- kernel/patch/include/extrainit.h | 2 +- kernel/patch/patch.c | 8 ++++---- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/kernel/include/preset.h b/kernel/include/preset.h index 33817656..6c32af13 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -159,6 +159,7 @@ typedef int32_t extra_item_type; // todo #define EXTRA_EVENT_PAGING_INIT "paging-init" #define EXTRA_EVENT_PRE_KERNEL_INIT "pre-kernel-init" +#define EXTRA_EVENT_KPM_DEFAULT EXTRA_EVENT_PRE_KERNEL_INIT #define EXTRA_EVENT_POST_KERNEL_INIT "post-kernel-init" #define EXTRA_EVENT_PRE_INIT "pre-init" #define EXTRA_EVENT_POST_INIT "post-init" diff --git a/kernel/patch/common/extrainit.c b/kernel/patch/common/extrainit.c index f56d4bdc..7a385796 100644 --- a/kernel/patch/common/extrainit.c +++ b/kernel/patch/common/extrainit.c @@ -7,20 +7,23 @@ #include #include #include +#include #include -static int extra_callback(const patch_extra_item_t *extra, const char *args, const void *data, void *udata) +static int extra_load_kpm_callback(const patch_extra_item_t *extra, const char *args, const void *data, void *udata) { const char *event = (const char *)udata; if (extra->type == EXTRA_TYPE_KPM) { - int rc = load_module(data, extra->con_size, args, event, 0); - log_boot("%s loading extra kpm return: %d\n", event, rc); + if (!strcmp(event, extra->event) || (!extra->event[0]) && !strcmp(EXTRA_EVENT_KPM_DEFAULT, event)) { + int rc = load_module(data, extra->con_size, args, event, 0); + log_boot("%s loading extra kpm return: %d\n", event, rc); + } } return 0; } -int extra_init(const char *event) +int extra_load_kpm(const char *event) { - on_each_extra_item(extra_callback, (void *)event); + on_each_extra_item(extra_load_kpm_callback, (void *)event); return 0; } diff --git a/kernel/patch/include/extrainit.h b/kernel/patch/include/extrainit.h index 3ff0763b..c9f4954e 100644 --- a/kernel/patch/include/extrainit.h +++ b/kernel/patch/include/extrainit.h @@ -6,6 +6,6 @@ #ifndef _KP_EXTRAINIT_H_ #define _KP_EXTRAINIT_H_ -int extra_init(); +int extra_load_kpm(); #endif \ No newline at end of file diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index 61fdf046..8aa2889e 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -94,15 +94,15 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) static void before_kernel_init(hook_fargs4_t *args, void *udata) { log_boot("before kernel_init ...\n"); - int rc = extra_init(EXTRA_EVENT_PRE_KERNEL_INIT); - log_boot("extra_init done: %d\n", rc); + int rc = extra_load_kpm(EXTRA_EVENT_PRE_KERNEL_INIT); + log_boot("extra_load_kpm done: %d\n", rc); } static void after_kernel_init(hook_fargs4_t *args, void *udata) { log_boot("after kernel_init ...\n"); - // int rc = extra_init(EXTRA_EVENT_POST_KERNEL_INIT); - // log_boot("extra_init done: %d\n", rc); + // int rc = extra_load_kpm(EXTRA_EVENT_POST_KERNEL_INIT); + // log_boot("extra_load_kpm done: %d\n", rc); } int patch() From 9e83c90a94768573aef8f40cf46964b9561f4427 Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 22 Feb 2024 10:49:51 +0800 Subject: [PATCH 32/51] a --- kernel/patch/common/extrainit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/patch/common/extrainit.c b/kernel/patch/common/extrainit.c index 7a385796..0747a425 100644 --- a/kernel/patch/common/extrainit.c +++ b/kernel/patch/common/extrainit.c @@ -14,7 +14,7 @@ static int extra_load_kpm_callback(const patch_extra_item_t *extra, const char * { const char *event = (const char *)udata; if (extra->type == EXTRA_TYPE_KPM) { - if (!strcmp(event, extra->event) || (!extra->event[0]) && !strcmp(EXTRA_EVENT_KPM_DEFAULT, event)) { + if (!strcmp(event, extra->event) || (!extra->event[0] && !strcmp(EXTRA_EVENT_KPM_DEFAULT, event))) { int rc = load_module(data, extra->con_size, args, event, 0); log_boot("%s loading extra kpm return: %d\n", event, rc); } From 06b8580a8f6ec254e172eb8e9f1efaf1060dacee Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 22 Feb 2024 14:54:21 +0800 Subject: [PATCH 33/51] a --- kernel/include/preset.h | 2 +- kernel/patch/common/pidmem.c | 31 ++++++++++----------- kpm-demo/shmem/main.c | 2 -- tools/kptools.c | 6 +--- tools/patch.c | 54 +++++++++++++++++------------------- tools/patch.h | 1 - 6 files changed, 42 insertions(+), 54 deletions(-) diff --git a/kernel/include/preset.h b/kernel/include/preset.h index 6c32af13..655b3512 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -30,7 +30,7 @@ #define PATCH_SYMBOL_LEN (512) -#define ADDITIONAL_LEN (256) +#define ADDITIONAL_LEN (512) #define PATCH_EXTRA_ITEM_LEN (128) diff --git a/kernel/patch/common/pidmem.c b/kernel/patch/common/pidmem.c index fd6c8618..4579d238 100644 --- a/kernel/patch/common/pidmem.c +++ b/kernel/patch/common/pidmem.c @@ -10,28 +10,27 @@ phys_addr_t pid_virt_to_phys(pid_t pid, uintptr_t vaddr) { - if (mm_struct_offset.pgd_offset < 0) { - return -EFAULT; - } + // if (mm_struct_offset.pgd_offset < 0) { + // return -EFAULT; + // } - struct task_struct *task = find_get_task_by_vpid(pid); - if (!task) { - logkfe("no such pid: %d\n", pid); - return -ESRCH; - } + // struct task_struct *task = find_get_task_by_vpid(pid); + // if (!task) { + // logkfe("no such pid: %d\n", pid); + // return -ESRCH; + // } int rc = 0; - struct mm_struct *mm = get_task_mm(task); - if (IS_ERR(mm)) { - // todo - } - uintptr_t pgd = *(uintptr_t *)((uintptr_t)mm + mm_struct_offset.pgd_offset); - uintptr_t *entry = pgtable_entry(pgd, vaddr); + // struct mm_struct *mm = get_task_mm(task); + // if (IS_ERR(mm)) { + // // todo + // } + // uintptr_t pgd = *(uintptr_t *)((uintptr_t)mm + mm_struct_offset.pgd_offset); + // uintptr_t *entry = pgtable_entry(pgd, vaddr); // remap_pfn_range or direct modify pgtable - mmput(mm); -out: + // mmput(mm); return rc; } \ No newline at end of file diff --git a/kpm-demo/shmem/main.c b/kpm-demo/shmem/main.c index da54b19d..98a9f14f 100644 --- a/kpm-demo/shmem/main.c +++ b/kpm-demo/shmem/main.c @@ -19,8 +19,6 @@ KPM_DESCRIPTION("Share memory between processes"); /* * This module's main functionality is to map any address of any process to any other process. * Of course, this means you can easily manipulate data of other processes. - * However, this is too powerful and ... - * so let's leave it aside for now. Perhaps it will be developed someday ...... */ static long init(const char *args, const char *event, void *__user reserved) diff --git a/tools/kptools.c b/tools/kptools.c index 1c841130..e94c751b 100644 --- a/tools/kptools.c +++ b/tools/kptools.c @@ -96,9 +96,8 @@ int main(int argc, char *argv[]) { "extra-name", required_argument, NULL, 'N' }, { "extra-event", required_argument, NULL, 'V' }, { "extra-args", required_argument, NULL, 'A' }, - { "extra-detach", no_argument, NULL, 'D' }, { 0, 0, 0, 0 } }; - char *optstr = "hvpurdli:s:k:o:K:M:E:T:N:V:A:D"; + char *optstr = "hvpurdli:s:k:o:a:K:M:E:T:N:V:A:"; char *kimg_path = NULL; char *kpimg_path = NULL; @@ -171,9 +170,6 @@ int main(int argc, char *argv[]) case 'A': config->set_args = optarg; break; - case 'D': - config->set_detach = true; - break; default: break; } diff --git a/tools/patch.c b/tools/patch.c index 42c14a22..c4aaa11e 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -94,12 +94,11 @@ void print_preset_info(preset_t *preset) fprintf(stdout, INFO_ADDITIONAL_SESSION "\n"); char *pos = setup->additional; - for (; pos < setup->additional + ADDITIONAL_LEN - 1;) { - pos++; - if (!*(pos - 1) && *pos) { - fprintf(stdout, "%s\n", pos); - pos += strlen(pos); - } + while (pos < setup->additional + ADDITIONAL_LEN) { + int len = *pos; + if (!len) break; + fprintf(stdout, "%s\n", strndup(++pos, len)); + pos += len; } } @@ -215,19 +214,19 @@ int print_image_patch_info(patched_kimg_t *pimg) fprintf(stdout, "name=%s\n", item->name); fprintf(stdout, "event=%s\n", item->event); fprintf(stdout, "priority=%d\n", item->priority); - fprintf(stdout, "con_size=0x%x\n", item->con_size); fprintf(stdout, "args_size=0x%x\n", item->args_size); - if (item->args_size > 0) { - fprintf(stdout, "args=%s\n", (char *)item + sizeof(*item)); - } else { - fprintf(stdout, "args=\n"); - } + fprintf(stdout, "args=%s\n", item->args_size > 0 ? (char *)item + sizeof(*item) : ""); + fprintf(stdout, "con_size=0x%x\n", item->con_size); + if (item->type == EXTRA_TYPE_KPM) { kpm_info_t kpm_info = { 0 }; void *kpm = (kpm_info_t *)((uintptr_t)item + sizeof(patch_extra_item_t) + item->args_size); rc = get_kpm_info(kpm, item->con_size, &kpm_info); if (rc) tools_loge_exit("get kpm infomation error: %d\n", rc); - print_kpm_info(&kpm_info); + fprintf(stdout, "version=%s\n", kpm_info.version); + fprintf(stdout, "license=%s\n", kpm_info.license); + fprintf(stdout, "author=%s\n", kpm_info.author); + fprintf(stdout, "description=%s\n", kpm_info.description); } } } @@ -340,9 +339,8 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * } else { const char *name = config->name; for (int j = 0; j < pimg.embed_item_num; j++) { - if (config->set_detach) continue; - if (strcmp(name, config->item->name)) continue; item = pimg.embed_item[j]; + if (strcmp(name, item->name)) continue; if (is_be() ^ kinfo->is_be) { item->type = i32swp(item->type); item->priority = i32swp(item->priority); @@ -372,7 +370,6 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * for (int i = 0; i < extra_config_num; i++) { extra_config_t *config = extra_configs + i; - if (config->set_detach) continue; extra_num++; extra_size += sizeof(patch_extra_item_t); extra_size += config->item->args_size; @@ -462,22 +459,20 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * int text_offset = align_kimg_len + SZ_4K; b((uint32_t *)(out_img + kinfo->b_stext_insn_offset), kinfo->b_stext_insn_offset, text_offset); - // additional key=value set + // additional [len key=value] set char *addition_pos = setup->additional; - for (; addition_pos < setup->additional + ADDITIONAL_LEN - 1; addition_pos++) { - if (!*addition_pos && !*(addition_pos + 1)) break; - } for (int i = 0;; i++) { - addition_pos++; const char *kv = additional[i]; if (!kv) break; - if (!strchr(kv, '=')) { - tools_loge_exit("addition must be format of key=value\n"); - } + if (!strchr(kv, '=')) tools_loge_exit("addition must be format of key=value\n"); + int kvlen = strlen(kv); - if (addition_pos + kvlen >= setup->additional + ADDITIONAL_LEN) { - tools_loge_exit("no memory for addition\n"); - } + if (kvlen > 127) tools_loge_exit("addition %s too long\n", kv); + if (addition_pos + kvlen + 1 > setup->additional + ADDITIONAL_LEN) tools_loge_exit("no memory for addition\n"); + + *addition_pos = (char)kvlen; + addition_pos++; + tools_logi("adding addition: %s\n", kv); strcpy(addition_pos, kv); addition_pos += kvlen; @@ -491,8 +486,9 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * extra_config_t *config = extra_configs + i; patch_extra_item_t *item = config->item; const char *type = extra_type_str(item->type); - tools_logi("embedding %s, name: %s, priority: %d, event: %s, size: 0x%x+0x%x+0x%x\n", type, item->name, - item->priority, item->event, (int)sizeof(*item), item->args_size, item->con_size); + tools_logi("embedding %s, name: %s, priority: %d, event: %s, args: %s, size: 0x%x+0x%x+0x%x\n", type, + item->name, item->priority, item->event, config->set_args ?: "", (int)sizeof(*item), item->args_size, + item->con_size); int args_len = item->args_size; int con_len = item->con_size; diff --git a/tools/patch.h b/tools/patch.h index 23a54a7a..fa25d758 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -46,7 +46,6 @@ typedef struct const char *set_name; const char *set_event; int priority; - bool set_detach; const char *data; patch_extra_item_t *item; } extra_config_t; From e75606376b34d7682d50908d8f0d081d6dafa323 Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 22 Feb 2024 17:09:49 +0800 Subject: [PATCH 34/51] a --- doc/zh-CN/module.md | 4 ---- kernel/base/predata.c | 5 +++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/doc/zh-CN/module.md b/doc/zh-CN/module.md index 4213794f..05a37b1c 100644 --- a/doc/zh-CN/module.md +++ b/doc/zh-CN/module.md @@ -4,10 +4,6 @@ **KPM is an ELF file that can be loaded and run within the kernel space by KernelPatch.** - KPM in principle and implementation is quite similar to LKM. There is no doubt about this, as much of the implementation code in KPM is derived from LKM. However, this does not imply a seamless transition from LKM to KPM, as there may be numerous compatibility issues. - - **The design purpose of KPM is not to replace LKM; rather, KPM is intended to accomplish specific, small, and elegant tasks, such as monitoring and hiding. Of course, if you want to develop a complex module, you can do that too.** - ## How to write a KPM Here are a few examples that you can use to quickly understand. diff --git a/kernel/base/predata.c b/kernel/base/predata.c index 8c2fea1e..797a2caf 100644 --- a/kernel/base/predata.c +++ b/kernel/base/predata.c @@ -39,8 +39,9 @@ int on_each_extra_item(int (*callback)(const patch_extra_item_t *extra, const ch while (item_addr < _kp_extra_end) { patch_extra_item_t *item = (patch_extra_item_t *)item_addr; if (item->type == EXTRA_TYPE_NONE) break; - rc = callback(item, (const char *)(item_addr + sizeof(patch_extra_item_t)), - (void *)(item_addr + sizeof(patch_extra_item_t) + item->args_size), udata); + const char *args = item->args_size > 0 ? (const char *)(item_addr + sizeof(patch_extra_item_t)) : 0; + const void *con = (void *)(item_addr + sizeof(patch_extra_item_t) + item->args_size); + rc = callback(item, args, con, udata); if (rc) break; item_addr += sizeof(patch_extra_item_t); item_addr += item->args_size; From 69093911ac55f9ba7ef275072fe96836ab6f47b2 Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 22 Feb 2024 18:55:06 +0800 Subject: [PATCH 35/51] a --- kernel/patch/ksyms/misc.c | 4 ++-- kernel/patch/ksyms/task_cred.c | 29 +++++++++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/kernel/patch/ksyms/misc.c b/kernel/patch/ksyms/misc.c index 1d30b3d6..37aec928 100644 --- a/kernel/patch/ksyms/misc.c +++ b/kernel/patch/ksyms/misc.c @@ -265,8 +265,8 @@ int kfunc_def(stop_machine)(int (*fn)(void *), void *data, const struct cpumask static void _linux_kernel_stop_machine_sym_match(const char *name, unsigned long addr) { - kvar_match(stop_machine_initialized, name, addr); - kvar_match(cpu_online_mask, name, addr); + // kvar_match(stop_machine_initialized, name, addr); + // kvar_match(cpu_online_mask, name, addr); kfunc_match(stop_machine, name, addr); } diff --git a/kernel/patch/ksyms/task_cred.c b/kernel/patch/ksyms/task_cred.c index e8c1eb98..d8d6c64f 100644 --- a/kernel/patch/ksyms/task_cred.c +++ b/kernel/patch/ksyms/task_cred.c @@ -584,19 +584,20 @@ int resolve_current() return 0; } -int resolve_mm_struct_offset() -{ - log_boot("struct mm_struct: \n"); - uintptr_t init_mm_addr = (uintptr_t)init_mm; - for (uintptr_t i = init_mm_addr; i < init_mm_addr + MM_STRUCT_MAX_SIZE; i += sizeof(uintptr_t)) { - uint64_t pgd = *(uintptr_t *)i; - if (pgd == phys_to_kimg(pgd_pa)) { - mm_struct_offset.pgd_offset = i - init_mm_addr; - } - } - log_boot(" pgd offset: %x\n", mm_struct_offset.pgd_offset); - return 0; -} +// int resolve_mm_struct_offset() +// { +// log_boot("struct mm_struct: \n"); +// uintptr_t init_mm_addr = (uintptr_t)init_mm; +// struct mm_struct *mm = get_task_mm(task); +// for (uintptr_t i = init_mm_addr; i < init_mm_addr + MM_STRUCT_MAX_SIZE; i += sizeof(uintptr_t)) { +// uint64_t pgd = *(uintptr_t *)i; +// if (pgd == phys_to_kimg(pgd_pa)) { +// mm_struct_offset.pgd_offset = i - init_mm_addr; +// } +// } +// log_boot(" pgd offset: %x\n", mm_struct_offset.pgd_offset); +// return 0; +// } int resolve_struct() { @@ -607,7 +608,7 @@ int resolve_struct() if ((err = resolve_task_offset())) goto out; if ((err = resolve_cred_offset())) goto out; - resolve_mm_struct_offset(); + // resolve_mm_struct_offset(); out: return err; From 211f03855b94593ef3cb992fc14e1f027463611f Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 22 Feb 2024 19:26:00 +0800 Subject: [PATCH 36/51] version 0.10.0 --- version | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version b/version index f8645495..d68ebbb8 100644 --- a/version +++ b/version @@ -1,3 +1,3 @@ #define MAJOR 0 -#define MINOR 9 -#define PATCH 2 +#define MINOR 10 +#define PATCH 0 From 4c41d0ca0eb68d126d68d6ca01096ca7ab559cea Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 27 Feb 2024 19:45:24 +0800 Subject: [PATCH 37/51] a --- .github/workflows/build_dev.yml | 17 +- kernel/base/fphook.c | 3 +- kernel/base/hook.c | 45 +- kernel/include/hook.h | 7 +- kernel/include/preset.h | 2 + .../linux/arch/arm64/include/asm/processor.h | 3 + kernel/linux/include/linux/slab.h | 1 + kernel/linux/include/linux/uaccess.h | 4 +- kernel/patch/android/kpuserd.c | 24 +- .../patch/android/{sucompat.c => sucompat.c1} | 93 ++-- kernel/patch/android/supercall.c | 4 +- kernel/patch/common/pidmem.c | 2 +- kernel/patch/common/sucompat.c | 470 ++++++++++++++++++ kernel/patch/common/supercall.c | 28 +- kernel/patch/common/syscall.c | 18 +- kernel/patch/common/taskob.c | 2 +- kernel/patch/common/utils.c | 53 +- kernel/patch/include/kputils.h | 4 +- kernel/patch/include/syscall.h | 13 + kernel/patch/ksyms/libs.c | 8 +- kernel/patch/ksyms/misc.c | 12 +- kernel/patch/ksyms/pt_regs.c | 62 +++ kernel/patch/ksyms/suffix_sym.c | 0 kernel/patch/module/module.c | 2 +- kernel/patch/patch.c | 10 +- kpm-demo/hello/hello.c | 2 +- kpm-demo/syscallhook/syscallhook.c | 2 +- tools/symbol.c | 96 ++-- user/android/android_user.c | 53 +- 29 files changed, 815 insertions(+), 225 deletions(-) rename kernel/patch/android/{sucompat.c => sucompat.c1} (82%) create mode 100644 kernel/patch/common/sucompat.c create mode 100644 kernel/patch/ksyms/pt_regs.c delete mode 100644 kernel/patch/ksyms/suffix_sym.c diff --git a/.github/workflows/build_dev.yml b/.github/workflows/build_dev.yml index e1d2b2ce..8d217d7d 100644 --- a/.github/workflows/build_dev.yml +++ b/.github/workflows/build_dev.yml @@ -1,22 +1,7 @@ name: Build DEV CI on: - push: - branches: ["dev"] - paths: - - ".github/workflows/build_dev.yml" - - "kernel/**" - - "user/**" - - "tools/**" - - "version" - pull_request: - branches: ["dev"] - paths: - - ".github/workflows/build_dev.yml" - - "kernel/**" - - "user/**" - - "tools/**" - - "version" + workflow_dispatch: jobs: Build-kpimg: diff --git a/kernel/base/fphook.c b/kernel/base/fphook.c index 31325806..6f8bba4d 100644 --- a/kernel/base/fphook.c +++ b/kernel/base/fphook.c @@ -244,7 +244,7 @@ KP_EXPORT_SYMBOL(fp_unhook); hook_err_t fp_hook_wrap(uintptr_t fp_addr, int32_t argno, void *before, void *after, void *udata) { hook_err_t err = HOOK_NO_ERR; - if (!fp_addr) return -HOOK_INPUT_NULL; + if (is_bad_address((void *)fp_addr)) return -HOOK_BAD_ADDRESS; fp_hook_chain_t *chain = hook_get_mem_from_origin(fp_addr); if (!chain) { chain = (fp_hook_chain_t *)hook_mem_zalloc(fp_addr, FUNCTION_POINTER_CHAIN); @@ -281,6 +281,7 @@ KP_EXPORT_SYMBOL(fp_hook_wrap); void fp_hook_unwrap(uintptr_t fp_addr, void *before, void *after) { + if (is_bad_address((void *)fp_addr)) return; fp_hook_chain_t *chain = (fp_hook_chain_t *)hook_get_mem_from_origin(fp_addr); if (!chain) return; for (int i = 0; i < FP_HOOK_CHAIN_NUM; i++) { diff --git a/kernel/base/hook.c b/kernel/base/hook.c index 60616766..049a6931 100644 --- a/kernel/base/hook.c +++ b/kernel/base/hook.c @@ -36,6 +36,7 @@ typedef uint32_t inst_mask_t; #define INST_CBNZ 0x35000000 #define INST_TBZ 0x36000000 #define INST_TBNZ 0x37000000 +#define INST_HINT 0xD503201F #define INST_IGNORE 0x0 #define MASK_B 0xFC000000 @@ -54,6 +55,7 @@ typedef uint32_t inst_mask_t; #define MASK_CBNZ 0x7F000000u #define MASK_TBZ 0x7F000000u #define MASK_TBNZ 0x7F000000u +#define MASK_HINT 0xFFFFF01F #define MASK_IGNORE 0x0 static inst_mask_t masks[] = { @@ -107,16 +109,38 @@ static uint64_t relo_in_tramp(hook_t *hook, uint64_t addr) } #ifdef HOOK_INTO_BRANCH_FUNC -uint64_t branch_func_addr(uint64_t addr) + +static uint64_t branch_func_addr_once(uint64_t addr) { + uint64_t ret = addr; uint32_t inst = *(uint32_t *)addr; if ((inst & MASK_B) == INST_B) { uint64_t imm26 = bits32(inst, 25, 0); uint64_t imm64 = sign64_extend(imm26 << 2u, 28u); - addr += imm64; + ret = addr + imm64; + } else { + addr += 4; + uint32_t inst1 = *(uint32_t *)addr; + if (((inst & MASK_HINT) == INST_HINT) && ((inst1 & MASK_B) == INST_B)) { + uint64_t imm26 = bits32(inst1, 25, 0); + uint64_t imm64 = sign64_extend(imm26 << 2u, 28u); + ret = addr + imm64; + } + } + return ret; +} + +uint64_t branch_func_addr(uint64_t addr) +{ + uint64_t ret; + for (;;) { + ret = branch_func_addr_once(addr); + if (ret == addr) break; + addr = ret; } - return addr; + return ret; } + #endif hook_err_t relo_b(hook_t *hook, uint64_t inst_addr, uint32_t inst, inst_type_t type) @@ -532,9 +556,11 @@ static __noinline hook_err_t relocate_inst(hook_t *hook, uint64_t inst_addr, uin hook_err_t hook_prepare(hook_t *hook) { - if (!hook->func_addr || !hook->origin_addr || !hook->replace_addr || !hook->relo_addr) { - return -HOOK_INPUT_NULL; - } + if (is_bad_address((void *)hook->func_addr)) return -HOOK_BAD_ADDRESS; + if (is_bad_address((void *)hook->origin_addr)) return -HOOK_BAD_ADDRESS; + if (is_bad_address((void *)hook->replace_addr)) return -HOOK_BAD_ADDRESS; + if (is_bad_address((void *)hook->relo_addr)) return -HOOK_BAD_ADDRESS; + // backup origin instruction for (int i = 0; i < TRAMPOLINE_NUM; i++) { hook->origin_insts[i] = *((uint32_t *)hook->origin_addr + i); @@ -604,7 +630,7 @@ hook_err_t hook(void *func, void *replace, void **backup) { hook_err_t err = HOOK_NO_ERR; if (!func || !replace || !backup) { - return -HOOK_INPUT_NULL; + return -HOOK_BAD_ADDRESS; } uint64_t origin_addr = branch_func_addr((uintptr_t)func); hook_t *hook = (hook_t *)hook_mem_zalloc(origin_addr, INLINE); @@ -724,9 +750,10 @@ KP_EXPORT_SYMBOL(hook_chain_remove); // todo: lock hook_err_t hook_wrap(void *func, int32_t argno, void *before, void *after, void *udata) { - if (!func) return -HOOK_INPUT_NULL; + if (is_bad_address(func)) return -HOOK_BAD_ADDRESS; uint64_t faddr = (uint64_t)func; uint64_t origin = branch_func_addr(faddr); + if (is_bad_address(func)) return -HOOK_BAD_ADDRESS; hook_chain_t *chain = (hook_chain_t *)hook_get_mem_from_origin(origin); if (chain) return hook_chain_add(chain, before, after, udata); chain = (hook_chain_t *)hook_mem_zalloc(origin, INLINE_CHAIN); @@ -757,8 +784,10 @@ KP_EXPORT_SYMBOL(hook_wrap); void hook_unwrap_remove(void *func, void *before, void *after, int remove) { + if (is_bad_address(func)) return; uint64_t faddr = (uint64_t)func; uint64_t origin = branch_func_addr(faddr); + if (is_bad_address(func)) return; hook_chain_t *chain = (hook_chain_t *)hook_get_mem_from_origin(origin); if (!chain) return; hook_chain_remove(chain, before, after); diff --git a/kernel/include/hook.h b/kernel/include/hook.h index 0ec14159..0d028c41 100644 --- a/kernel/include/hook.h +++ b/kernel/include/hook.h @@ -14,7 +14,7 @@ typedef enum { HOOK_NO_ERR = 0, - HOOK_INPUT_NULL = 4089, + HOOK_BAD_ADDRESS = 4089, HOOK_NO_MEM = 4090, HOOK_BAD_RELO = 4091, HOOK_TRANSIT_NO_MEM = 4092, @@ -229,6 +229,11 @@ typedef struct _fphook_chain uint32_t transit[TRANSIT_INST_NUM]; } fp_hook_chain_t __attribute__((aligned(8))); +static inline int is_bad_address(void *addr) +{ + return ((uint64_t)addr & 0x8000000000000000) != 0x8000000000000000; +} + int32_t branch_from_to(uint32_t *tramp_buf, uint64_t src_addr, uint64_t dst_addr); int32_t branch_relative(uint32_t *buf, uint64_t src_addr, uint64_t dst_addr); int32_t branch_absolute(uint32_t *buf, uint64_t addr); diff --git a/kernel/include/preset.h b/kernel/include/preset.h index 655b3512..2a8b3c3f 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -122,10 +122,12 @@ struct patch_symbol uint64_t slow_avc_audit; uint64_t input_handle_event; uint64_t vfs_statx; + uint64_t vfs_stat; uint64_t do_statx; uint64_t vfs_fstatat; uint64_t do_faccessat; uint64_t sys_faccessat; + uint64_t sys_faccessat2; }; char _cap[PATCH_SYMBOL_LEN]; }; diff --git a/kernel/linux/arch/arm64/include/asm/processor.h b/kernel/linux/arch/arm64/include/asm/processor.h index 9fcdabd1..ca39a61c 100644 --- a/kernel/linux/arch/arm64/include/asm/processor.h +++ b/kernel/linux/arch/arm64/include/asm/processor.h @@ -18,6 +18,9 @@ // #define task_pt_regs(p) ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) // implemented in utils + +extern int16_t pt_regs_offset; + struct pt_regs *_task_pt_reg(struct task_struct *task); #define task_pt_regs(p) _task_pt_reg(p) diff --git a/kernel/linux/include/linux/slab.h b/kernel/linux/include/linux/slab.h index 1a5a983f..bceb3f2f 100644 --- a/kernel/linux/include/linux/slab.h +++ b/kernel/linux/include/linux/slab.h @@ -33,6 +33,7 @@ void *kmalloc_node_trace(struct kmem_cache *s, gfp_t gfpflags, int node, size_t void *kmalloc_large(size_t size, gfp_t flags); void *kmalloc_large_node(size_t size, gfp_t flags, int node); +// todo: kernel version specified different gfp_t static inline void *kmalloc(size_t size, gfp_t flags) { kfunc_call(kmalloc, size, flags); diff --git a/kernel/linux/include/linux/uaccess.h b/kernel/linux/include/linux/uaccess.h index 24e30b0e..27b2f362 100644 --- a/kernel/linux/include/linux/uaccess.h +++ b/kernel/linux/include/linux/uaccess.h @@ -13,7 +13,7 @@ // unsigned long __must_check copy_in_user(void __user *to, const void __user *from, unsigned long n); // >= 5.8, On success, returns the length of the string INCLUDING the trailing NUL. -extern long kfunc_def(strncpy_from_user_nofault)(char *dst, const void __user *unsafe_addr, long count); +extern long kfunc_def(compact_strncpy_from_user)(char *dst, const void __user *unsafe_addr, long count); /** * strncpy_from_unsafe_user: - Copy a NUL terminated string from unsafe user * address. @@ -58,7 +58,7 @@ extern long kfunc_def(strnlen_user_nofault)(const void __user *unsafe_addr, long extern long kfunc_def(strnlen_unsafe_user)(const void __user *unsafe_addr, long count); extern long kfunc_def(strnlen_user)(const char __user *str, long n); -long strncpy_from_user_nofault(char *dest, const char __user *src, long count); +long compact_strncpy_from_user(char *dest, const char __user *src, long count); static inline long strnlen_user_nofault(const char __user *str, long n) { diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index e26d036c..7e5711bc 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -54,7 +54,7 @@ static const void *kernel_read_file(const char *path, loff_t *len) { void *data = 0; struct file *filp = filp_open(path, O_RDONLY, 0); - if (IS_ERR(filp)) { + if (!filp || IS_ERR(filp)) { log_boot("open file: %s error: %d\n", path, PTR_ERR(filp)); goto out; } @@ -72,7 +72,7 @@ static void kernel_write_file(const char *path, const void *data, loff_t len, um { set_priv_selinx_allow(current, 1); struct file *fp = filp_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode); - if (IS_ERR(fp)) { + if (!fp || IS_ERR(fp)) { log_boot("create file %s error: %d\n", path, PTR_ERR(fp)); goto out; } @@ -128,7 +128,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) filename_index = 1; } struct filename *filename = (struct filename *)args->args[filename_index]; - if (!filename || IS_ERR(filename)) return; + if (!filename || !filename || IS_ERR(filename)) return; const char app_process[] = "/system/bin/app_process"; static int first_app_process = 1; @@ -151,9 +151,9 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) const char *__user p1 = get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); if (!p1) break; - if (!IS_ERR(p1)) { + if (!!p1 || IS_ERR(p1)) { char arg[16] = { '\0' }; - if (strncpy_from_user_nofault(arg, p1, sizeof(arg)) <= 0) break; + if (compact_strncpy_from_user(arg, p1, sizeof(arg)) <= 0) break; if (!strcmp(arg, "second_stage") || !strcmp(arg, "--second-stage")) { log_boot("exec %s second stage 0\n", filename->name); before_second_stage(); @@ -168,9 +168,9 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) for (int i = 0;; i++) { const char *__user up = get_user_arg_ptr((void *)args->args[envp_index], (void *)args->args[envp_index + 1], i); - if (IS_ERR(up)) break; + if (!up || IS_ERR(up)) break; char env[256]; - if (strncpy_from_user_nofault(env, up, sizeof(env)) <= 0) break; + if (compact_strncpy_from_user(env, up, sizeof(env)) <= 0) break; char *env_name = env; char *env_value = strchr(env, '='); if (env_value) { @@ -207,7 +207,7 @@ static void before_openat(hook_fargs4_t *args, void *udata) const char __user *filename = (typeof(filename))syscall_argn(args, 1); char buf[32]; - strncpy_from_user_nofault(buf, filename, sizeof(buf)); + compact_strncpy_from_user(buf, filename, sizeof(buf)); if (strcmp(ORIGIN_RC_FILE, buf)) return; replaced = 1; @@ -216,7 +216,7 @@ static void before_openat(hook_fargs4_t *args, void *udata) // create replace file and redirect loff_t ori_len = 0; struct file *newfp = filp_open(REPLACE_RC_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (IS_ERR(newfp)) { + if (!newfp || IS_ERR(newfp)) { log_boot("create replace rc error: %d\n", PTR_ERR(newfp)); goto out; } @@ -234,7 +234,7 @@ static void before_openat(hook_fargs4_t *args, void *udata) goto free; } // yes, filename is not read only - args->local.data0 = seq_copy_to_user((void *)filename, REPLACE_RC_FILE, sizeof(REPLACE_RC_FILE)); + args->local.data0 = compat_copy_to_user((void *)filename, REPLACE_RC_FILE, sizeof(REPLACE_RC_FILE)); log_boot("redirect rc file: %x\n", args->local.data0); free: filp_close(newfp, 0); @@ -250,7 +250,7 @@ static void after_openat(hook_fargs4_t *args, void *udata) { if (args->local.data0) { const char __user *filename = (typeof(filename))syscall_argn(args, 1); - int len = seq_copy_to_user((void *)filename, ORIGIN_RC_FILE, sizeof(ORIGIN_RC_FILE)); + int len = compat_copy_to_user((void *)filename, ORIGIN_RC_FILE, sizeof(ORIGIN_RC_FILE)); log_boot("restore rc file: %x\n", len); fp_unhook_syscall(__NR_openat, before_openat, after_openat); } @@ -272,7 +272,7 @@ static void before_input_handle_event(hook_fargs4_t *args, void *udata) if (volumedown_pressed_count == 3) { log_boot("entering safemode ..."); struct file *filp = filp_open(SAFE_MODE_FLAG_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0666); - if (!IS_ERR(filp)) filp_close(filp, 0); + if (!!filp || IS_ERR(filp)) filp_close(filp, 0); } } } diff --git a/kernel/patch/android/sucompat.c b/kernel/patch/android/sucompat.c1 similarity index 82% rename from kernel/patch/android/sucompat.c rename to kernel/patch/android/sucompat.c1 index 343e65c7..619aa60e 100644 --- a/kernel/patch/android/sucompat.c +++ b/kernel/patch/android/sucompat.c1 @@ -180,10 +180,10 @@ int su_allow_uids(uid_t *__user uuids, int unum) goto out; } uid_t uid = pos->profile.uid; - int cplen = seq_copy_to_user(uuids + num, &uid, sizeof(uid)); + int cplen = compat_copy_to_user(uuids + num, &uid, sizeof(uid)); logkfd("uid: %d\n", uid); if (cplen <= 0) { - logkfd("seq_copy_to_user error: %d", cplen); + logkfd("compat_copy_to_user error: %d", cplen); rc = cplen; goto out; } @@ -203,10 +203,10 @@ int su_allow_uid_profile(uid_t uid, struct su_profile *__user uprofile) list_for_each_entry(pos, &allow_uid_list, list) { if (pos->profile.uid != uid) continue; - int cplen = seq_copy_to_user(uprofile, &pos->profile, sizeof(struct su_profile)); + int cplen = compat_copy_to_user(uprofile, &pos->profile, sizeof(struct su_profile)); logkfd("profile: %d %d %s\n", uid, pos->profile.to_uid, pos->profile.scontext); if (cplen <= 0) { - logkfd("seq_copy_to_user error: %d", cplen); + logkfd("compat_copy_to_user error: %d", cplen); rc = cplen; goto out; } @@ -244,7 +244,7 @@ int su_get_path(char *__user ubuf, int buf_len) if (len <= 0) return -EINVAL; if (buf_len < len) return -ENOBUFS; logkfi("%s\n", current_su_path); - return seq_copy_to_user(ubuf, current_su_path, len + 1); + return compat_copy_to_user(ubuf, current_su_path, len + 1); } // todo: rcu_dereference_protected @@ -261,7 +261,7 @@ static void *__user copy_to_user_stack(void *data, size_t len) uintptr_t addr = current_user_stack_pointer(); addr -= len; addr &= 0xFFFFFFFFFFFFFFF0; - seq_copy_to_user((void *)addr, data, len); + compat_copy_to_user((void *)addr, data, len); return (void *)addr; } @@ -290,7 +290,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) } filename = (struct filename *)args->args[filename_index]; - if (IS_ERR(filename)) return; + if (!filename || IS_ERR(filename)) return; if (!strcmp(current_su_path, filename->name)) { uid_t uid = current_uid(); @@ -302,7 +302,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) commit_su(to_uid, sctx); struct file *filp = filp_open(apd_path, O_RDONLY, 0); - if (IS_ERR(filp)) { + if (!filp || IS_ERR(filp)) { logkfi("call su uid: %d, to_uid: %d, sctx: %s\n", uid, to_uid, sctx); strcpy((char *)filename->name, sh_path); } else { @@ -311,9 +311,9 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) strcpy((char *)filename->name, apd_path); const char *__user p0 = get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], 0); - int sz = seq_copy_to_user((char *__user)p0, default_su_path, sizeof(default_su_path)); + int sz = compat_copy_to_user((char *__user)p0, default_su_path, sizeof(default_su_path)); if (sz != sizeof(default_su_path)) { - logkfe("seq_copy_to_user error: %d\n", sz); + logkfe("compat_copy_to_user error: %d\n", sz); } } kvfree(profile); @@ -322,11 +322,11 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) void *ua1 = (void *)args->args[filename_index + 2]; // key const char __user *p1 = get_user_arg_ptr(ua0, ua1, 1); - if (IS_ERR(p1)) return; + if (!p1 || IS_ERR(p1)) return; // auth skey char arg1[SUPER_KEY_LEN]; - if (strncpy_from_user_nofault(arg1, p1, sizeof(arg1)) <= 0) return; + if (compact_strncpy_from_user(arg1, p1, sizeof(arg1)) <= 0) return; if (superkey_auth(arg1)) return; commit_su(0, 0); @@ -334,14 +334,14 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) // real exec const char __user *p2 = get_user_arg_ptr(ua0, ua1, 2); - if (IS_ERR(p2)) { + if (!p2 || IS_ERR(p2)) { strcpy((char *)filename->name, sh_path); return; } #define EMBEDDED_NAME_MAX (PATH_MAX - sizeof(*filename) - 128) // enough - int len = strncpy_from_user_nofault((char *)filename->name, p2, EMBEDDED_NAME_MAX); + int len = compact_strncpy_from_user((char *)filename->name, p2, EMBEDDED_NAME_MAX); if (unlikely(len < 0)) return; // user_arg_ptr @@ -359,14 +359,14 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) // for (int i = 3; i < 10; i++) { // const char *pn = // get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); - // if (IS_ERR(pn)) break; - // strncpy_from_user_nofault(option, pn, sizeof(option)); + // if (!pn || IS_ERR(pn)) break; + // compact_strncpy_from_user(option, pn, sizeof(option)); // if (!strcmp("--path", option)) { // i++; // pn = // get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); - // if (IS_ERR(pn)) break; - // strncpy_from_user_nofault(option, pn, sizeof(option)); + // if (!pn || IS_ERR(pn)) break; + // compact_strncpy_from_user(option, pn, sizeof(option)); // strcpy((char *)filename->name, option); // } // } @@ -377,6 +377,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) // long do_faccessat(int dfd, const char __user *filename, int mode, int flags) // SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) +// SYSCALL_DEFINE4(faccessat2, int, dfd, const char __user *, filename, int, mode, int, flags) static void before_faccessat(hook_fargs4_t *args, void *udata) { uid_t uid = current_uid(); @@ -386,7 +387,7 @@ static void before_faccessat(hook_fargs4_t *args, void *udata) char __user *filename = (char __user *)args->arg1; char buf[SU_PATH_MAX_LEN]; - strncpy_from_user_nofault(buf, filename, sizeof(buf)); + compact_strncpy_from_user(buf, filename, sizeof(buf)); if (strcmp(buf, local_su_path)) return; logkfd("uid: %d\n", uid); @@ -395,6 +396,7 @@ static void before_faccessat(hook_fargs4_t *args, void *udata) } // int vfs_statx(int dfd, struct filename *filename, int flags, struct kstat *stat, u32 request_mask) +// int do_statx(int dfd, struct filename *filename, unsigned int flags, unsigned int mask, struct statx __user *buffer) // int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, int flags) // int do_statx(int dfd, struct filename *filename, unsigned int flags, unsigned int mask, struct statx __user *buffer) // int do_statx(int dfd, const char __user *filename, unsigned flags, unsigned int mask, struct statx __user *buffer) @@ -415,12 +417,12 @@ static void before_stat(hook_fargs8_t *args, void *udata) // assume this is kernel address if ((((uintptr_t)args->arg1) & 0xFFFF000000000000) == 0xFFFF000000000000) { filename = (struct filename *)args->arg1; - if (IS_ERR(filename)) return; + if (!filename || IS_ERR(filename)) return; if (strcmp(filename->name, local_su_path)) return; } else { u_filename = (char *)args->arg1; char buf[SU_PATH_MAX_LEN]; - strncpy_from_user_nofault(buf, u_filename, sizeof(buf)); + compact_strncpy_from_user(buf, u_filename, sizeof(buf)); if (strcmp(buf, local_su_path)) return; } @@ -429,13 +431,13 @@ static void before_stat(hook_fargs8_t *args, void *udata) strcpy((char *)filename->name, sh_path); } else { logkfd("1 uid: %d\n", uid); - int sz = seq_copy_to_user(u_filename, sh_path, sizeof(sh_path)); + int sz = compat_copy_to_user(u_filename, sh_path, sizeof(sh_path)); if (sz == sizeof(sh_path)) { change_flag = 1; args->local.data[0] = change_flag; args->local.data[1] = (uint64_t)local_su_path; } else { - // logkfe("seq_copy_to_user error: %d\n", sz); + // logkfe("compat_copy_to_user error: %d\n", sz); args->arg1 = (uint64_t)android_sh_user_path(); } } @@ -446,8 +448,8 @@ static void after_stat(hook_fargs8_t *args, void *udata) int change_flag = args->local.data[0]; if (change_flag) { const char *local_su_path = (const char *)args->local.data[1]; - int sz = seq_copy_to_user((void *)args->arg1, local_su_path, strlen(local_su_path) + 1); - if (sz != strlen(local_su_path) + 1) logkfe("seq_copy_to_user error: %d\n", sz); + int sz = compat_copy_to_user((void *)args->arg1, local_su_path, strlen(local_su_path) + 1); + if (sz != strlen(local_su_path) + 1) logkfe("compat_copy_to_user error: %d\n", sz); } } @@ -458,15 +460,15 @@ static void after_stat(hook_fargs8_t *args, void *udata) // args->local.data[0] = change_flag; // char buf[sizeof(su_path)]; -// strncpy_from_user_nofault(buf, (char *__user)args->arg0, sizeof(buf)); +// compact_strncpy_from_user(buf, (char *__user)args->arg0, sizeof(buf)); // if (strcmp(su_path, buf)) return; // uid_t uid = current_uid(); // if (!is_allow_uid(uid)) return; // logkfd("uid: %d\n", uid); -// int sz = seq_copy_to_user((char *__user)args->arg0, sh_path, sizeof(sh_path)); -// if (sz != sizeof(sh_path)) logkfe("seq_copy_to_user error: %d\n", sz); +// int sz = compat_copy_to_user((char *__user)args->arg0, sh_path, sizeof(sh_path)); +// if (sz != sizeof(sh_path)) logkfe("compat_copy_to_user error: %d\n", sz); // change_flag = 1; // args->local.data[0] = change_flag; @@ -476,8 +478,8 @@ static void after_stat(hook_fargs8_t *args, void *udata) // { // int change_flag = args->local.data[0]; // if (change_flag) { -// int sz = seq_copy_to_user((void *)args->arg0, su_path, sizeof(su_path)); -// if (sz != sizeof(su_path)) logkfe("seq_copy_to_user error: %d\n", sz); +// int sz = compat_copy_to_user((void *)args->arg0, su_path, sizeof(su_path)); +// if (sz != sizeof(su_path)) logkfe("compat_copy_to_user error: %d\n", sz); // } // } @@ -497,7 +499,9 @@ int su_compat_init() }; su_add_allow_uid(default_shell_profile.uid, &default_shell_profile, 1); - // state + hook_err_t err = HOOK_NO_ERR; + + // stat unsigned long vfs_stat_addr = get_preset_patch_sym()->vfs_statx; if (!vfs_stat_addr) vfs_stat_addr = get_preset_patch_sym()->do_statx; if (!vfs_stat_addr) vfs_stat_addr = get_preset_patch_sym()->vfs_fstatat; @@ -506,7 +510,7 @@ int su_compat_init() rc = -ENOENT; goto out; } else { - hook_err_t err = hook_wrap8((void *)vfs_stat_addr, before_stat, after_stat, 0); + err |= hook_wrap8((void *)vfs_stat_addr, before_stat, after_stat, 0); if (err) { log_boot("hook vfs_fstatat error: %d\n", err); rc = err; @@ -514,15 +518,24 @@ int su_compat_init() } } + unsigned long xxx = kallsyms_lookup_name("vfs_stat"); + logkd("aaaaaaaaaaaaaaa %llx\n", xxx); + err |= hook_wrap8((void *)xxx, before_stat, after_stat, 0); + // access - unsigned long faccessat_addr = get_preset_patch_sym()->do_faccessat; - if (!faccessat_addr) faccessat_addr = get_preset_patch_sym()->sys_faccessat; - if (!faccessat_addr) { - log_boot("no symbol do_faccessat or sys_faccessat\n"); - rc = -ENOENT; - goto out; + unsigned long do_accessat_addr = get_preset_patch_sym()->do_faccessat; + if (do_accessat_addr) { + err |= hook_wrap4((void *)do_accessat_addr, before_faccessat, 0, 0); + if (err) { + log_boot("hook do_faccessat error: %d\n", err); + rc = err; + goto out; + } } else { - hook_err_t err = hook_wrap4((void *)faccessat_addr, before_faccessat, 0, 0); + unsigned long faccessat_addr = get_preset_patch_sym()->sys_faccessat; + unsigned long faccessat2_addr = get_preset_patch_sym()->sys_faccessat; + err |= hook_wrap4((void *)faccessat_addr, before_faccessat, 0, 0); + err |= hook_wrap4((void *)faccessat2_addr, before_faccessat, 0, 0); if (err) { log_boot("hook do_faccessat error: %d\n", err); rc = err; @@ -531,7 +544,7 @@ int su_compat_init() } // execv - hook_err_t err = add_execv_hook(before_do_execve, 0, 0); + err |= add_execv_hook(before_do_execve, 0, 0); if (err) { log_boot("hook add execv error: %d\n", err); rc = err; diff --git a/kernel/patch/android/supercall.c b/kernel/patch/android/supercall.c index 493f27bb..a336b7e8 100644 --- a/kernel/patch/android/supercall.c +++ b/kernel/patch/android/supercall.c @@ -23,7 +23,7 @@ static long call_grant_uid(uid_t uid, struct su_profile *__user uprofile) { struct su_profile *profile = memdup_user(uprofile, sizeof(struct su_profile)); - if (IS_ERR(profile)) return PTR_ERR(profile); + if (!profile || IS_ERR(profile)) return PTR_ERR(profile); int rc = su_add_allow_uid(uid, profile, 1); kvfree(profile); return rc; @@ -52,7 +52,7 @@ static long call_su_allow_uid_profile(uid_t uid, struct su_profile *__user uprof static long call_reset_su_path(const char *__user upath) { char path[SU_PATH_MAX_LEN]; - strncpy_from_user_nofault(path, upath, sizeof(path)); + compact_strncpy_from_user(path, upath, sizeof(path)); return su_reset_path(path); } diff --git a/kernel/patch/common/pidmem.c b/kernel/patch/common/pidmem.c index 4579d238..19bf6655 100644 --- a/kernel/patch/common/pidmem.c +++ b/kernel/patch/common/pidmem.c @@ -23,7 +23,7 @@ phys_addr_t pid_virt_to_phys(pid_t pid, uintptr_t vaddr) int rc = 0; // struct mm_struct *mm = get_task_mm(task); - // if (IS_ERR(mm)) { + // if (!mm || IS_ERR(mm)) { // // todo // } // uintptr_t pgd = *(uintptr_t *)((uintptr_t)mm + mm_struct_offset.pgd_offset); diff --git a/kernel/patch/common/sucompat.c b/kernel/patch/common/sucompat.c new file mode 100644 index 00000000..9e90a55d --- /dev/null +++ b/kernel/patch/common/sucompat.c @@ -0,0 +1,470 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2023 bmax121. All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char sh_path[] = ANDROID_SH_PATH; +static const char default_su_path[] = ANDROID_SU_PATH; +static const char *current_su_path = 0; +static const char apd_path[] = APD_PATH; + +struct allow_uid +{ + uid_t uid; + struct su_profile profile; + struct list_head list; + struct rcu_head rcu; +}; + +static struct list_head allow_uid_list; +static spinlock_t list_lock; + +static void allow_reclaim_callback(struct rcu_head *rcu) +{ + struct allow_uid *allow = container_of(rcu, struct allow_uid, rcu); + kvfree(allow); +} + +static struct su_profile *search_allow_uid(uid_t uid) +{ + rcu_read_lock(); + struct allow_uid *pos; + list_for_each_entry_rcu(pos, &allow_uid_list, list) + { + if (pos->uid == uid) { + // make a deep copy + struct su_profile *profile = (struct su_profile *)vmalloc(sizeof(struct su_profile)); + memcpy(profile, &pos->profile, sizeof(struct su_profile)); + rcu_read_unlock(); + return profile; + } + } + rcu_read_unlock(); + return 0; +} + +static int is_allow_uid(uid_t uid) +{ + rcu_read_lock(); + struct allow_uid *pos; + list_for_each_entry_rcu(pos, &allow_uid_list, list) + { + if (pos->uid == uid) { + rcu_read_unlock(); + return 1; + } + } + rcu_read_unlock(); + return 0; +} + +int su_add_allow_uid(uid_t uid, struct su_profile *profile, int async) +{ + rcu_read_lock(); + struct allow_uid *pos, *old = 0; + list_for_each_entry(pos, &allow_uid_list, list) + { + if (pos->uid == uid) { + old = pos; + break; + } + } + struct allow_uid *new = (struct allow_uid *)vmalloc(sizeof(struct allow_uid)); + new->uid = profile->uid; + memcpy(&new->profile, profile, sizeof(struct su_profile)); + new->profile.scontext[sizeof(new->profile.scontext) - 1] = '\0'; + + spin_lock(&list_lock); + if (old) { // update + list_replace_rcu(&old->list, &new->list); + logkfi("update uid: %d, to_uid: %d, sctx: %s\n", uid, new->profile.to_uid, new->profile.scontext); + } else { // add new one + list_add_rcu(&new->list, &allow_uid_list); + logkfi("new uid: %d, to_uid: %d, sctx: %s\n", uid, new->profile.to_uid, new->profile.scontext); + } + spin_unlock(&list_lock); + + rcu_read_unlock(); + if (old) { + if (async) { + call_rcu(&old->rcu, allow_reclaim_callback); + } else { + synchronize_rcu(); + kvfree(old); + } + } + return 0; +} + +int su_remove_allow_uid(uid_t uid, int async) +{ + struct allow_uid *pos; + spin_lock(&list_lock); + list_for_each_entry(pos, &allow_uid_list, list) + { + if (pos->uid == uid) { + list_del_rcu(&pos->list); + spin_unlock(&list_lock); + logkfi("uid: %d, to_uid: %d, sctx: %s\n", pos->uid, pos->profile.to_uid, pos->profile.scontext); + if (async) { + call_rcu(&pos->rcu, allow_reclaim_callback); + } else { + synchronize_rcu(); + kvfree(pos); + } + return 0; + } + } + spin_unlock(&list_lock); + return 0; +} + +int su_allow_uid_nums() +{ + int num = 0; + rcu_read_lock(); + struct allow_uid *pos; + list_for_each_entry(pos, &allow_uid_list, list) + { + num++; + } + rcu_read_unlock(); + logkfd("%d\n", num); + return num; +} + +int su_allow_uids(uid_t *__user uuids, int unum) +{ + int rc = 0; + int num = 0; + rcu_read_lock(); + struct allow_uid *pos; + list_for_each_entry(pos, &allow_uid_list, list) + { + if (num >= unum) { + goto out; + } + uid_t uid = pos->profile.uid; + int cplen = compat_copy_to_user(uuids + num, &uid, sizeof(uid)); + logkfd("uid: %d\n", uid); + if (cplen <= 0) { + logkfd("compat_copy_to_user error: %d", cplen); + rc = cplen; + goto out; + } + num++; + } + rc = num; +out: + rcu_read_unlock(); + return rc; +} + +int su_allow_uid_profile(uid_t uid, struct su_profile *__user uprofile) +{ + int rc = -ENOENT; + rcu_read_lock(); + struct allow_uid *pos; + list_for_each_entry(pos, &allow_uid_list, list) + { + if (pos->profile.uid != uid) continue; + int cplen = compat_copy_to_user(uprofile, &pos->profile, sizeof(struct su_profile)); + logkfd("profile: %d %d %s\n", uid, pos->profile.to_uid, pos->profile.scontext); + if (cplen <= 0) { + logkfd("compat_copy_to_user error: %d", cplen); + rc = cplen; + goto out; + } + rc = 0; + goto out; + } +out: + rcu_read_unlock(); + return rc; +} + +// no free, no lock +int su_reset_path(const char *path) +{ + if (!path) return -EINVAL; + int len = strlen(path); + if (len <= 0) return -EINVAL; + char *new_su_path = vmalloc(len + 1); + if (!new_su_path) return -ENOMEM; + strcpy(new_su_path, path); + new_su_path[len] = '\0'; + current_su_path = new_su_path; + dsb(ishst); + logkfi("%s\n", current_su_path); + return 0; +} + +int su_get_path(char *__user ubuf, int buf_len) +{ + if (!current_su_path) { + logkfi("null su path\n"); + current_su_path = default_su_path; + } + int len = strnlen(current_su_path, SU_PATH_MAX_LEN); + if (len <= 0) return -EINVAL; + if (buf_len < len) return -ENOBUFS; + logkfi("%s\n", current_su_path); + return compat_copy_to_user(ubuf, current_su_path, len + 1); +} + +// todo: rcu_dereference_protected +static uid_t current_uid() +{ + struct cred *cred = *(struct cred **)((uintptr_t)current + task_struct_offset.cred_offset); + uid_t uid = *(uid_t *)((uintptr_t)cred + cred_offset.uid_offset); + return uid; +} + +// #define TRY_DIRECT_MODIFY_USER + +static void handle_before_execve(hook_local_t *hook_local, char **__user u_filename_p, char **__user uargv, void *udata) +{ + // copy to user len + hook_local->data0 = 0; + + char __user *ufilename = *u_filename_p; + char filename[SU_PATH_MAX_LEN]; + int flen = compact_strncpy_from_user(filename, ufilename, sizeof(filename)); + if (flen <= 0) return; + + if (!strcmp(current_su_path, filename)) { + uid_t uid = current_uid(); + struct su_profile *profile = search_allow_uid(uid); + if (!profile) return; + + uid_t to_uid = profile->to_uid; + const char *sctx = profile->scontext; + commit_su(to_uid, sctx); + + struct file *filp = filp_open(apd_path, O_RDONLY, 0); + if (!filp || IS_ERR(filp)) { + int cplen = 0; +#ifdef TRY_DIRECT_MODIFY_USER + cplen = compat_copy_to_user(*u_filename_p, sh_path, sizeof(sh_path)); +#endif + if (cplen > 0) { + hook_local->data0 = cplen; + hook_local->data1 = (uint64_t)u_filename_p; + logkfi("call su uid: %d, to_uid: %d, sctx: %s, cplen: %d\n", uid, to_uid, sctx, cplen); + } else { + void *uptr = copy_to_user_stack(sh_path, sizeof(sh_path)); + if (uptr && !IS_ERR(uptr)) { + *u_filename_p = (char *__user)uptr; + } + } + } else { + filp_close(filp, 0); + + // command + int cplen = 0; +#ifdef TRY_DIRECT_MODIFY_USER + cplen = compat_copy_to_user(*u_filename_p, apd_path, sizeof(apd_path)); +#endif + uint64_t sp = 0; + if (cplen > 0) { + hook_local->data0 = cplen; + hook_local->data1 = (uint64_t)u_filename_p; + } else { + sp = current_user_stack_pointer(); + sp -= sizeof(apd_path); + sp &= 0xFFFFFFFFFFFFFFF8; + cplen = compat_copy_to_user((void *)sp, apd_path, sizeof(apd_path)); + if (cplen > 0) { + *u_filename_p = (char *)sp; + } + } + + // args0 + int argv_cplen = 0; +#ifdef TRY_DIRECT_MODIFY_USER + const char __user *p1 = get_user_arg_ptr(0, *uargv, 0); + argv_cplen = compat_copy_to_user((void *__user)p1, default_su_path, sizeof(default_su_path)); +#endif + if (argv_cplen <= 0) { + sp = sp ? sp - sizeof(default_su_path) : current_user_stack_pointer(); + sp &= 0xFFFFFFFFFFFFFFF8; + logkd("aaaaaaaaaa %llx, %llx\n", *uargv, sp); + int rc = set_user_arg_ptr(0, *uargv, 0, (void *)sp); + logkd("aaaaaaa rc: %d\n", rc); + } + logkfi("call apd uid: %d, to_uid: %d, sctx: %s, cplen: %d, %d\n", uid, to_uid, sctx, cplen, argv_cplen); + } + kvfree(profile); + } else if (!strcmp(SUPERCMD, filename)) { + // key + const char __user *p1 = get_user_arg_ptr(0, *uargv, 1); + if (!p1 || IS_ERR(p1)) return; + + // auth key + char arg1[SUPER_KEY_LEN]; + if (compact_strncpy_from_user(arg1, p1, sizeof(arg1)) <= 0) return; + if (superkey_auth(arg1)) return; + commit_su(0, 0); + + // shift args + *uargv += 2 * 8; + } +} + +static void handle_after_execve(hook_local_t *hook_local) +{ + int cplen = hook_local->data0; + char **__user u_filename_p = (char **__user)hook_local->data1; + if (cplen > 0) { + compat_copy_to_user((void *)*u_filename_p, current_su_path, cplen); + } +} + +// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2087 +// SYSCALL_DEFINE3(execve, const char __user *, filename, const char __user *const __user *, argv, +// const char __user *const __user *, envp) +static void before_execve(hook_fargs3_t *args, void *udata) +{ + void *arg0p = syscall_argn_p(args, 0); + void *arg1p = syscall_argn_p(args, 1); + handle_before_execve(&args->local, (char **)arg0p, (char **)arg1p, udata); +} + +static void after_execve(hook_fargs3_t *args, void *udata) +{ + handle_after_execve(&args->local); +} + +// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2095 +// SYSCALL_DEFINE5(execveat, int, fd, const char __user *, filename, const char __user *const __user *, argv, +// const char __user *const __user *, envp, int, flags) +static void before_execveat(hook_fargs5_t *args, void *udata) +{ + void *arg1p = syscall_argn_p(args, 1); + void *arg2p = syscall_argn_p(args, 2); + handle_before_execve(&args->local, (char **)arg1p, (char **)arg2p, udata); +} + +static void after_execveat(hook_fargs5_t *args, void *udata) +{ + handle_after_execve(&args->local); +} + +// https://elixir.bootlin.com/linux/v6.1/source/fs/stat.c#L431 +// SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, +// struct stat __user *, statbuf, int, flag) + +// https://elixir.bootlin.com/linux/v6.1/source/fs/open.c#L492 +// SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) + +// https://elixir.bootlin.com/linux/v6.1/source/fs/open.c#L497 +// SYSCALL_DEFINE4(faccessat2, int, dfd, const char __user *, filename, int, mode, int, flags) + +// https://elixir.bootlin.com/linux/v6.1/source/fs/stat.c#L661 +// SYSCALL_DEFINE5(statx, +// int, dfd, const char __user *, filename, unsigned, flags, +// unsigned int, mask, +// struct statx __user *, buffer) +static void su_handler_arg1_ufilename_before(hook_fargs6_t *args, void *udata) +{ + // copy to user len + args->local.data0 = 0; + + uid_t uid = current_uid(); + if (!is_allow_uid(uid)) return; + + char __user *ufilename = (char __user *)syscall_argn(args, 1); + char filename[SU_PATH_MAX_LEN]; + int flen = compact_strncpy_from_user(filename, ufilename, sizeof(filename)); + if (flen <= 0) return; + + if (!strcmp(current_su_path, filename)) { + int cplen = 0; +#ifdef TRY_DIRECT_MODIFY_USER + cplen = compat_copy_to_user(ufilename, sh_path, sizeof(sh_path)); +#endif + if (cplen > 0) { + args->local.data0 = cplen; + args->local.data1 = (uint64_t)ufilename; + logkfi("su uid: %d, cp: %d\n", uid, cplen); + } else { + void *uptr = copy_to_user_stack(sh_path, sizeof(sh_path)); + if (uptr && !IS_ERR(uptr)) { + set_syscall_argn(args, 1, (uint64_t)uptr); + } + logkfi("su uid: %d, cp stack: %llx\n", uid, uptr); + } + } +} + +static void su_handler_arg1_ufilename_after(hook_fargs6_t *args, void *udata) +{ + int cplen = args->local.data0; + if (cplen > 0) { + compat_copy_to_user((void *)args->local.data1, current_su_path, cplen); + } +} + +int su_compat_init() +{ + current_su_path = default_su_path; + + INIT_LIST_HEAD(&allow_uid_list); + spin_lock_init(&list_lock); + + // default shell + struct su_profile default_shell_profile = { + .uid = 2000, + .to_uid = 0, + }; + su_add_allow_uid(default_shell_profile.uid, &default_shell_profile, 1); + + hook_err_t err = HOOK_NO_ERR; + + err |= inline_hook_syscalln(__NR_execve, 3, before_execve, after_execve, (void *)__NR_execve); + err |= inline_hook_syscalln(__NR_execveat, 5, before_execveat, after_execveat, (void *)__NR_execveat); + + err |= inline_hook_syscalln(__NR3264_fstatat, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, + (void *)__NR3264_fstatat); + + err |= inline_hook_syscalln(__NR_faccessat, 3, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, + (void *)__NR_faccessat); + err |= inline_hook_syscalln(__NR_faccessat2, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, + (void *)__NR_faccessat2); + + return err; +} \ No newline at end of file diff --git a/kernel/patch/common/supercall.c b/kernel/patch/common/supercall.c index 9f3e155e..1eefb4ce 100644 --- a/kernel/patch/common/supercall.c +++ b/kernel/patch/common/supercall.c @@ -66,7 +66,7 @@ static long call_panic() static long call_klog(const char __user *arg1) { char buf[1024]; - long len = strncpy_from_user_nofault(buf, arg1, sizeof(buf)); + long len = compact_strncpy_from_user(buf, arg1, sizeof(buf)); if (len <= 0) return -EINVAL; if (len > 0) logki("user log: %s", buf); return 0; @@ -75,25 +75,25 @@ static long call_klog(const char __user *arg1) static long call_kpm_load(const char __user *arg1, const char *__user arg2, void *__user reserved) { char path[1024], args[KPM_ARGS_LEN]; - long pathlen = strncpy_from_user_nofault(path, arg1, sizeof(path)); + long pathlen = compact_strncpy_from_user(path, arg1, sizeof(path)); if (pathlen <= 0) return -EINVAL; - long arglen = strncpy_from_user_nofault(args, arg2, sizeof(args)); + long arglen = compact_strncpy_from_user(args, arg2, sizeof(args)); return load_module_path(path, arglen <= 0 ? 0 : args, reserved); } static long call_kpm_control(const char __user *arg1, const char *__user arg2, void *__user out_msg, int outlen) { char name[KPM_NAME_LEN], args[KPM_ARGS_LEN]; - long namelen = strncpy_from_user_nofault(name, arg1, sizeof(name)); + long namelen = compact_strncpy_from_user(name, arg1, sizeof(name)); if (namelen <= 0) return -EINVAL; - long arglen = strncpy_from_user_nofault(args, arg2, sizeof(args)); + long arglen = compact_strncpy_from_user(args, arg2, sizeof(args)); return module_control0(name, arglen <= 0 ? 0 : args, out_msg, outlen); } static long call_kpm_unload(const char *__user arg1, void *__user reserved) { char name[KPM_NAME_LEN]; - long len = strncpy_from_user_nofault(name, arg1, sizeof(name)); + long len = compact_strncpy_from_user(name, arg1, sizeof(name)); if (len <= 0) return -EINVAL; return unload_module(name, reserved); } @@ -109,7 +109,7 @@ static long call_kpm_list(char *__user names, int len) char buf[4096]; int sz = list_modules(buf, sizeof(buf)); if (sz > len) return -ENOBUFS; - sz = seq_copy_to_user(names, buf, len); + sz = compat_copy_to_user(names, buf, len); return sz; } @@ -118,12 +118,12 @@ static long call_kpm_info(const char *__user uname, char *__user out_info, int o if (out_len <= 0) return -EINVAL; char name[64]; char buf[2048]; - int len = strncpy_from_user_nofault(name, uname, sizeof(name)); + int len = compact_strncpy_from_user(name, uname, sizeof(name)); if (len <= 0) return -EINVAL; int sz = get_module_info(name, buf, sizeof(buf)); if (sz < 0) return sz; if (sz > out_len) return -ENOBUFS; - sz = seq_copy_to_user(out_info, buf, sz); + sz = compat_copy_to_user(out_info, buf, sz); return sz; } @@ -135,7 +135,7 @@ static unsigned long call_pid_virt_to_phys(pid_t pid, uintptr_t vaddr) static long call_su(struct su_profile *__user uprofile) { struct su_profile *profile = memdup_user(uprofile, sizeof(struct su_profile)); - if (IS_ERR(profile)) return PTR_ERR(profile); + if (!profile || IS_ERR(profile)) return PTR_ERR(profile); profile->scontext[sizeof(profile->scontext) - 1] = '\0'; int rc = commit_su(profile->to_uid, profile->scontext); kvfree(profile); @@ -145,7 +145,7 @@ static long call_su(struct su_profile *__user uprofile) static long call_su_task(pid_t pid, struct su_profile *__user uprofile) { struct su_profile *profile = memdup_user(uprofile, sizeof(struct su_profile)); - if (IS_ERR(profile)) return PTR_ERR(profile); + if (!profile || IS_ERR(profile)) return PTR_ERR(profile); profile->scontext[sizeof(profile->scontext) - 1] = '\0'; int rc = task_su(pid, profile->to_uid, profile->scontext); kvfree(profile); @@ -215,7 +215,7 @@ static void before(hook_fargs6_t *args, void *udata) if ((hash_key_val & 0xFFFF0000) != hash) return; char key[MAX_KEY_LEN]; - long len = strncpy_from_user_nofault(key, ukey, MAX_KEY_LEN); + long len = compact_strncpy_from_user(key, ukey, MAX_KEY_LEN); if (len <= 0) return; if (superkey_auth(key)) return; @@ -228,8 +228,8 @@ int supercall_install() int rc = 0; hash_key_val = hash_key(get_superkey()); - // hook_err_t err = inline_hook_syscalln(__NR_supercall, 6, before, 0, 0); - hook_err_t err = fp_hook_syscalln(__NR_supercall, 6, before, 0, 0); + hook_err_t err = inline_hook_syscalln(__NR_supercall, 6, before, 0, 0); + // hook_err_t err = fp_hook_syscalln(__NR_supercall, 6, before, 0, 0); if (err) { log_boot("install supercall hook error: %d\n", err); rc = err; diff --git a/kernel/patch/common/syscall.c b/kernel/patch/common/syscall.c index 0650cc34..0d1cd81f 100644 --- a/kernel/patch/common/syscall.c +++ b/kernel/patch/common/syscall.c @@ -17,6 +17,7 @@ #include #include #include +#include uintptr_t *sys_call_table = 0; KP_EXPORT_SYMBOL(sys_call_table); @@ -45,6 +46,7 @@ struct user_arg_ptr_compat } ptr; }; +// actually, a0 is true if it is compact const char __user *get_user_arg_ptr(void *a0, void *a1, int nr) { char __user *const __user *native = (char __user *const __user *)a0; @@ -55,7 +57,7 @@ const char __user *get_user_arg_ptr(void *a0, void *a1, int nr) } native = (char __user *const __user *)((unsigned long)native + nr * size); char __user **upptr = memdup_user(native, size); - if (IS_ERR(upptr)) return ERR_PTR((long)upptr); + if (!upptr || IS_ERR(upptr)) return ERR_PTR((long)upptr); char __user *uptr; if (size == 8) { @@ -67,6 +69,20 @@ const char __user *get_user_arg_ptr(void *a0, void *a1, int nr) return uptr; } +int set_user_arg_ptr(void *a0, void *a1, int nr, void *__user val) +{ + char __user *const __user *native = (char __user *const __user *)a0; + int size = 8; + if (has_config_compat) { + native = (char __user *const __user *)a1; + if (a0) size = 4; // compat + } + native = (char __user *const __user *)((unsigned long)native + nr * size); + + int cplen = compat_copy_to_user((void *)native, val, size); + return cplen == size ? 0 : cplen; +} + typedef long (*warp_raw_syscall_f)(const struct pt_regs *regs); typedef long (*raw_syscall0_f)(); typedef long (*raw_syscall1_f)(long arg0); diff --git a/kernel/patch/common/taskob.c b/kernel/patch/common/taskob.c index 07f790e0..293127e1 100644 --- a/kernel/patch/common/taskob.c +++ b/kernel/patch/common/taskob.c @@ -56,7 +56,7 @@ static struct task_struct *(*backup_copy_process)(void *a0, void *a1, void *a2, struct task_struct *replace_copy_process(void *a0, void *a1, void *a2, void *a3, void *a4, void *a5, void *a6, void *a7) { struct task_struct *new = backup_copy_process(a0, a1, a2, a3, a4, a5, a6, a7); - if (unlikely(IS_ERR(new))) return new; + if (unlikely(!new || IS_ERR(new))) return new; prepare_task_ext(new, current); return new; } diff --git a/kernel/patch/common/utils.c b/kernel/patch/common/utils.c index a2894e1d..340d08c2 100644 --- a/kernel/patch/common/utils.c +++ b/kernel/patch/common/utils.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include int trace_seq_copy_to_user(void __user *to, const void *from, int n) { @@ -40,7 +42,7 @@ int seq_buf_copy_to_user(void __user *to, const void *from, int n) return seq_buf_to_user(&seq_buf, to, n); } -int __must_check seq_copy_to_user(void __user *to, const void *from, int n) +int __must_check compat_copy_to_user(void __user *to, const void *from, int n) { int copy_len; if (kfunc(seq_buf_to_user)) { @@ -50,11 +52,11 @@ int __must_check seq_copy_to_user(void __user *to, const void *from, int n) } return copy_len; } -KP_EXPORT_SYMBOL(seq_copy_to_user); +KP_EXPORT_SYMBOL(compat_copy_to_user); #include -long strncpy_from_user_nofault(char *dest, const char __user *src, long count) +long compact_strncpy_from_user(char *dest, const char __user *src, long count) { if (kfunc(strncpy_from_user)) { long rc = kfunc(strncpy_from_user)(dest, src, count); @@ -66,30 +68,45 @@ long strncpy_from_user_nofault(char *dest, const char __user *src, long count) } return rc; } - kfunc_call(strncpy_from_user_nofault, dest, src, count); + kfunc_call(compact_strncpy_from_user, dest, src, count); kfunc_call(strncpy_from_unsafe_user, dest, src, count); return 0; } -KP_EXPORT_SYMBOL(strncpy_from_user_nofault); +KP_EXPORT_SYMBOL(compact_strncpy_from_user); + +int16_t pt_regs_offset = -1; struct pt_regs *_task_pt_reg(struct task_struct *task) { unsigned long stack = (unsigned long)task_stack_page(task); uintptr_t addr = (uintptr_t)(thread_size + stack); + if (likely(pt_regs_offset > 0)) { + addr -= pt_regs_offset; + } else { #ifndef ANDROID - if (kver < VERSION(4, 4, 19)) { - addr -= sizeof(struct pt_regs_lt4419); - } else + if (kver < VERSION(4, 4, 19)) { + addr -= sizeof(struct pt_regs_lt4419); + } else #endif - if (kver < VERSION(4, 14, 0)) { - addr -= sizeof(struct pt_regs_lt4140); - } else if (kver < VERSION(5, 10, 0)) { - addr -= sizeof(struct pt_regs_lt5100); - } else { - addr -= sizeof(struct pt_regs); + if (kver < VERSION(4, 14, 0)) { + addr -= sizeof(struct pt_regs_lt4140); + } else if (kver < VERSION(5, 10, 0)) { + addr -= sizeof(struct pt_regs_lt5100); + } else { + addr -= sizeof(struct pt_regs); + } } - struct pt_regs *regs; - regs = (struct pt_regs *)(addr); - return regs; + + return (struct pt_regs *)(addr); +} +KP_EXPORT_SYMBOL(_task_pt_reg); + +void *__user __must_check copy_to_user_stack(const void *data, int len) +{ + uintptr_t addr = current_user_stack_pointer(); + addr -= len; + addr &= 0xFFFFFFFFFFFFFFF8; + int cplen = compat_copy_to_user((void *)addr, data, len); + return cplen > 0 ? (void *__user)addr : (void *)(long)cplen; } -KP_EXPORT_SYMBOL(_task_pt_reg); \ No newline at end of file +KP_EXPORT_SYMBOL(copy_to_user_stack); \ No newline at end of file diff --git a/kernel/patch/include/kputils.h b/kernel/patch/include/kputils.h index cc47485e..6aba95bc 100644 --- a/kernel/patch/include/kputils.h +++ b/kernel/patch/include/kputils.h @@ -9,7 +9,9 @@ #include #include -int __must_check seq_copy_to_user(void __user *to, const void *from, int n); +int __must_check compat_copy_to_user(void __user *to, const void *from, int n); + +void *__user copy_to_user_stack(const void *data, int len); void print_bootlog(); diff --git a/kernel/patch/include/syscall.h b/kernel/patch/include/syscall.h index 552e8320..622e9849 100644 --- a/kernel/patch/include/syscall.h +++ b/kernel/patch/include/syscall.h @@ -16,6 +16,7 @@ extern uintptr_t *sys_call_table; extern int has_syscall_wrapper; const char __user *get_user_arg_ptr(void *a0, void *a1, int nr); +int set_user_arg_ptr(void *a0, void *a1, int nr, void *__user val); long raw_syscall0(long nr); long raw_syscall1(long nr, long arg0); @@ -49,9 +50,15 @@ static inline void set_syscall_argn(void *fdata_args, int n, uint64_t val) args[n] = val; } +static inline void *syscall_argn_p(void *fdata_args, int n) +{ + return syscall_args(fdata_args) + n; +} + static inline hook_err_t fp_hook_syscalln(int nr, int narg, void *before, void *after, void *udata) { uintptr_t fp_addr = (uintptr_t)(sys_call_table + nr); + if (has_syscall_wrapper) narg = 1; return fp_hook_wrap(fp_addr, narg, before, after, udata); } @@ -61,9 +68,15 @@ static inline void fp_unhook_syscall(int nr, void *before, void *after) fp_hook_unwrap(fp_addr, before, after); } +/* +xxx.cfi_jt example: +hint #0x22 +b #0xfffffffffeb452f4 +*/ static inline hook_err_t inline_hook_syscalln(int nr, int narg, void *before, void *after, void *udata) { uintptr_t fp = sys_call_table[nr]; + if (has_syscall_wrapper) narg = 1; return hook_wrap((void *)fp, narg, before, after, udata); } diff --git a/kernel/patch/ksyms/libs.c b/kernel/patch/ksyms/libs.c index fbdbe5c7..139ca605 100644 --- a/kernel/patch/ksyms/libs.c +++ b/kernel/patch/ksyms/libs.c @@ -23,8 +23,8 @@ static void _linux_lib_dump_stack_sym_match(const char *name, unsigned long addr #include -long kfunc_def(strncpy_from_user_nofault)(char *dst, const void __user *unsafe_addr, long count) = 0; -KP_EXPORT_SYMBOL(kfunc(strncpy_from_user_nofault)); +long kfunc_def(compact_strncpy_from_user)(char *dst, const void __user *unsafe_addr, long count) = 0; +KP_EXPORT_SYMBOL(kfunc(compact_strncpy_from_user)); long kfunc_def(strncpy_from_unsafe_user)(char *dst, const void __user *unsafe_addr, long count) = 0; KP_EXPORT_SYMBOL(kfunc(strncpy_from_unsafe_user)); long kfunc_def(strncpy_from_user)(char *dest, const char __user *src, long count) = 0; @@ -38,8 +38,8 @@ KP_EXPORT_SYMBOL(kfunc(strnlen_user)); static void _linux_lib_strncpy_from_user_sym_match(const char *name, unsigned long addr) { - kfunc_match(strncpy_from_user_nofault, name, addr); - if (!kfunc(strncpy_from_user_nofault)) { + kfunc_match(compact_strncpy_from_user, name, addr); + if (!kfunc(compact_strncpy_from_user)) { kfunc_match(strncpy_from_unsafe_user, name, addr); } kfunc_match(strncpy_from_user, name, addr); diff --git a/kernel/patch/ksyms/misc.c b/kernel/patch/ksyms/misc.c index 37aec928..d5c0492b 100644 --- a/kernel/patch/ksyms/misc.c +++ b/kernel/patch/ksyms/misc.c @@ -304,10 +304,10 @@ void kfunc_def(kfree)(const void *) = 0; static void _linux_mm_utils_sym_match(const char *name, unsigned long addr) { - kfunc_match(kfree_const, name, addr); - kfunc_match(kstrdup, name, addr); - kfunc_match(kstrdup_const, name, addr); - kfunc_match(kstrndup, name, addr); + // kfunc_match(kfree_const, name, addr); + // kfunc_match(kstrdup, name, addr); + // kfunc_match(kstrdup_const, name, addr); + // kfunc_match(kstrndup, name, addr); // kfunc_match(kmemdup, name, addr); // kfunc_match(kmemdup_nul, name, addr); kfunc_match(memdup_user, name, addr); @@ -324,8 +324,8 @@ static void _linux_mm_utils_sym_match(const char *name, unsigned long addr) // kfunc_match(__page_mapcount, name, addr); // kfunc_match(vm_memory_committed, name, addr); // kfunc_match(get_cmdline, name, addr); - kfunc_match(__kmalloc, name, addr); - kfunc_match(kmalloc, name, addr); + // kfunc_match(__kmalloc, name, addr); + // kfunc_match(kmalloc, name, addr); kfunc_match(kfree, name, addr); } diff --git a/kernel/patch/ksyms/pt_regs.c b/kernel/patch/ksyms/pt_regs.c new file mode 100644 index 00000000..119d754a --- /dev/null +++ b/kernel/patch/ksyms/pt_regs.c @@ -0,0 +1,62 @@ +#include + +#include +#include +#include +#include +#include +#include + +static int first_init_execed = 0; + +// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2087 +// SYSCALL_DEFINE3(execve, const char __user *, filename, const char __user *const __user *, argv, +// const char __user *const __user *, envp) + +// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2095 +// SYSCALL_DEFINE5(execveat, int, fd, const char __user *, filename, const char __user *const __user *, argv, +// const char __user *const __user *, envp, int, flags) +static void before_execve(hook_fargs5_t *args, void *udata) +{ + if (first_init_execed) return; + first_init_execed = 1; + + uint64_t arg0 = syscall_argn(args, 0); + uint64_t arg1 = syscall_argn(args, 1); + uint64_t arg2 = syscall_argn(args, 2); + uint64_t nr = (uint64_t)udata; + + unsigned long stack = (unsigned long)get_stack(current); + uintptr_t addr = (uintptr_t)(thread_size + stack); + + for (uintptr_t i = addr - sizeof(struct pt_regs) - 0x40; i < addr - 31 * 8; i += 8) { + uintptr_t val0 = *(uintptr_t *)i; + uintptr_t val1 = *(uintptr_t *)(i + 0x8); + uintptr_t val2 = *(uintptr_t *)(i + 0x10); + + if ((arg0 == val0) && (val1 == arg1) && (val2 == arg2)) { + struct pt_regs *regs = (struct pt_regs *)i; + if (regs->orig_x0 == arg0 && regs->syscallno == nr && regs->regs[8] == nr) { + pt_regs_offset = addr - i; + log_boot("pt_regs offset of stack top: %llx\n", pt_regs_offset); + break; + } + } + } + if (pt_regs_offset < 0) { + log_boot("can't resolve pt_regs\n"); + } +} + +static void after_execv(hook_fargs5_t *args, void *udata) +{ + inline_unhook_syscall(__NR_execve, before_execve, after_execv); + inline_unhook_syscall(__NR_execveat, before_execve, after_execv); +} + +int resolve_pt_regs() +{ + inline_hook_syscalln(__NR_execve, 3, before_execve, after_execv, (void *)__NR_execve); + inline_hook_syscalln(__NR_execveat, 5, before_execve, after_execv, (void *)__NR_execveat); + return 0; +} \ No newline at end of file diff --git a/kernel/patch/ksyms/suffix_sym.c b/kernel/patch/ksyms/suffix_sym.c deleted file mode 100644 index e69de29b..00000000 diff --git a/kernel/patch/module/module.c b/kernel/patch/module/module.c index 7d30bfbc..15de1ac9 100644 --- a/kernel/patch/module/module.c +++ b/kernel/patch/module/module.c @@ -502,7 +502,7 @@ long load_module_path(const char *path, const char *args, void *__user reserved) logkfd("%s\n", path); struct file *filp = filp_open(path, O_RDONLY, 0); - if (unlikely(IS_ERR(filp))) { + if (unlikely(!filp || IS_ERR(filp))) { logkfe("open module: %s error\n", path); rc = PTR_ERR(filp); goto out; diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index 8aa2889e..aeee5c7f 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -20,6 +20,7 @@ int linux_libs_symbol_init(); int resolve_struct(); int task_observer(); int bypass_kcfi(); +int resolve_pt_regs(); void print_bootlog() { @@ -79,12 +80,15 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) if ((rc = supercall_install())) goto out; log_boot("supercall_install done: %d\n", rc); -#ifdef ANDROID - if ((rc = kpuserd_init())) goto out; - log_boot("kpuserd_init done: %d\n", rc); + if ((rc = resolve_pt_regs())) goto out; if ((rc = su_compat_init())) goto out; log_boot("su_compat_init done: %d\n", rc); + +#ifdef ANDROID + + // if ((rc = kpuserd_init())) goto out; + // log_boot("kpuserd_init done: %d\n", rc); #endif out: diff --git a/kpm-demo/hello/hello.c b/kpm-demo/hello/hello.c index c3a55319..7727d76e 100644 --- a/kpm-demo/hello/hello.c +++ b/kpm-demo/hello/hello.c @@ -45,7 +45,7 @@ static long hello_control0(const char *args, char *__user out_msg, int outlen) pr_info("kpm hello control0, args: %s\n", args); char echo[64] = "echo: "; strncat(echo, args, 48); - seq_copy_to_user(out_msg, echo, sizeof(echo)); + compat_copy_to_user(out_msg, echo, sizeof(echo)); return 0; } diff --git a/kpm-demo/syscallhook/syscallhook.c b/kpm-demo/syscallhook/syscallhook.c index a719e968..d7855343 100644 --- a/kpm-demo/syscallhook/syscallhook.c +++ b/kpm-demo/syscallhook/syscallhook.c @@ -40,7 +40,7 @@ void before_openat_0(hook_fargs4_t *args, void *udata) umode_t mode = (int)syscall_argn(args, 3); char buf[1024]; - strncpy_from_user_nofault(buf, filename, sizeof(buf)); + compact_strncpy_from_user(buf, filename, sizeof(buf)); struct task_struct *task = current; pid_t pid = -1, tgid = -1; diff --git a/tools/symbol.c b/tools/symbol.c index a7e4f421..30851df1 100644 --- a/tools/symbol.c +++ b/tools/symbol.c @@ -6,22 +6,6 @@ #include "symbol.h" #include "common.h" -int32_t get_symbol_offset_zero(kallsym_t *info, char *img, char *symbol) -{ - int32_t offset = get_symbol_offset(info, img, symbol); - return offset > 0 ? offset : 0; -} - -int32_t get_symbol_offset_exit(kallsym_t *info, char *img, char *symbol) -{ - int32_t offset = get_symbol_offset(info, img, symbol); - if (offset >= 0) { - return offset; - } else { - tools_loge_exit("no symbol %s\n", symbol); - } -} - struct on_each_symbol_struct { const char *symbol; @@ -47,6 +31,29 @@ int32_t find_suffixed_symbol(kallsym_t *kallsym, char *img_buf, const char *symb return udata.addr; } +int32_t get_symbol_offset_zero(kallsym_t *info, char *img, char *symbol) +{ + int32_t offset = get_symbol_offset(info, img, symbol); + return offset > 0 ? offset : 0; +} + +int32_t get_symbol_offset_exit(kallsym_t *info, char *img, char *symbol) +{ + int32_t offset = get_symbol_offset(info, img, symbol); + if (offset >= 0) { + return offset; + } else { + tools_loge_exit("no symbol %s\n", symbol); + } +} + +int32_t try_get_symbol_offset_zero(kallsym_t *info, char *img, char *symbol) +{ + int32_t offset = get_symbol_offset(info, img, symbol); + if (offset > 0) return offset; + return find_suffixed_symbol(info, img, symbol); +} + // todo void select_map_area(kallsym_t *kallsym, char *image_buf, int32_t *map_start, int32_t *max_size) { @@ -98,11 +105,8 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym { symbol->panic = get_symbol_offset_zero(kallsym, img_buf, "panic"); - symbol->rest_init = get_symbol_offset_zero(kallsym, img_buf, "rest_init"); - symbol->cgroup_init = get_symbol_offset_zero(kallsym, img_buf, "cgroup_init"); - if (!symbol->rest_init && !symbol->cgroup_init) { - symbol->rest_init = find_suffixed_symbol(kallsym, img_buf, "rest_init"); - } + symbol->rest_init = try_get_symbol_offset_zero(kallsym, img_buf, "rest_init"); + if (!symbol->rest_init) symbol->cgroup_init = try_get_symbol_offset_zero(kallsym, img_buf, "cgroup_init"); if (!symbol->rest_init && !symbol->cgroup_init) tools_loge_exit("no symbol rest_init"); symbol->kernel_init = get_symbol_offset_zero(kallsym, img_buf, "kernel_init"); @@ -111,52 +115,36 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym symbol->__cfi_slowpath_diag = get_symbol_offset_zero(kallsym, img_buf, "__cfi_slowpath_diag"); symbol->__cfi_slowpath = get_symbol_offset_zero(kallsym, img_buf, "__cfi_slowpath"); - symbol->copy_process = get_symbol_offset_zero(kallsym, img_buf, "copy_process"); - symbol->cgroup_post_fork = get_symbol_offset_zero(kallsym, img_buf, "cgroup_post_fork"); - if (!symbol->copy_process && !symbol->cgroup_post_fork) { - symbol->copy_process = find_suffixed_symbol(kallsym, img_buf, "copy_process"); - } + symbol->copy_process = try_get_symbol_offset_zero(kallsym, img_buf, "copy_process"); + if (!symbol->copy_process) symbol->cgroup_post_fork = get_symbol_offset_zero(kallsym, img_buf, "cgroup_post_fork"); if (!symbol->copy_process && !symbol->cgroup_post_fork) tools_loge_exit("no symbol copy_process"); - symbol->__do_execve_file = get_symbol_offset_zero(kallsym, img_buf, "__do_execve_file"); - symbol->do_execveat_common = get_symbol_offset_zero(kallsym, img_buf, "do_execveat_common"); - symbol->do_execve_common = get_symbol_offset_zero(kallsym, img_buf, "do_execve_common"); - if (!symbol->__do_execve_file && !symbol->do_execveat_common && !symbol->do_execve_common) { - symbol->__do_execve_file = find_suffixed_symbol(kallsym, img_buf, "__do_execve_file"); - symbol->do_execveat_common = find_suffixed_symbol(kallsym, img_buf, "do_execveat_common"); - symbol->do_execve_common = find_suffixed_symbol(kallsym, img_buf, "do_execve_common"); - } + symbol->__do_execve_file = try_get_symbol_offset_zero(kallsym, img_buf, "__do_execve_file"); + symbol->do_execveat_common = try_get_symbol_offset_zero(kallsym, img_buf, "do_execveat_common"); + symbol->do_execve_common = try_get_symbol_offset_zero(kallsym, img_buf, "do_execve_common"); if (!symbol->__do_execve_file && !symbol->do_execveat_common && !symbol->do_execve_common) tools_loge_exit("no symbol execve"); - symbol->avc_denied = get_symbol_offset_zero(kallsym, img_buf, "avc_denied"); - if (!symbol->avc_denied) { - // gcc -fipa-sra eg: avc_denied.isra.5 - symbol->avc_denied = find_suffixed_symbol(kallsym, img_buf, "avc_denied"); - } + // gcc -fipa-sra eg: avc_denied.isra.5 + symbol->avc_denied = try_get_symbol_offset_zero(kallsym, img_buf, "avc_denied"); if (!symbol->avc_denied && is_android) tools_loge_exit("no symbol avc_denied"); - symbol->slow_avc_audit = get_symbol_offset_zero(kallsym, img_buf, "slow_avc_audit"); + symbol->slow_avc_audit = try_get_symbol_offset_zero(kallsym, img_buf, "slow_avc_audit"); symbol->input_handle_event = get_symbol_offset_zero(kallsym, img_buf, "input_handle_event"); - symbol->vfs_statx = get_symbol_offset_zero(kallsym, img_buf, "vfs_statx"); - symbol->do_statx = get_symbol_offset_zero(kallsym, img_buf, "do_statx"); - symbol->vfs_fstatat = get_symbol_offset_zero(kallsym, img_buf, "vfs_fstatat"); - if (!symbol->vfs_statx && !symbol->do_statx && !symbol->vfs_fstatat) { - symbol->vfs_statx = find_suffixed_symbol(kallsym, img_buf, "vfs_statx"); - symbol->do_statx = find_suffixed_symbol(kallsym, img_buf, "do_statx"); - symbol->vfs_fstatat = find_suffixed_symbol(kallsym, img_buf, "vfs_fstatat"); - } + symbol->vfs_statx = try_get_symbol_offset_zero(kallsym, img_buf, "vfs_statx"); + symbol->do_statx = try_get_symbol_offset_zero(kallsym, img_buf, "do_statx"); + symbol->vfs_fstatat = try_get_symbol_offset_zero(kallsym, img_buf, "vfs_fstatat"); if (!symbol->vfs_statx && !symbol->do_statx && !symbol->vfs_fstatat) tools_loge_exit("no symbol stat"); - symbol->do_faccessat = get_symbol_offset_zero(kallsym, img_buf, "do_faccessat"); - symbol->sys_faccessat = get_symbol_offset_zero(kallsym, img_buf, "sys_faccessat"); - if (!symbol->do_faccessat && !symbol->sys_faccessat) { - symbol->do_faccessat = find_suffixed_symbol(kallsym, img_buf, "do_faccessat"); - symbol->sys_faccessat = find_suffixed_symbol(kallsym, img_buf, "sys_faccessat"); + symbol->do_faccessat = try_get_symbol_offset_zero(kallsym, img_buf, "do_faccessat"); + if (!symbol->do_faccessat) { + symbol->sys_faccessat = get_symbol_offset_zero(kallsym, img_buf, "sys_faccessat"); + symbol->sys_faccessat2 = get_symbol_offset_zero(kallsym, img_buf, "sys_faccessat2"); } - if (!symbol->do_faccessat && !symbol->sys_faccessat) tools_loge_exit("no symbol accessat"); + // if (!symbol->do_faccessat && (!symbol->sys_faccessat || !symbol->sys_faccessat2)) + // tools_loge_exit("no symbol accessat"); if ((is_be() ^ target_is_be)) { for (int64_t *pos = (int64_t *)symbol; pos <= (int64_t *)symbol; pos++) { diff --git a/user/android/android_user.c b/user/android/android_user.c index c7a24c98..1d829b30 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -34,8 +34,8 @@ static char pkg_cfg_path[] = APATCH_FLODER "package_config"; static char su_path_path[] = APATCH_FLODER "su_path"; static char skip_sepolicy_path[] = APATCH_FLODER "skip_sepolicy"; -static char boot0_log_path[] = APATCH_LOG_FLODER "kpatch_0.log"; -static char boot1_log_path[] = APATCH_LOG_FLODER "kpatch_1.log"; +static char boot0_log_path[] = ADB_FLODER "kpatch_0.log"; +static char boot1_log_path[] = ADB_FLODER "kpatch_1.log"; extern const char *key; static bool from_kernel = false; @@ -63,36 +63,12 @@ static int log_kernel(const char *fmt, ...) return sc_klog(key, buf); } -static void save_dmegs(const char *file) -{ - char *dmesg_argv[] = { - "/system/bin/dmesg", - NULL, - }; - pid_t pid = fork(); - - if (pid < 0) { - log_kernel("%d fork for dmesg error: %d\n", getpid(), pid); - } else if (pid == 0) { - int fd = open(file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); - dup2(fd, 1); - dup2(fd, 2); - close(fd); - int rc = execv(dmesg_argv[0], dmesg_argv); - log_kernel("%d exec dmesg > %s error: %s\n", getpid(), file, strerror(errno)); - } else { - int status; - wait(&status); - log_kernel("%d wait dmesg status: 0x%x\n", getpid(), status); - } -} - static char *csv_val(const char *header, const char *line, const char *key) { const char *kpos = strstr(header, key); - if (!kpos) return NULL; + if (!kpos) return 0; int kidx = 0; - const char *c = NULL; + const char *c = 0; for (c = header; c < kpos; c++) { if (*c == ',') kidx++; } @@ -210,22 +186,21 @@ static void post_fs_data_init() struct su_profile profile = { .uid = getuid() }; sc_su(key, &profile); - log_kernel("%d starting android user post_fs_data_init, from kernel: %d\n", getpid(), from_kernel); + log_kernel("%d starting android user post-fs-data-init\n", getpid()); - if (!access(APATCH_FLODER, F_OK)) mkdir(APATCH_FLODER, 0700); - if (!access(APATCH_LOG_FLODER, F_OK)) mkdir(APATCH_LOG_FLODER, 0700); + if (access(APATCH_FLODER, F_OK)) mkdir(APATCH_FLODER, 0700); + if (access(APATCH_LOG_FLODER, F_OK)) mkdir(APATCH_LOG_FLODER, 0700); - if (from_kernel) save_dmegs(boot0_log_path); + char *dmesg_argv[] = { "/system/bin/dmesg", ">", boot0_log_path, "2>&1", NULL }; + fork_for_result(dmesg_argv[0], dmesg_argv); char current_exe[1024] = { '\0' }; if (readlink("/proc/self/exe", current_exe, sizeof(current_exe) - 1)) { if (!strcmp(current_exe, KPATCH_DEV_PATH)) { - log_kernel("%d copy %s to %s.\n", getpid(), current_exe, KPATCH_DATA_PATH); - char *const cp_argv[] = { "/system/bin/cp", current_exe, KPATCH_DATA_PATH, NULL }; fork_for_result(cp_argv[0], cp_argv); - char *const rm_argv[] = { "/system/bin/rm", current_exe, NULL }; + char *const rm_argv[] = { "/system/bin/unlink", current_exe, NULL }; fork_for_result(rm_argv[0], rm_argv); } } @@ -240,7 +215,8 @@ static void post_fs_data_init() log_kernel("%d finished android user post_fs_data_init.\n", getpid()); - if (from_kernel) save_dmegs(boot1_log_path); + dmesg_argv[2] = boot1_log_path; + fork_for_result(dmesg_argv[0], dmesg_argv); } static struct option const longopts[] = { @@ -290,7 +266,10 @@ int android_user(int argc, char **argv) char log_path[128] = { '\0' }; sprintf(log_path, "%s/kpatch_%s.log", APATCH_LOG_FLODER, scmd); - save_dmegs(log_path); + + char *dmesg_argv[] = { "/system/bin/dmesg", ">", log_path, "2>&1", NULL }; + fork_for_result(dmesg_argv[0], dmesg_argv); + } else { log_kernel("invalid android user cmd: %s\n", scmd); } From 11bc49f9c202dae75eda194fcb375394a0da2164 Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 28 Feb 2024 11:00:01 +0800 Subject: [PATCH 38/51] a --- kernel/patch/android/kpuserd.c | 35 ++++++++++++++-------------------- kernel/patch/common/sucompat.c | 22 ++++++++++++--------- kernel/patch/common/syscall.c | 6 +++--- kernel/patch/common/taskob.c | 34 --------------------------------- kernel/patch/include/syscall.h | 2 +- kernel/patch/patch.c | 5 +++-- 6 files changed, 34 insertions(+), 70 deletions(-) diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index 7e5711bc..8b329c8e 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -128,7 +128,7 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) filename_index = 1; } struct filename *filename = (struct filename *)args->args[filename_index]; - if (!filename || !filename || IS_ERR(filename)) return; + if (!filename || IS_ERR(filename)) return; const char app_process[] = "/system/bin/app_process"; static int first_app_process = 1; @@ -150,15 +150,14 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) for (int i = 1;; i++) { const char *__user p1 = get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); - if (!p1) break; - if (!!p1 || IS_ERR(p1)) { - char arg[16] = { '\0' }; - if (compact_strncpy_from_user(arg, p1, sizeof(arg)) <= 0) break; - if (!strcmp(arg, "second_stage") || !strcmp(arg, "--second-stage")) { - log_boot("exec %s second stage 0\n", filename->name); - before_second_stage(); - init_second_stage_executed = 1; - } + if (!p1 || IS_ERR(p1)) break; + + char arg[16] = { '\0' }; + if (compact_strncpy_from_user(arg, p1, sizeof(arg)) <= 0) break; + if (!strcmp(arg, "second_stage") || !strcmp(arg, "--second-stage")) { + log_boot("exec %s second stage 0\n", filename->name); + before_second_stage(); + init_second_stage_executed = 1; } } } @@ -195,8 +194,6 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) } } -static void after_openat(hook_fargs4_t *args, void *udata); - static void before_openat(hook_fargs4_t *args, void *udata) { // clear local @@ -259,7 +256,6 @@ static void after_openat(hook_fargs4_t *args, void *udata) #define EV_KEY 0x01 #define KEY_VOLUMEDOWN 114 -/* Modified from KernelSU */ // void input_handle_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) static void before_input_handle_event(hook_fargs4_t *args, void *udata) { @@ -272,7 +268,7 @@ static void before_input_handle_event(hook_fargs4_t *args, void *udata) if (volumedown_pressed_count == 3) { log_boot("entering safemode ..."); struct file *filp = filp_open(SAFE_MODE_FLAG_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0666); - if (!!filp || IS_ERR(filp)) filp_close(filp, 0); + if (filp && !IS_ERR(filp)) filp_close(filp, 0); } } } @@ -280,14 +276,11 @@ static void before_input_handle_event(hook_fargs4_t *args, void *udata) int kpuserd_init() { int rc = 0; - hook_err_t err = add_execv_hook(before_do_execve, 0, 0); - if (err) { - log_boot("hook add execv error: %d\n", err); - rc = err; - goto out; - } + hook_err_t err = HOOK_NO_ERR; + err |= inline_hook_syscalln(__NR_execve, 3, before_execve, after_execve, (void *)__NR_execve); + err |= inline_hook_syscalln(__NR_execveat, 5, before_execveat, after_execveat, (void *)__NR_execveat); - fp_hook_syscalln(__NR_openat, 4, before_openat, after_openat, 0); + err |= inline_hook_syscalln(__NR_openat, 4, before_openat, after_openat, 0); unsigned long input_handle_event_addr = get_preset_patch_sym()->input_handle_event; if (!input_handle_event_addr) { diff --git a/kernel/patch/common/sucompat.c b/kernel/patch/common/sucompat.c index 9e90a55d..cd4be6c2 100644 --- a/kernel/patch/common/sucompat.c +++ b/kernel/patch/common/sucompat.c @@ -254,7 +254,7 @@ static uid_t current_uid() return uid; } -// #define TRY_DIRECT_MODIFY_USER +#define TRY_DIRECT_MODIFY_USER static void handle_before_execve(hook_local_t *hook_local, char **__user u_filename_p, char **__user uargv, void *udata) { @@ -284,16 +284,15 @@ static void handle_before_execve(hook_local_t *hook_local, char **__user u_filen if (cplen > 0) { hook_local->data0 = cplen; hook_local->data1 = (uint64_t)u_filename_p; - logkfi("call su uid: %d, to_uid: %d, sctx: %s, cplen: %d\n", uid, to_uid, sctx, cplen); } else { void *uptr = copy_to_user_stack(sh_path, sizeof(sh_path)); if (uptr && !IS_ERR(uptr)) { *u_filename_p = (char *__user)uptr; } } + logkfi("call su uid: %d, to_uid: %d, sctx: %s, cplen: %d\n", uid, to_uid, sctx, cplen); } else { filp_close(filp, 0); - // command int cplen = 0; #ifdef TRY_DIRECT_MODIFY_USER @@ -320,11 +319,15 @@ static void handle_before_execve(hook_local_t *hook_local, char **__user u_filen argv_cplen = compat_copy_to_user((void *__user)p1, default_su_path, sizeof(default_su_path)); #endif if (argv_cplen <= 0) { - sp = sp ? sp - sizeof(default_su_path) : current_user_stack_pointer(); + sp = sp ?: current_user_stack_pointer(); + sp -= sizeof(default_su_path); sp &= 0xFFFFFFFFFFFFFFF8; - logkd("aaaaaaaaaa %llx, %llx\n", *uargv, sp); - int rc = set_user_arg_ptr(0, *uargv, 0, (void *)sp); - logkd("aaaaaaa rc: %d\n", rc); + argv_cplen = compat_copy_to_user((void *)sp, default_su_path, sizeof(default_su_path)); + if (argv_cplen > 0) { + int rc = set_user_arg_ptr(0, *uargv, 0, sp); + if (rc < 0) { // todo: modify entire argv + } + } } logkfi("call apd uid: %d, to_uid: %d, sctx: %s, cplen: %d, %d\n", uid, to_uid, sctx, cplen, argv_cplen); } @@ -338,6 +341,7 @@ static void handle_before_execve(hook_local_t *hook_local, char **__user u_filen char arg1[SUPER_KEY_LEN]; if (compact_strncpy_from_user(arg1, p1, sizeof(arg1)) <= 0) return; if (superkey_auth(arg1)) return; + commit_su(0, 0); // shift args @@ -420,13 +424,13 @@ static void su_handler_arg1_ufilename_before(hook_fargs6_t *args, void *udata) if (cplen > 0) { args->local.data0 = cplen; args->local.data1 = (uint64_t)ufilename; - logkfi("su uid: %d, cp: %d\n", uid, cplen); + // logkfi("su uid: %d, cp: %d\n", uid, cplen); } else { void *uptr = copy_to_user_stack(sh_path, sizeof(sh_path)); if (uptr && !IS_ERR(uptr)) { set_syscall_argn(args, 1, (uint64_t)uptr); } - logkfi("su uid: %d, cp stack: %llx\n", uid, uptr); + // logkfi("su uid: %d, cp stack: %llx\n", uid, uptr); } } } diff --git a/kernel/patch/common/syscall.c b/kernel/patch/common/syscall.c index 0d1cd81f..7388cb9e 100644 --- a/kernel/patch/common/syscall.c +++ b/kernel/patch/common/syscall.c @@ -69,7 +69,7 @@ const char __user *get_user_arg_ptr(void *a0, void *a1, int nr) return uptr; } -int set_user_arg_ptr(void *a0, void *a1, int nr, void *__user val) +int set_user_arg_ptr(void *a0, void *a1, int nr, uintptr_t val) { char __user *const __user *native = (char __user *const __user *)a0; int size = 8; @@ -78,8 +78,8 @@ int set_user_arg_ptr(void *a0, void *a1, int nr, void *__user val) if (a0) size = 4; // compat } native = (char __user *const __user *)((unsigned long)native + nr * size); - - int cplen = compat_copy_to_user((void *)native, val, size); + uintptr_t valarr[1] = { val }; + int cplen = compat_copy_to_user((void *)native, (void *)valarr, size); return cplen == size ? 0 : cplen; } diff --git a/kernel/patch/common/taskob.c b/kernel/patch/common/taskob.c index 293127e1..b41f079d 100644 --- a/kernel/patch/common/taskob.c +++ b/kernel/patch/common/taskob.c @@ -70,22 +70,6 @@ static void replace_cgroup_post_fork(struct task_struct *p, void *a1) prepare_task_ext(new, current); } -unsigned long execv_hook_addr = 0; - -// int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) -// int __do_execve_file(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags, -// struct file *file); -// static int do_execve_common(struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp) -hook_err_t add_execv_hook(hook_chain8_callback before, hook_chain8_callback after, void *udata) -{ - return hook_wrap8((void *)execv_hook_addr, before, after, udata); -} - -void remove_execv_hook(hook_chain8_callback before, hook_chain8_callback after) -{ - hook_unwrap((void *)execv_hook_addr, before, after); -} - int task_observer() { int rc = 0; @@ -118,24 +102,6 @@ int task_observer() } } - // hook execv - execv_hook_addr = get_preset_patch_sym()->__do_execve_file; - if (!execv_hook_addr) execv_hook_addr = get_preset_patch_sym()->do_execveat_common; - if (!execv_hook_addr) execv_hook_addr = get_preset_patch_sym()->do_execve_common; - - if (!execv_hook_addr) { - log_boot("no symbol for execv hook\n"); - rc = -ENOENT; - goto out; - } else { - hook_err_t err = hook_wrap8((void *)execv_hook_addr, 0, 0, 0); - if (err) { - log_boot("hook execv: %llx, error: %d\n", execv_hook_addr, err); - rc = err; - goto out; - } - } - out: return rc; } \ No newline at end of file diff --git a/kernel/patch/include/syscall.h b/kernel/patch/include/syscall.h index 622e9849..c49223e9 100644 --- a/kernel/patch/include/syscall.h +++ b/kernel/patch/include/syscall.h @@ -16,7 +16,7 @@ extern uintptr_t *sys_call_table; extern int has_syscall_wrapper; const char __user *get_user_arg_ptr(void *a0, void *a1, int nr); -int set_user_arg_ptr(void *a0, void *a1, int nr, void *__user val); +int set_user_arg_ptr(void *a0, void *a1, int nr, uintptr_t val); long raw_syscall0(long nr); long raw_syscall1(long nr, long arg0); diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index aeee5c7f..35119a87 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -87,8 +87,9 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) #ifdef ANDROID - // if ((rc = kpuserd_init())) goto out; - // log_boot("kpuserd_init done: %d\n", rc); + if ((rc = kpuserd_init())) goto out; + log_boot("kpuserd_init done: %d\n", rc); + #endif out: From 768889368dcf66026c11854d97f344ff34aa5e17 Mon Sep 17 00:00:00 2001 From: bmax Date: Wed, 28 Feb 2024 22:50:54 +0800 Subject: [PATCH 39/51] a --- kernel/include/preset.h | 26 +- kernel/patch/android/kpuserd.c | 282 ++++++++++++++-------- kernel/patch/common/accctl.c | 1 + kernel/patch/common/extrainit.c | 29 --- kernel/patch/common/sucompat.c | 30 ++- kernel/patch/include/extrainit.h | 11 - kernel/patch/ksyms/{pt_regs.c => execv.c} | 31 ++- kernel/patch/patch.c | 79 +++--- tools/symbol.c | 19 -- user/android/android_user.c | 6 +- 10 files changed, 283 insertions(+), 231 deletions(-) delete mode 100644 kernel/patch/common/extrainit.c delete mode 100644 kernel/patch/include/extrainit.h rename kernel/patch/ksyms/{pt_regs.c => execv.c} (72%) diff --git a/kernel/include/preset.h b/kernel/include/preset.h index 2a8b3c3f..845d6251 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -115,19 +115,9 @@ struct patch_symbol uint64_t __cfi_slowpath; uint64_t copy_process; uint64_t cgroup_post_fork; - uint64_t __do_execve_file; - uint64_t do_execveat_common; - uint64_t do_execve_common; uint64_t avc_denied; uint64_t slow_avc_audit; uint64_t input_handle_event; - uint64_t vfs_statx; - uint64_t vfs_stat; - uint64_t do_statx; - uint64_t vfs_fstatat; - uint64_t do_faccessat; - uint64_t sys_faccessat; - uint64_t sys_faccessat2; }; char _cap[PATCH_SYMBOL_LEN]; }; @@ -160,15 +150,19 @@ typedef int32_t extra_item_type; // todo #define EXTRA_EVENT_PAGING_INIT "paging-init" + #define EXTRA_EVENT_PRE_KERNEL_INIT "pre-kernel-init" #define EXTRA_EVENT_KPM_DEFAULT EXTRA_EVENT_PRE_KERNEL_INIT #define EXTRA_EVENT_POST_KERNEL_INIT "post-kernel-init" -#define EXTRA_EVENT_PRE_INIT "pre-init" -#define EXTRA_EVENT_POST_INIT "post-init" -#define EXTRA_EVENT_PRE_SECOND_STAGE "pre-second-stage" -#define EXTRA_EVENT_POST_SECOND_STAGE "post-second-stage" -#define EXTRA_EVENT_PRE_ZYGOTE_START "pre-zygote-start" -#define EXTRA_EVENT_POST_ZYGOTE_START "post-zygote-start" + +#define EXTRA_EVENT_PRE_FIRST_STAGE "pre-init-first-stage" +#define EXTRA_EVENT_POST_FIRST_STAGE "post-init-first-stage" + +#define EXTRA_EVENT_PRE_EXEC_INIT "pre-exec-init" +#define EXTRA_EVENT_POST_EXEC_INIT "post-exec-init" + +#define EXTRA_EVENT_PRE_SECOND_STAGE "pre-init-second-stage" +#define EXTRA_EVENT_POST_SECOND_STAGE "post-init-second-stage" struct _patch_extra_item { diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/kpuserd.c index 8b329c8e..37236a66 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/kpuserd.c @@ -31,28 +31,11 @@ #include #include -#define ORIGIN_RC_FILE "/system/etc/init/atrace.rc" -#define REPLACE_RC_FILE "/dev/.atrace.rc" - -static const char patch_rc[] = "" - "\n" - "on late-init\n" - " rm " REPLACE_RC_FILE "\n" - "on post-fs-data\n" - " exec -- " SUPERCMD " %s " KPATCH_DEV_PATH " %s android_user post-fs-data-init -k\n" - " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user post-fs-data -k\n" - "on nonencrypted\n" - " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" - "on property:vold.decrypt=trigger_restart_framework\n" - " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" - "on property:sys.boot_completed=1\n" - " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user boot-completed -k\n" - "\n\n" - ""; - static const void *kernel_read_file(const char *path, loff_t *len) { + set_priv_selinx_allow(current, 1); void *data = 0; + struct file *filp = filp_open(path, O_RDONLY, 0); if (!filp || IS_ERR(filp)) { log_boot("open file: %s error: %d\n", path, PTR_ERR(filp)); @@ -64,112 +47,132 @@ static const void *kernel_read_file(const char *path, loff_t *len) loff_t pos = 0; kernel_read(filp, data, *len, &pos); filp_close(filp, 0); + out: + set_priv_selinx_allow(current, 0); return data; } -static void kernel_write_file(const char *path, const void *data, loff_t len, umode_t mode) +static loff_t kernel_write_file(const char *path, const void *data, loff_t len, umode_t mode) { + loff_t off = 0; set_priv_selinx_allow(current, 1); + 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; } - loff_t off = 0; 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_selinx_allow(current, 0); + return off; } -static void kernel_write_exec(const char *path, const void *data, loff_t len) +static loff_t kernel_write_exec(const char *path, const void *data, loff_t len) { - kernel_write_file(path, data, len, 0744); + return kernel_write_file(path, data, len, 0744); } static int extract_kpatch_call_back(const patch_extra_item_t *extra, const char *arg, const void *con, void *udata) { - const char *path = (const char *)udata; + const char *event = (const char *)udata; if (extra->type == EXTRA_TYPE_EXEC && !strcmp("kpatch", extra->name)) { - log_boot("write kpatch to %s\n", path); - kernel_write_exec(path, con, extra->con_size); + loff_t size = kernel_write_exec(KPATCH_DEV_PATH, con, extra->con_size); + log_boot("%s extract kpatch size: %d\n", event, (long)size); } return 0; } -static void before_first_stage() +static void try_extract_kpatch(const char *event) { - const char *path = KPATCH_DEV_PATH; - on_each_extra_item(extract_kpatch_call_back, (void *)path); + set_priv_selinx_allow(current, 1); + struct file *fp = filp_open(KPATCH_DEV_PATH, O_RDONLY, 0); + if (!fp || IS_ERR(fp)) { + on_each_extra_item(extract_kpatch_call_back, (void *)event); + } else { + filp_close(fp, 0); + } + set_priv_selinx_allow(current, 0); } -static void before_second_stage() +static void pre_user_exec_init() { + log_boot("event: %s\n", EXTRA_EVENT_PRE_EXEC_INIT); + try_extract_kpatch(EXTRA_EVENT_PRE_EXEC_INIT); } -static void on_zygote_start() +static void pre_init_second_stage() { + log_boot("event: %s\n", EXTRA_EVENT_PRE_SECOND_STAGE); + try_extract_kpatch(EXTRA_EVENT_PRE_SECOND_STAGE); } -// int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) -// int __do_execve_file(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags, -// struct file *file); -// static int do_execve_common(struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp) -static void before_do_execve(hook_fargs8_t *args, void *udata) +static void on_first_app_process() { - int filename_index = 0; - if ((((uintptr_t)args->arg0) & 0xF000000000000000) != 0xF000000000000000) { - filename_index = 1; - } - struct filename *filename = (struct filename *)args->args[filename_index]; - if (!filename || IS_ERR(filename)) return; +} - const char app_process[] = "/system/bin/app_process"; - static int first_app_process = 1; +#define TRY_DIRECT_MODIFY_USER + +static void handle_before_execve(hook_local_t *hook_local, char **__user u_filename_p, char **__user uargv, + char **__user uenvp, void *udata) +{ + // unhook flag + hook_local->data7 = 0; + + static char app_process[] = "/system/bin/app_process"; + static char app_process64[] = "/system/bin/app_process64"; + static int first_app_process_execed = 0; static const char system_bin_init[] = "/system/bin/init"; static const char root_init[] = "/init"; - static int init_first_stage_executed = 0; + static int first_user_init_executed = 0; static int init_second_stage_executed = 0; - if (!strcmp(system_bin_init, filename->name) || !strcmp(root_init, filename->name)) { + char __user *ufilename = *u_filename_p; + char filename[SU_PATH_MAX_LEN]; + int flen = compact_strncpy_from_user(filename, ufilename, sizeof(filename)); + if (flen <= 0) return; + + if (!strcmp(system_bin_init, filename) || !strcmp(root_init, filename)) { // - if (!init_first_stage_executed) { - init_first_stage_executed = 1; - log_boot("exec %s first stage\n", filename->name); - before_first_stage(); + if (!first_user_init_executed) { + first_user_init_executed = 1; + log_boot("exec first user init: %s\n", filename); + pre_user_exec_init(); } if (!init_second_stage_executed) { for (int i = 1;; i++) { - const char *__user p1 = - get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); + const char __user *p1 = get_user_arg_ptr(0, *uargv, i); if (!p1 || IS_ERR(p1)) break; char arg[16] = { '\0' }; if (compact_strncpy_from_user(arg, p1, sizeof(arg)) <= 0) break; + if (!strcmp(arg, "second_stage") || !strcmp(arg, "--second-stage")) { - log_boot("exec %s second stage 0\n", filename->name); - before_second_stage(); + log_boot("exec %s second stage 0\n", filename); + pre_init_second_stage(); init_second_stage_executed = 1; } } } if (!init_second_stage_executed) { - int envp_index = filename_index + (has_config_compat ? 3 : 2); for (int i = 0;; i++) { - const char *__user up = - get_user_arg_ptr((void *)args->args[envp_index], (void *)args->args[envp_index + 1], i); - if (!up || IS_ERR(up)) break; + const char *__user uenv = get_user_arg_ptr(0, *uenvp, i); + if (!uenv || IS_ERR(uenv)) break; + char env[256]; - if (compact_strncpy_from_user(env, up, sizeof(env)) <= 0) break; + if (compact_strncpy_from_user(env, uenv, sizeof(env)) <= 0) break; char *env_name = env; char *env_value = strchr(env, '='); if (env_value) { @@ -177,8 +180,8 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) env_value++; if (!strcmp(env_name, "INIT_SECOND_STAGE") && (!strcmp(env_value, "1") || !strcmp(env_value, "true"))) { - log_boot("exec %s second stage 1\n", filename->name); - before_second_stage(); + log_boot("exec %s second stage 1\n", filename); + pre_init_second_stage(); init_second_stage_executed = 1; } } @@ -186,18 +189,90 @@ static void before_do_execve(hook_fargs8_t *args, void *udata) } } - if (unlikely(first_app_process && !strcmp(app_process, filename->name))) { - first_app_process = 0; - log_boot("exec app_process, /data prepared, second_stage: %d\n", init_second_stage_executed); - on_zygote_start(); - remove_execv_hook(before_do_execve, 0); + if (!first_app_process_execed && (!strcmp(app_process, filename) || !strcmp(app_process64, filename))) { + first_app_process_execed = 1; + log_boot("exec first app_process: %s\n", filename); + on_first_app_process(); + hook_local->data7 = 1; + return; } } +static void before_execve(hook_fargs3_t *args, void *udata); +static void after_execve(hook_fargs3_t *args, void *udata); +static void before_execveat(hook_fargs5_t *args, void *udata); +static void after_execveat(hook_fargs5_t *args, void *udata); + +static void handle_after_execve(hook_local_t *hook_local) +{ + int unhook = hook_local->data7; + if (unhook) { + inline_unhook_syscall(__NR_execve, before_execve, after_execve); + inline_unhook_syscall(__NR_execveat, before_execveat, after_execveat); + } +} + +// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2087 +// SYSCALL_DEFINE3(execve, const char __user *, filename, const char __user *const __user *, argv, +// const char __user *const __user *, envp) +static void before_execve(hook_fargs3_t *args, void *udata) +{ + void *arg0p = syscall_argn_p(args, 0); + void *arg1p = syscall_argn_p(args, 1); + void *arg2p = syscall_argn_p(args, 2); + handle_before_execve(&args->local, (char **)arg0p, (char **)arg1p, (char **)arg2p, udata); +} + +static void after_execve(hook_fargs3_t *args, void *udata) +{ + handle_after_execve(&args->local); +} + +// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2095 +// SYSCALL_DEFINE5(execveat, int, fd, const char __user *, filename, const char __user *const __user *, argv, +// const char __user *const __user *, envp, int, flags) +static void before_execveat(hook_fargs5_t *args, void *udata) +{ + void *arg1p = syscall_argn_p(args, 1); + void *arg2p = syscall_argn_p(args, 2); + void *arg3p = syscall_argn_p(args, 3); + handle_before_execve(&args->local, (char **)arg1p, (char **)arg2p, (char **)arg3p, udata); +} + +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/.atrace.rc" + +static const char patch_rc[] = "" + "\n" + "on late-init\n" + " rm " REPLACE_RC_FILE "\n" + "on post-fs-data\n" + " exec -- " SUPERCMD " %s " KPATCH_DEV_PATH " %s android_user post-fs-data-init -k\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user post-fs-data -k\n" + "on nonencrypted\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" + "on property:vold.decrypt=trigger_restart_framework\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" + "on property:sys.boot_completed=1\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user boot-completed -k\n" + "\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) { - // clear local + // cp len args->local.data0 = 0; + // cp ptr + args->local.data1 = 0; + // unhook flag + args->local.data2 = 0; static int replaced = 0; if (replaced) return; @@ -209,20 +284,20 @@ static void before_openat(hook_fargs4_t *args, void *udata) replaced = 1; - set_priv_selinx_allow(current, 1); - // create replace file and redirect loff_t ori_len = 0; struct file *newfp = filp_open(REPLACE_RC_FILE, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (!newfp || IS_ERR(newfp)) { log_boot("create replace rc error: %d\n", PTR_ERR(newfp)); goto out; } + const char *ori_rc_data = kernel_read_file(ORIGIN_RC_FILE, &ori_len); if (!ori_rc_data) goto out; + char *replace_rc_data = vmalloc(sizeof(patch_rc) + 10 * SUPER_KEY_LEN); - const char *superkey = get_superkey(); - sprintf(replace_rc_data, patch_rc, superkey, superkey, superkey, superkey, superkey, superkey, superkey, superkey, - superkey, superkey); + const char *sk = get_superkey(); + sprintf(replace_rc_data, patch_rc, sk, sk, sk, sk, sk, sk, sk, sk, sk, sk); + loff_t off = 0; kernel_write(newfp, replace_rc_data, strlen(replace_rc_data), &off); kernel_write(newfp, ori_rc_data, ori_len, &off); @@ -230,26 +305,37 @@ static void before_openat(hook_fargs4_t *args, void *udata) log_boot("write replace rc error: %x\n", off); goto free; } - // yes, filename is not read only - args->local.data0 = compat_copy_to_user((void *)filename, REPLACE_RC_FILE, sizeof(REPLACE_RC_FILE)); - log_boot("redirect rc file: %x\n", args->local.data0); + + 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); + } + free: filp_close(newfp, 0); kvfree(ori_rc_data); kvfree(replace_rc_data); + out: - // read file not require selinux permission, reset not allow now - set_priv_selinx_allow(current, 0); + args->local.data2 = 1; return; } static void after_openat(hook_fargs4_t *args, void *udata) { if (args->local.data0) { - const char __user *filename = (typeof(filename))syscall_argn(args, 1); - int len = compat_copy_to_user((void *)filename, ORIGIN_RC_FILE, sizeof(ORIGIN_RC_FILE)); - log_boot("restore rc file: %x\n", len); - fp_unhook_syscall(__NR_openat, before_openat, after_openat); + compat_copy_to_user((void *)args->local.data1, ORIGIN_RC_FILE, sizeof(ORIGIN_RC_FILE)); + log_boot("restore rc file: %x\n", args->local.data0); + } + if (args->local.data2) { + inline_unhook_syscall(__NR_openat, before_openat, after_openat); } } @@ -275,27 +361,27 @@ static void before_input_handle_event(hook_fargs4_t *args, void *udata) int kpuserd_init() { - int rc = 0; - hook_err_t err = HOOK_NO_ERR; - err |= inline_hook_syscalln(__NR_execve, 3, before_execve, after_execve, (void *)__NR_execve); - err |= inline_hook_syscalln(__NR_execveat, 5, before_execveat, after_execveat, (void *)__NR_execveat); + hook_err_t ret = 0; + hook_err_t rc = HOOK_NO_ERR; + + rc = inline_hook_syscalln(__NR_execve, 3, before_execve, after_execve, (void *)__NR_execve); + log_boot("hook rc: %d\n", rc); + ret |= rc; - err |= inline_hook_syscalln(__NR_openat, 4, before_openat, after_openat, 0); + rc = inline_hook_syscalln(__NR_execveat, 5, before_execveat, after_execveat, (void *)__NR_execveat); + log_boot("hook rc: %d\n", rc); + ret |= rc; + + rc = inline_hook_syscalln(__NR_openat, 4, before_openat, after_openat, 0); + log_boot("hook rc: %d\n", rc); + ret |= rc; unsigned long input_handle_event_addr = get_preset_patch_sym()->input_handle_event; if (!input_handle_event_addr) { - log_boot("no symbol input_handle_event_addr\n"); - rc = -ENOENT; - goto out; - } else { - hook_err_t err = hook_wrap4((void *)input_handle_event_addr, before_input_handle_event, 0, 0); - if (err) { - log_boot("hook do_faccessat error: %d\n", err); - rc = err; - goto out; - } + rc = hook_wrap4((void *)input_handle_event_addr, before_input_handle_event, 0, 0); + ret |= rc; + log_boot("hook rc: %d\n", rc); } -out: - return rc; + return ret; } \ No newline at end of file diff --git a/kernel/patch/common/accctl.c b/kernel/patch/common/accctl.c index dd2acd31..e8b345d2 100644 --- a/kernel/patch/common/accctl.c +++ b/kernel/patch/common/accctl.c @@ -24,6 +24,7 @@ int set_priv_selinx_allow(struct task_struct *task, int val) { struct task_ext *ext = get_task_ext(task); ext->priv_selinux_allow = val; + dsb(ish); return 0; } diff --git a/kernel/patch/common/extrainit.c b/kernel/patch/common/extrainit.c deleted file mode 100644 index 0747a425..00000000 --- a/kernel/patch/common/extrainit.c +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2024 bmax121. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include - -static int extra_load_kpm_callback(const patch_extra_item_t *extra, const char *args, const void *data, void *udata) -{ - const char *event = (const char *)udata; - if (extra->type == EXTRA_TYPE_KPM) { - if (!strcmp(event, extra->event) || (!extra->event[0] && !strcmp(EXTRA_EVENT_KPM_DEFAULT, event))) { - int rc = load_module(data, extra->con_size, args, event, 0); - log_boot("%s loading extra kpm return: %d\n", event, rc); - } - } - return 0; -} - -int extra_load_kpm(const char *event) -{ - on_each_extra_item(extra_load_kpm_callback, (void *)event); - return 0; -} diff --git a/kernel/patch/common/sucompat.c b/kernel/patch/common/sucompat.c index cd4be6c2..61441fec 100644 --- a/kernel/patch/common/sucompat.c +++ b/kernel/patch/common/sucompat.c @@ -67,6 +67,7 @@ static struct su_profile *search_allow_uid(uid_t uid) { if (pos->uid == uid) { // make a deep copy + // todo: use stack struct su_profile *profile = (struct su_profile *)vmalloc(sizeof(struct su_profile)); memcpy(profile, &pos->profile, sizeof(struct su_profile)); rcu_read_unlock(); @@ -344,6 +345,8 @@ static void handle_before_execve(hook_local_t *hook_local, char **__user u_filen commit_su(0, 0); + // command + // shift args *uargv += 2 * 8; } @@ -457,18 +460,25 @@ int su_compat_init() }; su_add_allow_uid(default_shell_profile.uid, &default_shell_profile, 1); - hook_err_t err = HOOK_NO_ERR; + hook_err_t rc = HOOK_NO_ERR; + + rc = inline_hook_syscalln(__NR_execve, 3, before_execve, after_execve, (void *)__NR_execve); + log_boot("hook rc: %d\n", rc); - err |= inline_hook_syscalln(__NR_execve, 3, before_execve, after_execve, (void *)__NR_execve); - err |= inline_hook_syscalln(__NR_execveat, 5, before_execveat, after_execveat, (void *)__NR_execveat); + rc = inline_hook_syscalln(__NR_execveat, 5, before_execveat, after_execveat, (void *)__NR_execveat); + log_boot("hook rc: %d\n", rc); - err |= inline_hook_syscalln(__NR3264_fstatat, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, - (void *)__NR3264_fstatat); + rc = inline_hook_syscalln(__NR3264_fstatat, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, + (void *)__NR3264_fstatat); + log_boot("hook rc: %d\n", rc); - err |= inline_hook_syscalln(__NR_faccessat, 3, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, - (void *)__NR_faccessat); - err |= inline_hook_syscalln(__NR_faccessat2, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, - (void *)__NR_faccessat2); + rc = inline_hook_syscalln(__NR_faccessat, 3, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, + (void *)__NR_faccessat); + log_boot("hook rc: %d\n", rc); - return err; + rc = inline_hook_syscalln(__NR_faccessat2, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, + (void *)__NR_faccessat2); + log_boot("hook rc: %d\n", rc); + + return rc; } \ No newline at end of file diff --git a/kernel/patch/include/extrainit.h b/kernel/patch/include/extrainit.h deleted file mode 100644 index c9f4954e..00000000 --- a/kernel/patch/include/extrainit.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2024 bmax121. All Rights Reserved. - */ - -#ifndef _KP_EXTRAINIT_H_ -#define _KP_EXTRAINIT_H_ - -int extra_load_kpm(); - -#endif \ No newline at end of file diff --git a/kernel/patch/ksyms/pt_regs.c b/kernel/patch/ksyms/execv.c similarity index 72% rename from kernel/patch/ksyms/pt_regs.c rename to kernel/patch/ksyms/execv.c index 119d754a..31d95f5e 100644 --- a/kernel/patch/ksyms/pt_regs.c +++ b/kernel/patch/ksyms/execv.c @@ -6,9 +6,15 @@ #include #include #include +#include static int first_init_execed = 0; +static void before_first_exec() +{ + log_boot("event: %s\n", EXTRA_EVENT_PRE_EXEC_INIT); +} + // https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2087 // SYSCALL_DEFINE3(execve, const char __user *, filename, const char __user *const __user *, argv, // const char __user *const __user *, envp) @@ -16,10 +22,13 @@ static int first_init_execed = 0; // https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2095 // SYSCALL_DEFINE5(execveat, int, fd, const char __user *, filename, const char __user *const __user *, argv, // const char __user *const __user *, envp, int, flags) -static void before_execve(hook_fargs5_t *args, void *udata) +static void before_execve(hook_fargs3_t *args, void *udata) { if (first_init_execed) return; first_init_execed = 1; + before_first_exec(); + + log_boot("kernel stack:\n"); uint64_t arg0 = syscall_argn(args, 0); uint64_t arg1 = syscall_argn(args, 1); @@ -38,14 +47,11 @@ static void before_execve(hook_fargs5_t *args, void *udata) struct pt_regs *regs = (struct pt_regs *)i; if (regs->orig_x0 == arg0 && regs->syscallno == nr && regs->regs[8] == nr) { pt_regs_offset = addr - i; - log_boot("pt_regs offset of stack top: %llx\n", pt_regs_offset); break; } } } - if (pt_regs_offset < 0) { - log_boot("can't resolve pt_regs\n"); - } + log_boot(" pt_regs offset: %x\n", pt_regs_offset); } static void after_execv(hook_fargs5_t *args, void *udata) @@ -56,7 +62,16 @@ static void after_execv(hook_fargs5_t *args, void *udata) int resolve_pt_regs() { - inline_hook_syscalln(__NR_execve, 3, before_execve, after_execv, (void *)__NR_execve); - inline_hook_syscalln(__NR_execveat, 5, before_execve, after_execv, (void *)__NR_execveat); - return 0; + hook_err_t ret = 0; + hook_err_t rc = HOOK_NO_ERR; + + rc = inline_hook_syscalln(__NR_execve, 3, before_execve, after_execv, (void *)__NR_execve); + log_boot("hook rc: %d\n", rc); + ret |= rc; + + rc = inline_hook_syscalln(__NR_execveat, 5, before_execve, after_execv, (void *)__NR_execveat); + log_boot("hook rc: %d\n", rc); + ret |= rc; + + return rc; } \ No newline at end of file diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index 35119a87..2716a196 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include int linux_misc_symbol_init(); int linux_libs_symbol_init(); @@ -68,86 +68,89 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) if ((rc = resolve_struct())) goto out; log_boot("resolve_struct done: %d\n", rc); - if ((rc = task_observer())) goto out; - log_boot("task_observer done: %d\n", rc); - if ((rc = selinux_hook_install())) goto out; log_boot("selinux_hook_install done: %d\n", rc); + if ((rc = task_observer())) goto out; + log_boot("task_observer done: %d\n", rc); + if ((rc = module_init())) goto out; log_boot("module_init done: %d\n", rc); - if ((rc = supercall_install())) goto out; + rc = supercall_install(); log_boot("supercall_install done: %d\n", rc); - if ((rc = resolve_pt_regs())) goto out; + rc = resolve_pt_regs(); + log_boot("resolve_pt_regs done: %d\n", rc); - if ((rc = su_compat_init())) goto out; + rc = su_compat_init(); log_boot("su_compat_init done: %d\n", rc); #ifdef ANDROID - - if ((rc = kpuserd_init())) goto out; + rc = kpuserd_init(); log_boot("kpuserd_init done: %d\n", rc); - #endif out: return; } +static int extra_load_kpm_callback(const patch_extra_item_t *extra, const char *args, const void *data, void *udata) +{ + const char *event = (const char *)udata; + if (extra->type == EXTRA_TYPE_KPM) { + if (!strcmp(event, extra->event) || (!extra->event[0] && !strcmp(EXTRA_EVENT_KPM_DEFAULT, event))) { + int rc = load_module(data, extra->con_size, args, event, 0); + log_boot("%s loading extra kpm return: %d\n", event, rc); + } + } + return 0; +} + +static int extra_load_kpm(const char *event) +{ + on_each_extra_item(extra_load_kpm_callback, (void *)event); + return 0; +} + static void before_kernel_init(hook_fargs4_t *args, void *udata) { - log_boot("before kernel_init ...\n"); - int rc = extra_load_kpm(EXTRA_EVENT_PRE_KERNEL_INIT); - log_boot("extra_load_kpm done: %d\n", rc); + log_boot("event: %s\n", EXTRA_EVENT_PRE_KERNEL_INIT); + extra_load_kpm(EXTRA_EVENT_PRE_KERNEL_INIT); } static void after_kernel_init(hook_fargs4_t *args, void *udata) { - log_boot("after kernel_init ...\n"); - // int rc = extra_load_kpm(EXTRA_EVENT_POST_KERNEL_INIT); - // log_boot("extra_load_kpm done: %d\n", rc); + log_boot("event: %s\n", EXTRA_EVENT_POST_KERNEL_INIT); } int patch() { - int rc = 0; + hook_err_t ret = 0; unsigned long panic_addr = get_preset_patch_sym()->panic; if (panic_addr) { - hook_err_t err = hook_wrap12((void *)panic_addr, before_panic, 0, 0); - if (err) { - log_boot("hook panic: %llx, error: %d\n", panic_addr, rc); - rc = err; - goto out; - } + hook_err_t rc = hook_wrap12((void *)panic_addr, before_panic, 0, 0); + log_boot("hook rc: %d\n", rc); + ret |= rc; } // rest_init or cgroup_init unsigned long init_addr = get_preset_patch_sym()->rest_init; if (!init_addr) init_addr = get_preset_patch_sym()->cgroup_init; - if (init_addr) { - hook_err_t err = hook_wrap4((void *)init_addr, before_rest_init, 0, (void *)init_addr); - if (err) { - log_boot("hook for init: %llx, error: %d\n", init_addr, err); - rc = err; - goto out; - } + hook_err_t rc = hook_wrap4((void *)init_addr, before_rest_init, 0, (void *)init_addr); + log_boot("hook rc: %d\n", rc); + ret |= rc; } // kernel_init unsigned long kernel_init_addr = get_preset_patch_sym()->kernel_init; if (kernel_init_addr) { - hook_err_t err = hook_wrap4((void *)kernel_init_addr, before_kernel_init, after_kernel_init, 0); - if (err) { - log_boot("hook kernel_init: %llx, error: %d\n", kernel_init_addr, err); - rc = err; - goto out; - } + hook_err_t rc = hook_wrap4((void *)kernel_init_addr, before_kernel_init, after_kernel_init, 0); + log_boot("hook rc: %d\n", rc); + ret |= rc; } -out: - return rc; + return ret; } diff --git a/tools/symbol.c b/tools/symbol.c index 30851df1..5ab86fb6 100644 --- a/tools/symbol.c +++ b/tools/symbol.c @@ -119,12 +119,6 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym if (!symbol->copy_process) symbol->cgroup_post_fork = get_symbol_offset_zero(kallsym, img_buf, "cgroup_post_fork"); if (!symbol->copy_process && !symbol->cgroup_post_fork) tools_loge_exit("no symbol copy_process"); - symbol->__do_execve_file = try_get_symbol_offset_zero(kallsym, img_buf, "__do_execve_file"); - symbol->do_execveat_common = try_get_symbol_offset_zero(kallsym, img_buf, "do_execveat_common"); - symbol->do_execve_common = try_get_symbol_offset_zero(kallsym, img_buf, "do_execve_common"); - if (!symbol->__do_execve_file && !symbol->do_execveat_common && !symbol->do_execve_common) - tools_loge_exit("no symbol execve"); - // gcc -fipa-sra eg: avc_denied.isra.5 symbol->avc_denied = try_get_symbol_offset_zero(kallsym, img_buf, "avc_denied"); if (!symbol->avc_denied && is_android) tools_loge_exit("no symbol avc_denied"); @@ -133,19 +127,6 @@ int fillin_patch_symbol(kallsym_t *kallsym, char *img_buf, int imglen, patch_sym symbol->input_handle_event = get_symbol_offset_zero(kallsym, img_buf, "input_handle_event"); - symbol->vfs_statx = try_get_symbol_offset_zero(kallsym, img_buf, "vfs_statx"); - symbol->do_statx = try_get_symbol_offset_zero(kallsym, img_buf, "do_statx"); - symbol->vfs_fstatat = try_get_symbol_offset_zero(kallsym, img_buf, "vfs_fstatat"); - if (!symbol->vfs_statx && !symbol->do_statx && !symbol->vfs_fstatat) tools_loge_exit("no symbol stat"); - - symbol->do_faccessat = try_get_symbol_offset_zero(kallsym, img_buf, "do_faccessat"); - if (!symbol->do_faccessat) { - symbol->sys_faccessat = get_symbol_offset_zero(kallsym, img_buf, "sys_faccessat"); - symbol->sys_faccessat2 = get_symbol_offset_zero(kallsym, img_buf, "sys_faccessat2"); - } - // if (!symbol->do_faccessat && (!symbol->sys_faccessat || !symbol->sys_faccessat2)) - // tools_loge_exit("no symbol accessat"); - if ((is_be() ^ target_is_be)) { for (int64_t *pos = (int64_t *)symbol; pos <= (int64_t *)symbol; pos++) { *pos = i64swp(*pos); diff --git a/user/android/android_user.c b/user/android/android_user.c index 1d829b30..fcc36319 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -200,7 +200,7 @@ static void post_fs_data_init() char *const cp_argv[] = { "/system/bin/cp", current_exe, KPATCH_DATA_PATH, NULL }; fork_for_result(cp_argv[0], cp_argv); - char *const rm_argv[] = { "/system/bin/unlink", current_exe, NULL }; + char *const rm_argv[] = { "/system/bin/rm", current_exe, NULL }; fork_for_result(rm_argv[0], rm_argv); } } @@ -229,7 +229,9 @@ int android_user(int argc, char **argv) if (!sc_ready(key)) return -EFAULT; char *scmd = argv[1]; - if (scmd == NULL) return -1; + if (scmd == NULL) return -EINVAL; + + log_kernel("cmd: %s\n", scmd); int optc; while ((optc = getopt_long(argc, argv, "k", longopts, NULL)) != -1) { From 7b2caadcf817b4268cdd959744d372f5747fbaff Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 29 Feb 2024 13:43:49 +0800 Subject: [PATCH 40/51] a --- .github/workflows/build.yml | 112 ++-- .github/workflows/build_dev.yml | 17 +- kernel/patch/{common => android}/sucompat.c | 22 +- kernel/patch/android/sucompat.c1 | 571 -------------------- tools/patch.c | 4 +- user/android/android_user.c | 2 - version | 2 +- 7 files changed, 89 insertions(+), 641 deletions(-) rename kernel/patch/{common => android}/sucompat.c (95%) delete mode 100644 kernel/patch/android/sucompat.c1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0e9726c8..beaaddfa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,22 +1,8 @@ name: Build CI on: - push: - branches: ["main"] - paths: - - ".github/workflows/build.yml" - - "kernel/**" - - "user/**" - - "tools/**" - - "version" - pull_request: - branches: ["main"] - paths: - - ".github/workflows/build.yml" - - "kernel/**" - - "user/**" - - "tools/**" - - "version" + workflow_call: + workflow_dispatch: jobs: Build-kpimg: @@ -254,53 +240,53 @@ jobs: permissions: contents: write steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Generate version - shell: pwsh - run: | - $MAJOR = (Select-String -Path version -Pattern '#define MAJOR').Line.Split(' ')[2] - $MINOR = (Select-String -Path version -Pattern '#define MINOR').Line.Split(' ')[2] - $PATCH = (Select-String -Path version -Pattern '#define PATCH').Line.Split(' ')[2] - $VERSION = "$MAJOR.$MINOR.$PATCH" - Write-Output "Generated Version: $VERSION" - "VERSION=$VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append - Add-Content -Path $env:GITHUB_OUTPUT -Value "VERSION=$VERSION" - - uses: msys2/setup-msys2@v2 - with: - update: true - msystem: ucrt64 - path-type: inherit - install: >- - msys/make - msys/gcc - - name: Copyfile - shell: pwsh - run: | - cp .\kernel\include\preset.h .\tools\ - cd tools - (Get-Content -Path "Makefile") -replace '\$\(CC\)', " x86_64-pc-msys-gcc.exe" | Set-Content -Path "Makefile" - (Get-Content -Path "Makefile") -replace '\${CC}', "x86_64-pc-msys-gcc.exe" | Set-Content -Path "Makefile" - - name: build - shell: cmd - run: | - cd tools - msys2 -c 'make' - - - name: Copyfile2 - shell: pwsh - run: | - cp .\tools\kptools.exe .\tools\kptools-msys2.exe - 7z a kptools-msys2-win .\tools\kptools-msys2.exe D:\a\_temp\msys64\usr\bin\msys-2.0.dll - - name: Release - uses: ncipollo/release-action@v1.12.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - tag: ${{ env.VERSION }} - artifacts: | - kptools-msys2-win.7z - allowUpdates: true - replacesArtifacts: true + - name: Checkout + uses: actions/checkout@v3 + - name: Generate version + shell: pwsh + run: | + $MAJOR = (Select-String -Path version -Pattern '#define MAJOR').Line.Split(' ')[2] + $MINOR = (Select-String -Path version -Pattern '#define MINOR').Line.Split(' ')[2] + $PATCH = (Select-String -Path version -Pattern '#define PATCH').Line.Split(' ')[2] + $VERSION = "$MAJOR.$MINOR.$PATCH" + Write-Output "Generated Version: $VERSION" + "VERSION=$VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append + Add-Content -Path $env:GITHUB_OUTPUT -Value "VERSION=$VERSION" + - uses: msys2/setup-msys2@v2 + with: + update: true + msystem: ucrt64 + path-type: inherit + install: >- + msys/make + msys/gcc + - name: Copyfile + shell: pwsh + run: | + cp .\kernel\include\preset.h .\tools\ + cd tools + (Get-Content -Path "Makefile") -replace '\$\(CC\)', " x86_64-pc-msys-gcc.exe" | Set-Content -Path "Makefile" + (Get-Content -Path "Makefile") -replace '\${CC}', "x86_64-pc-msys-gcc.exe" | Set-Content -Path "Makefile" + - name: build + shell: cmd + run: | + cd tools + msys2 -c 'make' + + - name: Copyfile2 + shell: pwsh + run: | + cp .\tools\kptools.exe .\tools\kptools-msys2.exe + 7z a kptools-msys2-win .\tools\kptools-msys2.exe D:\a\_temp\msys64\usr\bin\msys-2.0.dll + - name: Release + uses: ncipollo/release-action@v1.12.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + tag: ${{ env.VERSION }} + artifacts: | + kptools-msys2-win.7z + allowUpdates: true + replacesArtifacts: true Build-kptools-windows-llvm: runs-on: ubuntu-latest diff --git a/.github/workflows/build_dev.yml b/.github/workflows/build_dev.yml index 8d217d7d..b6e34d3d 100644 --- a/.github/workflows/build_dev.yml +++ b/.github/workflows/build_dev.yml @@ -1,7 +1,22 @@ name: Build DEV CI on: - workflow_dispatch: + push: + branches: ["dev"] + paths: + - ".github/workflows/build.yml" + - "kernel/**" + - "user/**" + - "tools/**" + - "version" + pull_request: + branches: ["dev"] + paths: + - ".github/workflows/build.yml" + - "kernel/**" + - "user/**" + - "tools/**" + - "version" jobs: Build-kpimg: diff --git a/kernel/patch/common/sucompat.c b/kernel/patch/android/sucompat.c similarity index 95% rename from kernel/patch/common/sucompat.c rename to kernel/patch/android/sucompat.c index 61441fec..48f4363c 100644 --- a/kernel/patch/common/sucompat.c +++ b/kernel/patch/android/sucompat.c @@ -345,7 +345,27 @@ static void handle_before_execve(hook_local_t *hook_local, char **__user u_filen commit_su(0, 0); - // command + // real command +#define EMBEDDED_NAME_MAX (PATH_MAX - sizeof(*filename) - 128) // enough + + const char *exec = sh_path; + int exec_len = sizeof(sh_path); + const char __user *p2 = get_user_arg_ptr(0, *uargv, 2); + + if (p1 && !IS_ERR(p2)) { + char buffer[EMBEDDED_NAME_MAX]; + int len = compact_strncpy_from_user(buffer, p2, EMBEDDED_NAME_MAX); + if (len >= 0) { + exec = buffer; + exec_len = len; + } + } + + int cplen = 0; +#ifdef TRY_DIRECT_MODIFY_USER + cplen = compat_copy_to_user(*u_filename_p, exec, exec_len); +#endif + if (cplen <= 0) *u_filename_p = copy_to_user_stack(exec, exec_len); // shift args *uargv += 2 * 8; diff --git a/kernel/patch/android/sucompat.c1 b/kernel/patch/android/sucompat.c1 deleted file mode 100644 index 619aa60e..00000000 --- a/kernel/patch/android/sucompat.c1 +++ /dev/null @@ -1,571 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2023 bmax121. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const char sh_path[] = ANDROID_SH_PATH; -static const char default_su_path[] = ANDROID_SU_PATH; -static const char *current_su_path = 0; -static const char apd_path[] = APD_PATH; -static const char kpatch_supercmd[] = SUPERCMD; - -struct allow_uid -{ - uid_t uid; - struct su_profile profile; - struct list_head list; - struct rcu_head rcu; -}; - -static struct list_head allow_uid_list; -static spinlock_t list_lock; - -static void allow_reclaim_callback(struct rcu_head *rcu) -{ - struct allow_uid *allow = container_of(rcu, struct allow_uid, rcu); - kvfree(allow); -} - -static struct su_profile *search_allow_uid(uid_t uid) -{ - rcu_read_lock(); - struct allow_uid *pos; - list_for_each_entry_rcu(pos, &allow_uid_list, list) - { - if (pos->uid == uid) { - // make a deep copy - struct su_profile *profile = (struct su_profile *)vmalloc(sizeof(struct su_profile)); - memcpy(profile, &pos->profile, sizeof(struct su_profile)); - rcu_read_unlock(); - return profile; - } - } - rcu_read_unlock(); - return 0; -} - -static int is_allow_uid(uid_t uid) -{ - rcu_read_lock(); - struct allow_uid *pos; - list_for_each_entry_rcu(pos, &allow_uid_list, list) - { - if (pos->uid == uid) { - rcu_read_unlock(); - return 1; - } - } - rcu_read_unlock(); - return 0; -} - -int su_add_allow_uid(uid_t uid, struct su_profile *profile, int async) -{ - rcu_read_lock(); - struct allow_uid *pos, *old = 0; - list_for_each_entry(pos, &allow_uid_list, list) - { - if (pos->uid == uid) { - old = pos; - break; - } - } - struct allow_uid *new = (struct allow_uid *)vmalloc(sizeof(struct allow_uid)); - new->uid = profile->uid; - memcpy(&new->profile, profile, sizeof(struct su_profile)); - new->profile.scontext[sizeof(new->profile.scontext) - 1] = '\0'; - - spin_lock(&list_lock); - if (old) { // update - list_replace_rcu(&old->list, &new->list); - logkfi("update uid: %d, to_uid: %d, sctx: %s\n", uid, new->profile.to_uid, new->profile.scontext); - } else { // add new one - list_add_rcu(&new->list, &allow_uid_list); - logkfi("new uid: %d, to_uid: %d, sctx: %s\n", uid, new->profile.to_uid, new->profile.scontext); - } - spin_unlock(&list_lock); - - rcu_read_unlock(); - if (old) { - if (async) { - call_rcu(&old->rcu, allow_reclaim_callback); - } else { - synchronize_rcu(); - kvfree(old); - } - } - return 0; -} - -int su_remove_allow_uid(uid_t uid, int async) -{ - struct allow_uid *pos; - spin_lock(&list_lock); - list_for_each_entry(pos, &allow_uid_list, list) - { - if (pos->uid == uid) { - list_del_rcu(&pos->list); - spin_unlock(&list_lock); - logkfi("uid: %d, to_uid: %d, sctx: %s\n", pos->uid, pos->profile.to_uid, pos->profile.scontext); - if (async) { - call_rcu(&pos->rcu, allow_reclaim_callback); - } else { - synchronize_rcu(); - kvfree(pos); - } - return 0; - } - } - spin_unlock(&list_lock); - return 0; -} - -int su_allow_uid_nums() -{ - int num = 0; - rcu_read_lock(); - struct allow_uid *pos; - list_for_each_entry(pos, &allow_uid_list, list) - { - num++; - } - rcu_read_unlock(); - logkfd("%d\n", num); - return num; -} - -int su_allow_uids(uid_t *__user uuids, int unum) -{ - int rc = 0; - int num = 0; - rcu_read_lock(); - struct allow_uid *pos; - list_for_each_entry(pos, &allow_uid_list, list) - { - if (num >= unum) { - goto out; - } - uid_t uid = pos->profile.uid; - int cplen = compat_copy_to_user(uuids + num, &uid, sizeof(uid)); - logkfd("uid: %d\n", uid); - if (cplen <= 0) { - logkfd("compat_copy_to_user error: %d", cplen); - rc = cplen; - goto out; - } - num++; - } - rc = num; -out: - rcu_read_unlock(); - return rc; -} - -int su_allow_uid_profile(uid_t uid, struct su_profile *__user uprofile) -{ - int rc = -ENOENT; - rcu_read_lock(); - struct allow_uid *pos; - list_for_each_entry(pos, &allow_uid_list, list) - { - if (pos->profile.uid != uid) continue; - int cplen = compat_copy_to_user(uprofile, &pos->profile, sizeof(struct su_profile)); - logkfd("profile: %d %d %s\n", uid, pos->profile.to_uid, pos->profile.scontext); - if (cplen <= 0) { - logkfd("compat_copy_to_user error: %d", cplen); - rc = cplen; - goto out; - } - rc = 0; - goto out; - } -out: - rcu_read_unlock(); - return rc; -} - -// no free, no lock -int su_reset_path(const char *path) -{ - if (!path) return -EINVAL; - int len = strlen(path); - if (len <= 0) return -EINVAL; - char *new_su_path = vmalloc(len + 1); - if (!new_su_path) return -ENOMEM; - strcpy(new_su_path, path); - new_su_path[len] = '\0'; - current_su_path = new_su_path; - dsb(ishst); - logkfi("%s\n", current_su_path); - return 0; -} - -int su_get_path(char *__user ubuf, int buf_len) -{ - if (!current_su_path) { - logkfi("null su path\n"); - current_su_path = default_su_path; - } - int len = strnlen(current_su_path, SU_PATH_MAX_LEN); - if (len <= 0) return -EINVAL; - if (buf_len < len) return -ENOBUFS; - logkfi("%s\n", current_su_path); - return compat_copy_to_user(ubuf, current_su_path, len + 1); -} - -// todo: rcu_dereference_protected -static uid_t current_uid() -{ - struct cred *cred = *(struct cred **)((uintptr_t)current + task_struct_offset.cred_offset); - uid_t uid = *(uid_t *)((uintptr_t)cred + cred_offset.uid_offset); - return uid; -} - -/* KernelSU idea */ -static void *__user copy_to_user_stack(void *data, size_t len) -{ - uintptr_t addr = current_user_stack_pointer(); - addr -= len; - addr &= 0xFFFFFFFFFFFFFFF0; - compat_copy_to_user((void *)addr, data, len); - return (void *)addr; -} - -static inline char *__user android_sh_user_path() -{ - return (char *__user)copy_to_user_stack((void *)sh_path, sizeof(sh_path)); -} - -static inline char *__user android_su_user_path() -{ - int len = strlen(current_su_path); - return (char *__user)copy_to_user_stack((void *)current_su_path, len); -} - -// int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) -// int __do_execve_file(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags, -// struct file *file); -// static int do_execve_common(struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp) -static void before_do_execve(hook_fargs8_t *args, void *udata) -{ - struct filename *filename; - int filename_index = 0; - if ((((uintptr_t)args->arg0) & 0xFFFF000000000000) != 0xFFFF000000000000) { - // int, AT_FDCWD(ffffff9c) or fd - filename_index = 1; - } - filename = (struct filename *)args->args[filename_index]; - - if (!filename || IS_ERR(filename)) return; - - if (!strcmp(current_su_path, filename->name)) { - uid_t uid = current_uid(); - struct su_profile *profile = search_allow_uid(uid); - if (!profile) return; - - uid_t to_uid = profile->to_uid; - const char *sctx = profile->scontext; - commit_su(to_uid, sctx); - - struct file *filp = filp_open(apd_path, O_RDONLY, 0); - if (!filp || IS_ERR(filp)) { - logkfi("call su uid: %d, to_uid: %d, sctx: %s\n", uid, to_uid, sctx); - strcpy((char *)filename->name, sh_path); - } else { - filp_close(filp, 0); - logkfi("call apd uid: %d, to_uid: %d, sctx: %s\n", uid, to_uid, sctx); - strcpy((char *)filename->name, apd_path); - const char *__user p0 = - get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], 0); - int sz = compat_copy_to_user((char *__user)p0, default_su_path, sizeof(default_su_path)); - if (sz != sizeof(default_su_path)) { - logkfe("compat_copy_to_user error: %d\n", sz); - } - } - kvfree(profile); - } else if (!strcmp(kpatch_supercmd, filename->name)) { - void *ua0 = (void *)args->args[filename_index + 1]; - void *ua1 = (void *)args->args[filename_index + 2]; - // key - const char __user *p1 = get_user_arg_ptr(ua0, ua1, 1); - if (!p1 || IS_ERR(p1)) return; - - // auth skey - char arg1[SUPER_KEY_LEN]; - if (compact_strncpy_from_user(arg1, p1, sizeof(arg1)) <= 0) return; - if (superkey_auth(arg1)) return; - - commit_su(0, 0); - - // real exec - const char __user *p2 = get_user_arg_ptr(ua0, ua1, 2); - - if (!p2 || IS_ERR(p2)) { - strcpy((char *)filename->name, sh_path); - return; - } - -#define EMBEDDED_NAME_MAX (PATH_MAX - sizeof(*filename) - 128) // enough - - int len = compact_strncpy_from_user((char *)filename->name, p2, EMBEDDED_NAME_MAX); - if (unlikely(len < 0)) return; - - // user_arg_ptr - if (has_config_compat) { - if (ua0) { - args->args[filename_index + 2] += 2 * 4; - } else { - args->args[filename_index + 2] += 2 * 8; - } - } else { - args->args[filename_index + 1] += 2 * 8; - } - - // char option[128]; - // for (int i = 3; i < 10; i++) { - // const char *pn = - // get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); - // if (!pn || IS_ERR(pn)) break; - // compact_strncpy_from_user(option, pn, sizeof(option)); - // if (!strcmp("--path", option)) { - // i++; - // pn = - // get_user_arg_ptr((void *)args->args[filename_index + 1], (void *)args->args[filename_index + 2], i); - // if (!pn || IS_ERR(pn)) break; - // compact_strncpy_from_user(option, pn, sizeof(option)); - // strcpy((char *)filename->name, option); - // } - // } - } - - return; -} - -// long do_faccessat(int dfd, const char __user *filename, int mode, int flags) -// SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) -// SYSCALL_DEFINE4(faccessat2, int, dfd, const char __user *, filename, int, mode, int, flags) -static void before_faccessat(hook_fargs4_t *args, void *udata) -{ - uid_t uid = current_uid(); - if (!is_allow_uid(uid)) return; - - const char *local_su_path = current_su_path; - - char __user *filename = (char __user *)args->arg1; - char buf[SU_PATH_MAX_LEN]; - compact_strncpy_from_user(buf, filename, sizeof(buf)); - if (strcmp(buf, local_su_path)) return; - - logkfd("uid: %d\n", uid); - args->ret = 0; - args->skip_origin = 1; -} - -// int vfs_statx(int dfd, struct filename *filename, int flags, struct kstat *stat, u32 request_mask) -// int do_statx(int dfd, struct filename *filename, unsigned int flags, unsigned int mask, struct statx __user *buffer) -// int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, int flags) -// int do_statx(int dfd, struct filename *filename, unsigned int flags, unsigned int mask, struct statx __user *buffer) -// int do_statx(int dfd, const char __user *filename, unsigned flags, unsigned int mask, struct statx __user *buffer) -// int vfs_statx(int dfd, const char __user *filename, int flags, struct kstat *stat, u32 request_mask) -static void before_stat(hook_fargs8_t *args, void *udata) -{ - int change_flag = 0; - args->local.data[0] = change_flag; - - uid_t uid = current_uid(); - if (!is_allow_uid(uid)) return; - - struct filename *filename = 0; - char *__user u_filename = 0; - - const char *local_su_path = current_su_path; - - // assume this is kernel address - if ((((uintptr_t)args->arg1) & 0xFFFF000000000000) == 0xFFFF000000000000) { - filename = (struct filename *)args->arg1; - if (!filename || IS_ERR(filename)) return; - if (strcmp(filename->name, local_su_path)) return; - } else { - u_filename = (char *)args->arg1; - char buf[SU_PATH_MAX_LEN]; - compact_strncpy_from_user(buf, u_filename, sizeof(buf)); - if (strcmp(buf, local_su_path)) return; - } - - if (filename) { - logkfd("0 uid: %d\n", uid); - strcpy((char *)filename->name, sh_path); - } else { - logkfd("1 uid: %d\n", uid); - int sz = compat_copy_to_user(u_filename, sh_path, sizeof(sh_path)); - if (sz == sizeof(sh_path)) { - change_flag = 1; - args->local.data[0] = change_flag; - args->local.data[1] = (uint64_t)local_su_path; - } else { - // logkfe("compat_copy_to_user error: %d\n", sz); - args->arg1 = (uint64_t)android_sh_user_path(); - } - } -} - -static void after_stat(hook_fargs8_t *args, void *udata) -{ - int change_flag = args->local.data[0]; - if (change_flag) { - const char *local_su_path = (const char *)args->local.data[1]; - int sz = compat_copy_to_user((void *)args->arg1, local_su_path, strlen(local_su_path) + 1); - if (sz != strlen(local_su_path) + 1) logkfe("compat_copy_to_user error: %d\n", sz); - } -} - -// // static ssize_t path_getxattr(const char __user *pathname, const char __user *name, void __user *value, size_t size, unsigned int lookup_flags) -// static void before_path_getxattr(hook_fargs5_t *args, void *udata) -// { -// int change_flag = 0; -// args->local.data[0] = change_flag; - -// char buf[sizeof(su_path)]; -// compact_strncpy_from_user(buf, (char *__user)args->arg0, sizeof(buf)); -// if (strcmp(su_path, buf)) return; - -// uid_t uid = current_uid(); -// if (!is_allow_uid(uid)) return; - -// logkfd("uid: %d\n", uid); -// int sz = compat_copy_to_user((char *__user)args->arg0, sh_path, sizeof(sh_path)); -// if (sz != sizeof(sh_path)) logkfe("compat_copy_to_user error: %d\n", sz); - -// change_flag = 1; -// args->local.data[0] = change_flag; -// } - -// static void after_path_getxattr(hook_fargs5_t *args, void *udata) -// { -// int change_flag = args->local.data[0]; -// if (change_flag) { -// int sz = compat_copy_to_user((void *)args->arg0, su_path, sizeof(su_path)); -// if (sz != sizeof(su_path)) logkfe("compat_copy_to_user error: %d\n", sz); -// } -// } - -int su_compat_init() -{ - int rc = 0; - - current_su_path = default_su_path; - - INIT_LIST_HEAD(&allow_uid_list); - spin_lock_init(&list_lock); - - // default shell - struct su_profile default_shell_profile = { - .uid = 2000, - .to_uid = 0, - }; - su_add_allow_uid(default_shell_profile.uid, &default_shell_profile, 1); - - hook_err_t err = HOOK_NO_ERR; - - // stat - unsigned long vfs_stat_addr = get_preset_patch_sym()->vfs_statx; - if (!vfs_stat_addr) vfs_stat_addr = get_preset_patch_sym()->do_statx; - if (!vfs_stat_addr) vfs_stat_addr = get_preset_patch_sym()->vfs_fstatat; - if (!vfs_stat_addr) { - log_boot("no symbol vfs_fstatat, do_statx or vfs_statx\n"); - rc = -ENOENT; - goto out; - } else { - err |= hook_wrap8((void *)vfs_stat_addr, before_stat, after_stat, 0); - if (err) { - log_boot("hook vfs_fstatat error: %d\n", err); - rc = err; - goto out; - } - } - - unsigned long xxx = kallsyms_lookup_name("vfs_stat"); - logkd("aaaaaaaaaaaaaaa %llx\n", xxx); - err |= hook_wrap8((void *)xxx, before_stat, after_stat, 0); - - // access - unsigned long do_accessat_addr = get_preset_patch_sym()->do_faccessat; - if (do_accessat_addr) { - err |= hook_wrap4((void *)do_accessat_addr, before_faccessat, 0, 0); - if (err) { - log_boot("hook do_faccessat error: %d\n", err); - rc = err; - goto out; - } - } else { - unsigned long faccessat_addr = get_preset_patch_sym()->sys_faccessat; - unsigned long faccessat2_addr = get_preset_patch_sym()->sys_faccessat; - err |= hook_wrap4((void *)faccessat_addr, before_faccessat, 0, 0); - err |= hook_wrap4((void *)faccessat2_addr, before_faccessat, 0, 0); - if (err) { - log_boot("hook do_faccessat error: %d\n", err); - rc = err; - goto out; - } - } - - // execv - err |= add_execv_hook(before_do_execve, 0, 0); - if (err) { - log_boot("hook add execv error: %d\n", err); - rc = err; - goto out; - } - - // xattr - // unsigned long path_getxattr_addr = kallsyms_lookup_name("path_getxattr"); - // if (!path_getxattr_addr) { - // log_boot("no symbol do_faccessat or sys_faccessat\n"); - // rc = -ENOENT; - // goto out; - // } else { - // hook_err_t err = hook_wrap5((void *)path_getxattr_addr, before_path_getxattr, after_path_getxattr, 0); - // if (err) { - // log_boot("hook do_faccessat error: %d\n", err); - // rc = err; - // goto out; - // } - // } - -out: - return rc; -} \ No newline at end of file diff --git a/tools/patch.c b/tools/patch.c index c4aaa11e..59325589 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -83,8 +83,8 @@ void print_preset_info(preset_t *preset) setup_preset_t *setup = &preset->setup; version_t ver = header->kp_version; uint32_t ver_num = (ver.major << 16) + (ver.minor << 8) + ver.patch; - bool is_android = header->config_flags | CONFIG_ANDROID; - bool is_debug = header->config_flags | CONFIG_DEBUG; + bool is_android = (header->config_flags | CONFIG_ANDROID) == CONFIG_ANDROID; + bool is_debug = (header->config_flags & CONFIG_DEBUG) == CONFIG_DEBUG; fprintf(stdout, INFO_KP_IMG_SESSION "\n"); fprintf(stdout, "version=0x%x\n", ver_num); diff --git a/user/android/android_user.c b/user/android/android_user.c index fcc36319..bf01dadc 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -231,8 +231,6 @@ int android_user(int argc, char **argv) char *scmd = argv[1]; if (scmd == NULL) return -EINVAL; - log_kernel("cmd: %s\n", scmd); - int optc; while ((optc = getopt_long(argc, argv, "k", longopts, NULL)) != -1) { switch (optc) { diff --git a/version b/version index d68ebbb8..8ffe67de 100644 --- a/version +++ b/version @@ -1,3 +1,3 @@ #define MAJOR 0 #define MINOR 10 -#define PATCH 0 +#define PATCH 1 From e706c2be0017157007a1b87b08b58f3d58b98fb3 Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 29 Feb 2024 13:46:10 +0800 Subject: [PATCH 41/51] a --- .github/workflows/build_dev.yml | 2 ++ kernel/patch/patch.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_dev.yml b/.github/workflows/build_dev.yml index b6e34d3d..d2a93bee 100644 --- a/.github/workflows/build_dev.yml +++ b/.github/workflows/build_dev.yml @@ -17,6 +17,8 @@ on: - "user/**" - "tools/**" - "version" + workflow_call: + workflow_dispatch: jobs: Build-kpimg: diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index 2716a196..7a315b7e 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -83,10 +83,10 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) rc = resolve_pt_regs(); log_boot("resolve_pt_regs done: %d\n", rc); +#ifdef ANDROID rc = su_compat_init(); log_boot("su_compat_init done: %d\n", rc); -#ifdef ANDROID rc = kpuserd_init(); log_boot("kpuserd_init done: %d\n", rc); #endif From 7f23aab709bd2963b1348d72ab4130d743887913 Mon Sep 17 00:00:00 2001 From: bmax Date: Thu, 29 Feb 2024 16:49:41 +0800 Subject: [PATCH 42/51] a --- user/android/android_user.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/user/android/android_user.c b/user/android/android_user.c index bf01dadc..3dc0162f 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -169,9 +169,9 @@ static void fork_for_result(const char *exec, char *const *argv) setenv("SUPERKEY", key, 1); char kpver[16] = { '\0' }, kver[16] = { '\0' }; sprintf(kpver, "%x", sc_kp_ver(key)); - setenv("KERNEL_PATCH_VER", kpver, 1); + setenv("KERNELPATCH_VERSION", kpver, 1); sprintf(kver, "%x", sc_k_ver(key)); - setenv("KERNEL_VER", kver, 1); + setenv("KERNEL_VERSION", kver, 1); int rc = execv(exec, argv); log_kernel("%d exec %s error: %s\n", getpid(), cmd, strerror(errno)); } else { @@ -194,15 +194,13 @@ static void post_fs_data_init() char *dmesg_argv[] = { "/system/bin/dmesg", ">", boot0_log_path, "2>&1", NULL }; fork_for_result(dmesg_argv[0], dmesg_argv); - char current_exe[1024] = { '\0' }; - if (readlink("/proc/self/exe", current_exe, sizeof(current_exe) - 1)) { - if (!strcmp(current_exe, KPATCH_DEV_PATH)) { - char *const cp_argv[] = { "/system/bin/cp", current_exe, KPATCH_DATA_PATH, NULL }; - fork_for_result(cp_argv[0], cp_argv); + char current_exe[512] = { '\0' }; + if (from_kernel && readlink("/proc/self/exe", current_exe, sizeof(current_exe) - 1)) { + char *const cp_argv[] = { "/system/bin/cp", current_exe, KPATCH_DATA_PATH, NULL }; + fork_for_result(cp_argv[0], cp_argv); - char *const rm_argv[] = { "/system/bin/rm", current_exe, NULL }; - fork_for_result(rm_argv[0], rm_argv); - } + char *const rm_argv[] = { "/system/bin/rm", current_exe, NULL }; + fork_for_result(rm_argv[0], rm_argv); } if (!access(skip_sepolicy_path, F_OK)) { @@ -213,7 +211,7 @@ static void post_fs_data_init() load_config_su_path(); load_config_allow_uids(); - log_kernel("%d finished android user post_fs_data_init.\n", getpid()); + log_kernel("%d finished android user post-fs-data-init.\n", getpid()); dmesg_argv[2] = boot1_log_path; fork_for_result(dmesg_argv[0], dmesg_argv); @@ -245,7 +243,6 @@ int android_user(int argc, char **argv) if (!strcmp("post-fs-data-init", scmd)) { post_fs_data_init(); } else if (!strcmp("post-fs-data", scmd) || !strcmp("services", scmd) || !strcmp("boot-completed", scmd)) { - // todo: move to apd struct su_profile profile = { .uid = getuid(), .to_uid = 0, From c84c89530ce6476d6d6bcdf81a0b9616661160ba Mon Sep 17 00:00:00 2001 From: bmax Date: Fri, 1 Mar 2024 14:27:25 +0800 Subject: [PATCH 43/51] a --- kernel/include/preset.h | 9 +- kpm-demo/{shmem => stat-sel-fs}/.gitignore | 0 kpm-demo/{shmem => stat-sel-fs}/Makefile | 0 kpm-demo/{shmem => stat-sel-fs}/link.lds | 0 kpm-demo/{shmem => stat-sel-fs}/main.c | 9 +- preset.h | 239 +++++++++++++++++++++ tools/patch.c | 22 +- tools/patch.h | 2 +- 8 files changed, 262 insertions(+), 19 deletions(-) rename kpm-demo/{shmem => stat-sel-fs}/.gitignore (100%) rename kpm-demo/{shmem => stat-sel-fs}/Makefile (100%) rename kpm-demo/{shmem => stat-sel-fs}/link.lds (100%) rename kpm-demo/{shmem => stat-sel-fs}/main.c (70%) create mode 100644 preset.h diff --git a/kernel/include/preset.h b/kernel/include/preset.h index 845d6251..c1864e83 100644 --- a/kernel/include/preset.h +++ b/kernel/include/preset.h @@ -132,6 +132,8 @@ _Static_assert(sizeof(patch_symbol_t) == PATCH_SYMBOL_LEN, "sizeof patch_symbol_ #define EXTRA_NAME_LEN 0x20 #define EXTRA_EVENT_LEN 0x20 +#define EXTRA_HDR_MAGIC "kpe" + typedef int32_t extra_item_type; #define EXTRA_TYPE_NONE 0 @@ -170,12 +172,13 @@ struct _patch_extra_item { struct { - extra_item_type type; - char name[EXTRA_NAME_LEN]; - char event[EXTRA_EVENT_LEN]; + char magic[4]; int32_t priority; int32_t args_size; int32_t con_size; + extra_item_type type; + char name[EXTRA_NAME_LEN]; + char event[EXTRA_EVENT_LEN]; }; char _cap[PATCH_EXTRA_ITEM_LEN]; }; diff --git a/kpm-demo/shmem/.gitignore b/kpm-demo/stat-sel-fs/.gitignore similarity index 100% rename from kpm-demo/shmem/.gitignore rename to kpm-demo/stat-sel-fs/.gitignore diff --git a/kpm-demo/shmem/Makefile b/kpm-demo/stat-sel-fs/Makefile similarity index 100% rename from kpm-demo/shmem/Makefile rename to kpm-demo/stat-sel-fs/Makefile diff --git a/kpm-demo/shmem/link.lds b/kpm-demo/stat-sel-fs/link.lds similarity index 100% rename from kpm-demo/shmem/link.lds rename to kpm-demo/stat-sel-fs/link.lds diff --git a/kpm-demo/shmem/main.c b/kpm-demo/stat-sel-fs/main.c similarity index 70% rename from kpm-demo/shmem/main.c rename to kpm-demo/stat-sel-fs/main.c index 98a9f14f..fe447a7d 100644 --- a/kpm-demo/shmem/main.c +++ b/kpm-demo/stat-sel-fs/main.c @@ -10,16 +10,11 @@ #include #include -KPM_NAME("kpm-shmem"); +KPM_NAME("stat-sel-fs"); KPM_VERSION("1.0.0"); KPM_LICENSE("GPL v2"); KPM_AUTHOR("bmax121"); -KPM_DESCRIPTION("Share memory between processes"); - -/* - * This module's main functionality is to map any address of any process to any other process. - * Of course, this means you can easily manipulate data of other processes. -*/ +KPM_DESCRIPTION("Modify the attribute of selinux-fs"); static long init(const char *args, const char *event, void *__user reserved) { diff --git a/preset.h b/preset.h new file mode 100644 index 00000000..845d6251 --- /dev/null +++ b/preset.h @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2023 bmax121. All Rights Reserved. + */ + +#ifndef _KP_PRESET_H_ +#define _KP_PRESET_H_ + +#ifndef __ASSEMBLY__ +#include +#endif + +#define KP_MAGIC "KP1158" +#define MAGIC_LEN 0x8 +#define KP_HEADER_SIZE 0x40 +#define SUPER_KEY_LEN 0x40 +#define HDR_BACKUP_SIZE 0x8 +#define COMPILE_TIME_LEN 0x18 +#define MAP_MAX_SIZE 0xa00 +#define HOOK_ALLOC_SIZE (1 << 20) +#define MEMORY_ROX_SIZE (2 << 20) +#define MEMORY_RW_SIZE (2 << 20) +#define MAP_ALIGN 0x10 + +#define CONFIG_DEBUG 0x1 +#define CONFIG_ANDROID 0x2 + +#define MAP_SYMBOL_NUM (5) +#define MAP_SYMBOL_SIZE (MAP_SYMBOL_NUM * 8) + +#define PATCH_SYMBOL_LEN (512) + +#define ADDITIONAL_LEN (512) + +#define PATCH_EXTRA_ITEM_LEN (128) + +#define VERSION(major, minor, patch) (((major) << 16) + ((minor) << 8) + (patch)) + +#ifndef __ASSEMBLY__ +typedef struct version_t +{ + uint8_t _; + uint8_t patch; + uint8_t minor; + uint8_t major; +} version_t; +#endif + +#ifndef __ASSEMBLY__ + +typedef uint64_t config_t; + +typedef struct _setup_header_t // 64-bytes +{ + union + { + struct + { + char magic[MAGIC_LEN]; // + version_t kp_version; + uint32_t _; + config_t config_flags; + char compile_time[COMPILE_TIME_LEN]; + }; + char _cap[64]; + }; +} setup_header_t; + +_Static_assert(sizeof(setup_header_t) == KP_HEADER_SIZE, "sizeof setup_header_t mismatch"); + +#else +#define header_magic_offset 0 +#define header_kp_version_offset (MAGIC_LEN) +#define header_config_flags (header_kp_version_offset + 4 + 4) +#define header_compile_time_offset (header_config_flags + 8) +#endif + +#ifndef __ASSEMBLY__ +struct map_symbol +{ + union + { + struct + { + uint64_t memblock_reserve_relo; + uint64_t memblock_free_relo; + uint64_t memblock_phys_alloc_relo; + uint64_t memblock_virt_alloc_relo; + uint64_t memblock_mark_nomap_relo; + }; + char _cap[MAP_SYMBOL_SIZE]; + }; +}; +typedef struct map_symbol map_symbol_t; +_Static_assert(sizeof(map_symbol_t) == MAP_SYMBOL_SIZE, "sizeof map_symbol_t mismatch"); +#endif + +#ifndef __ASSEMBLY__ +struct patch_symbol +{ + union + { + struct + { + uint64_t kallsyms_lookup_name; + uint64_t printk; + uint64_t vm_area_add_early; + + uint64_t panic; + uint64_t rest_init; + uint64_t cgroup_init; + uint64_t kernel_init; + uint64_t report_cfi_failure; + uint64_t __cfi_slowpath_diag; + uint64_t __cfi_slowpath; + uint64_t copy_process; + uint64_t cgroup_post_fork; + uint64_t avc_denied; + uint64_t slow_avc_audit; + uint64_t input_handle_event; + }; + char _cap[PATCH_SYMBOL_LEN]; + }; +}; +typedef struct patch_symbol patch_symbol_t; +_Static_assert(sizeof(patch_symbol_t) == PATCH_SYMBOL_LEN, "sizeof patch_symbol_t mismatch"); +#endif + +#ifndef __ASSEMBLY__ + +#define EXTRA_ALIGN 0x10 +#define EXTRA_NAME_LEN 0x20 +#define EXTRA_EVENT_LEN 0x20 + +typedef int32_t extra_item_type; + +#define EXTRA_TYPE_NONE 0 +#define EXTRA_TYPE_KPM 1 +#define EXTRA_TYPE_SHELL 2 +#define EXTRA_TYPE_EXEC 3 +#define EXTRA_TYPE_RAW 4 +#define EXTRA_TYPE_ANDROID_RC 5 + +#define EXTRA_TYPE_NONE_STR "none" +#define EXTRA_TYPE_KPM_STR "kpm" +#define EXTRA_TYPE_SHELL_STR "shell" +#define EXTRA_TYPE_EXEC_STR "exec" +#define EXTRA_TYPE_RAW_STR "raw" +#define EXTRA_TYPE_ANDROID_RC_STR "android_rc" + +// todo +#define EXTRA_EVENT_PAGING_INIT "paging-init" + +#define EXTRA_EVENT_PRE_KERNEL_INIT "pre-kernel-init" +#define EXTRA_EVENT_KPM_DEFAULT EXTRA_EVENT_PRE_KERNEL_INIT +#define EXTRA_EVENT_POST_KERNEL_INIT "post-kernel-init" + +#define EXTRA_EVENT_PRE_FIRST_STAGE "pre-init-first-stage" +#define EXTRA_EVENT_POST_FIRST_STAGE "post-init-first-stage" + +#define EXTRA_EVENT_PRE_EXEC_INIT "pre-exec-init" +#define EXTRA_EVENT_POST_EXEC_INIT "post-exec-init" + +#define EXTRA_EVENT_PRE_SECOND_STAGE "pre-init-second-stage" +#define EXTRA_EVENT_POST_SECOND_STAGE "post-init-second-stage" + +struct _patch_extra_item +{ + union + { + struct + { + extra_item_type type; + char name[EXTRA_NAME_LEN]; + char event[EXTRA_EVENT_LEN]; + int32_t priority; + int32_t args_size; + int32_t con_size; + }; + char _cap[PATCH_EXTRA_ITEM_LEN]; + }; +}; +typedef struct _patch_extra_item patch_extra_item_t; +_Static_assert(sizeof(patch_extra_item_t) == PATCH_EXTRA_ITEM_LEN, "sizeof patch_extra_item_t mismatch"); +#endif + +#ifndef __ASSEMBLY__ +typedef struct _setup_preset_t +{ + version_t kernel_version; + int32_t _; + int64_t kimg_size; // must aligned + int64_t kpimg_size; // must aligned + int64_t kernel_size; // must aligned + int64_t page_shift; + int64_t setup_offset; // must aligned + int64_t start_offset; // must aligned + int64_t extra_size; // must aligned + int64_t map_offset; // must aligned MAP_ALIGN + int64_t map_max_size; + int64_t kallsyms_lookup_name_offset; + int64_t paging_init_offset; + int64_t printk_offset; + map_symbol_t map_symbol; + uint8_t header_backup[HDR_BACKUP_SIZE]; + uint8_t superkey[SUPER_KEY_LEN]; + patch_symbol_t patch_symbol; + char additional[ADDITIONAL_LEN]; +} setup_preset_t; +#else +#define setup_kernel_version_offset 0 +#define setup_kimg_size_offset (setup_kernel_version_offset + 8) +#define setup_kpimg_size_offset (setup_kimg_size_offset + 8) +#define setup_kernel_size_offset (setup_kpimg_size_offset + 8) +#define setup_page_shift_offset (setup_kernel_size_offset + 8) +#define setup_setup_offset_offset (setup_page_shift_offset + 8) +#define setup_start_offset_offset (setup_setup_offset_offset + 8) +#define setup_extra_size_offset (setup_start_offset_offset + 8) +#define setup_map_offset_offset (setup_extra_size_offset + 8) +#define setup_map_max_size_offset (setup_map_offset_offset + 8) +#define setup_kallsyms_lookup_name_offset_offset (setup_map_max_size_offset + 8) +#define setup_paging_init_offset_offset (setup_kallsyms_lookup_name_offset_offset + 8) +#define setup_printk_offset_offset (setup_paging_init_offset_offset + 8) +#define setup_map_symbol_offset (setup_printk_offset_offset + 8) +#define setup_header_backup_offset (setup_map_symbol_offset + MAP_SYMBOL_SIZE) +#define setup_superkey_offset (setup_header_backup_offset + HDR_BACKUP_SIZE) +#define setup_patch_symbol_offset (setup_superkey_offset + SUPER_KEY_LEN) +#define setup_end (setup_patch_symbol_offset + PATCH_SYMBOL_LEN) +#endif + +#ifndef __ASSEMBLY__ +typedef struct +{ + setup_header_t header; + setup_preset_t setup; +} preset_t; +#endif + +#endif // _KP_PRESET_H_ \ No newline at end of file diff --git a/tools/patch.c b/tools/patch.c index 59325589..0565f52c 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -161,17 +161,20 @@ int parse_image_patch_info(const char *kimg, int kimg_len, patched_kimg_t *pimg) // extra int extra_offset = align_kimg_len + old_preset->setup.kpimg_size; - int extra_size = old_preset->setup.extra_size; + if (extra_offset > kimg_len) tools_loge_exit("kpimg length mismatch\n"); + if (extra_offset == kimg_len) return 0; - const char *item_addr = kimg + extra_offset; + int extra_size = old_preset->setup.extra_size; + const char *item_pos = kimg + extra_offset; - while (item_addr < item_addr + extra_size) { - patch_extra_item_t *item = (patch_extra_item_t *)item_addr; + while (item_pos < kimg + extra_offset + extra_size) { + patch_extra_item_t *item = (patch_extra_item_t *)item_pos; + if (strcmp(EXTRA_HDR_MAGIC, item->magic)) break; if (item->type == EXTRA_TYPE_NONE) break; pimg->embed_item[pimg->embed_item_num++] = item; - item_addr += sizeof(patch_extra_item_t); - item_addr += item->args_size; - item_addr += item->con_size; + item_pos += sizeof(patch_extra_item_t); + item_pos += item->args_size; + item_pos += item->con_size; } return 0; @@ -200,11 +203,13 @@ int print_image_patch_info(patched_kimg_t *pimg) if (pimg->banner[strlen(pimg->banner) - 1] != '\n') fprintf(stdout, "\n"); fprintf(stdout, "patched=%s\n", preset ? "true" : "false"); - fprintf(stdout, "extra_num=%d\n", pimg->embed_item_num); if (preset) { print_preset_info(preset); + fprintf(stdout, INFO_EXTRA_SESSION "\n"); + fprintf(stdout, "num=%d\n", pimg->embed_item_num); + for (int i = 0; i < pimg->embed_item_num; i++) { patch_extra_item_t *item = pimg->embed_item[i]; const char *type = extra_type_str(item->type); @@ -356,6 +361,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * } } if (!item) tools_loge_exit("empty extra item\n"); + strcpy(item->magic, EXTRA_HDR_MAGIC); config->item = item; item->type = config->extra_type; if (config->set_args) item->args_size = align_ceil(strlen(config->set_args), EXTRA_ALIGN); diff --git a/tools/patch.h b/tools/patch.h index fa25d758..d0a0a009 100644 --- a/tools/patch.h +++ b/tools/patch.h @@ -16,7 +16,7 @@ #define INFO_KERNEL_IMG_SESSION "[kernel]" #define INFO_KP_IMG_SESSION "[kpimg]" #define INFO_ADDITIONAL_SESSION "[additional]" -#define INFO_EXTRA_SESSION "[extra]" +#define INFO_EXTRA_SESSION "[extras]" #define INFO_EXTRA_SESSION_N "[extra %d]" #define EXTRA_ITEM_MAX_NUM 32 From 35d5d910b968a2ba7068fbe632b0593f74fe07d4 Mon Sep 17 00:00:00 2001 From: bmax Date: Fri, 1 Mar 2024 17:19:23 +0800 Subject: [PATCH 44/51] a --- kernel/base/predata.c | 3 +++ kernel/patch/patch.c | 1 + tools/patch.c | 16 ++++++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/kernel/base/predata.c b/kernel/base/predata.c index 797a2caf..9037206c 100644 --- a/kernel/base/predata.c +++ b/kernel/base/predata.c @@ -39,6 +39,9 @@ int on_each_extra_item(int (*callback)(const patch_extra_item_t *extra, const ch while (item_addr < _kp_extra_end) { patch_extra_item_t *item = (patch_extra_item_t *)item_addr; if (item->type == EXTRA_TYPE_NONE) break; + for (int i = 0; i < sizeof(item->magic); i++) { + if (item->magic[i] != EXTRA_HDR_MAGIC[i]) break; + } const char *args = item->args_size > 0 ? (const char *)(item_addr + sizeof(patch_extra_item_t)) : 0; const void *con = (void *)(item_addr + sizeof(patch_extra_item_t) + item->args_size); rc = callback(item, args, con, udata); diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index 7a315b7e..e2baa81e 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -98,6 +98,7 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) static int extra_load_kpm_callback(const patch_extra_item_t *extra, const char *args, const void *data, void *udata) { const char *event = (const char *)udata; + if (extra->type == EXTRA_TYPE_KPM) { if (!strcmp(event, extra->event) || (!extra->event[0] && !strcmp(EXTRA_EVENT_KPM_DEFAULT, event))) { int rc = load_module(data, extra->con_size, args, event, 0); diff --git a/tools/patch.c b/tools/patch.c index 0565f52c..4f97f673 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -380,15 +380,21 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * extra_size += sizeof(patch_extra_item_t); extra_size += config->item->args_size; extra_size += config->item->con_size; - tools_logi("extra item num: %d, size: 0x%x\n", extra_num, extra_size); } // copy to out image int ori_kimg_len = pimg.ori_kimg_len; int align_kimg_len = align_ceil(ori_kimg_len, SZ_4K); int out_img_len = align_kimg_len + kpimg_len; - tools_logi("layout kimg: 0x0-0x%x, kpimg: 0x%x-0x%x, extra: 0x%x-0x%x\n", ori_kimg_len, align_kimg_len, kpimg_len, - align_kimg_len + kpimg_len, extra_size); + int out_all_len = out_img_len + extra_size; + + int start_offset = align_kernel_size; + if (out_all_len > start_offset) { + start_offset = align_ceil(out_all_len, SZ_4K); + tools_logi("patch overlap, move start from 0x%x to 0x%x\n", align_kernel_size, start_offset); + } + tools_logi("layout kimg: 0x0-0x%x, kpimg: 0x%x,0x%x, extra: 0x%x,0x%x, end: 0x%x, start: 0x%x\n", ori_kimg_len, + align_kimg_len, kpimg_len, out_img_len, extra_size, out_all_len, start_offset); char *out_img = (char *)malloc(out_img_len); memcpy(out_img, pimg.kimg, ori_kimg_len); @@ -419,7 +425,7 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * setup->kernel_size = kinfo->kernel_size; setup->page_shift = kinfo->page_shift; setup->setup_offset = align_kimg_len; - setup->start_offset = align_kernel_size; + setup->start_offset = start_offset; setup->extra_size = extra_size; int map_start, map_max_size; @@ -439,6 +445,8 @@ int patch_update_img(const char *kimg_path, const char *kpimg_path, const char * setup->kernel_size = i64swp(setup->kernel_size); setup->page_shift = i64swp(setup->page_shift); setup->setup_offset = i64swp(setup->setup_offset); + setup->start_offset = i64swp(setup->start_offset); + setup->extra_size = i64swp(setup->extra_size); setup->map_offset = i64swp(setup->map_offset); setup->map_max_size = i64swp(setup->map_max_size); setup->kallsyms_lookup_name_offset = i64swp(setup->kallsyms_lookup_name_offset); From 3879d1447a806764036e56206989ce41be4df74c Mon Sep 17 00:00:00 2001 From: bmax Date: Fri, 1 Mar 2024 20:05:04 +0800 Subject: [PATCH 45/51] a --- kernel/patch/patch.c | 13 +++---------- user/android/android_user.c | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index e2baa81e..46c99854 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -95,12 +95,11 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) return; } -static int extra_load_kpm_callback(const patch_extra_item_t *extra, const char *args, const void *data, void *udata) +static int pre_ki_kpm(const patch_extra_item_t *extra, const char *args, const void *data, void *udata) { const char *event = (const char *)udata; - if (extra->type == EXTRA_TYPE_KPM) { - if (!strcmp(event, extra->event) || (!extra->event[0] && !strcmp(EXTRA_EVENT_KPM_DEFAULT, event))) { + if (!strcmp(EXTRA_EVENT_PRE_KERNEL_INIT, extra->event) || !extra->event[0]) { int rc = load_module(data, extra->con_size, args, event, 0); log_boot("%s loading extra kpm return: %d\n", event, rc); } @@ -108,16 +107,10 @@ static int extra_load_kpm_callback(const patch_extra_item_t *extra, const char * return 0; } -static int extra_load_kpm(const char *event) -{ - on_each_extra_item(extra_load_kpm_callback, (void *)event); - return 0; -} - static void before_kernel_init(hook_fargs4_t *args, void *udata) { log_boot("event: %s\n", EXTRA_EVENT_PRE_KERNEL_INIT); - extra_load_kpm(EXTRA_EVENT_PRE_KERNEL_INIT); + on_each_extra_item(pre_ki_kpm, 0); } static void after_kernel_init(hook_fargs4_t *args, void *udata) diff --git a/user/android/android_user.c b/user/android/android_user.c index 3dc0162f..764a8622 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -181,19 +181,43 @@ static void fork_for_result(const char *exec, char *const *argv) } } +// static void save_dmegs(const char *file) +// { +// char *dmesg_argv[] = { +// "/system/bin/dmesg", +// NULL, +// }; +// pid_t pid = fork(); + +// if (pid < 0) { +// log_kernel("%d fork for dmesg error: %d\n", getpid(), pid); +// } else if (pid == 0) { +// int fd = open(file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); +// dup2(fd, 1); +// dup2(fd, 2); +// close(fd); +// int rc = execv(dmesg_argv[0], dmesg_argv); +// log_kernel("%d exec dmesg > %s error: %s\n", getpid(), file, strerror(errno)); +// } else { +// int status; +// wait(&status); +// log_kernel("%d wait dmesg status: 0x%x\n", getpid(), status); +// } +// } + static void post_fs_data_init() { struct su_profile profile = { .uid = getuid() }; sc_su(key, &profile); + char *dmesg_argv[] = { "/system/bin/dmesg", ">", boot0_log_path, NULL }; + fork_for_result(dmesg_argv[0], dmesg_argv); + log_kernel("%d starting android user post-fs-data-init\n", getpid()); if (access(APATCH_FLODER, F_OK)) mkdir(APATCH_FLODER, 0700); if (access(APATCH_LOG_FLODER, F_OK)) mkdir(APATCH_LOG_FLODER, 0700); - char *dmesg_argv[] = { "/system/bin/dmesg", ">", boot0_log_path, "2>&1", NULL }; - fork_for_result(dmesg_argv[0], dmesg_argv); - char current_exe[512] = { '\0' }; if (from_kernel && readlink("/proc/self/exe", current_exe, sizeof(current_exe) - 1)) { char *const cp_argv[] = { "/system/bin/cp", current_exe, KPATCH_DATA_PATH, NULL }; @@ -213,8 +237,8 @@ static void post_fs_data_init() log_kernel("%d finished android user post-fs-data-init.\n", getpid()); - dmesg_argv[2] = boot1_log_path; - fork_for_result(dmesg_argv[0], dmesg_argv); + char *dmesg_argv_1[] = { "/system/bin/dmesg", ">", boot1_log_path, NULL }; + fork_for_result(dmesg_argv_1[0], dmesg_argv_1); } static struct option const longopts[] = { @@ -264,7 +288,7 @@ int android_user(int argc, char **argv) char log_path[128] = { '\0' }; sprintf(log_path, "%s/kpatch_%s.log", APATCH_LOG_FLODER, scmd); - char *dmesg_argv[] = { "/system/bin/dmesg", ">", log_path, "2>&1", NULL }; + char *dmesg_argv[] = { "/system/bin/dmesg", ">", log_path, NULL }; fork_for_result(dmesg_argv[0], dmesg_argv); } else { From 03f0413901430f5e7995e65ea2131603c5a94edd Mon Sep 17 00:00:00 2001 From: bmax Date: Sun, 3 Mar 2024 09:24:42 +0800 Subject: [PATCH 46/51] a --- kernel/patch/android/sucompat.c | 24 ++--- kernel/patch/android/{kpuserd.c => userd.c} | 65 +++++++----- kernel/patch/include/uapi/scdefs.h | 2 + tools/image.c | 2 +- user/android/android_user.c | 103 ++++++++++++-------- 5 files changed, 120 insertions(+), 76 deletions(-) rename kernel/patch/android/{kpuserd.c => userd.c} (88%) diff --git a/kernel/patch/android/sucompat.c b/kernel/patch/android/sucompat.c index 48f4363c..27f4f2bd 100644 --- a/kernel/patch/android/sucompat.c +++ b/kernel/patch/android/sucompat.c @@ -59,23 +59,21 @@ static void allow_reclaim_callback(struct rcu_head *rcu) kvfree(allow); } -static struct su_profile *search_allow_uid(uid_t uid) +static struct su_profile search_allow_uid(uid_t uid) { rcu_read_lock(); struct allow_uid *pos; + struct su_profile profile = { 0 }; list_for_each_entry_rcu(pos, &allow_uid_list, list) { if (pos->uid == uid) { - // make a deep copy - // todo: use stack - struct su_profile *profile = (struct su_profile *)vmalloc(sizeof(struct su_profile)); - memcpy(profile, &pos->profile, sizeof(struct su_profile)); + memcpy(&profile, &pos->profile, sizeof(struct su_profile)); rcu_read_unlock(); return profile; } } rcu_read_unlock(); - return 0; + return profile; } static int is_allow_uid(uid_t uid) @@ -269,11 +267,11 @@ static void handle_before_execve(hook_local_t *hook_local, char **__user u_filen if (!strcmp(current_su_path, filename)) { uid_t uid = current_uid(); - struct su_profile *profile = search_allow_uid(uid); - if (!profile) return; + if (!is_allow_uid(uid)) return; + struct su_profile profile = search_allow_uid(uid); - uid_t to_uid = profile->to_uid; - const char *sctx = profile->scontext; + uid_t to_uid = profile.to_uid; + const char *sctx = profile.scontext; commit_su(to_uid, sctx); struct file *filp = filp_open(apd_path, O_RDONLY, 0); @@ -285,13 +283,14 @@ static void handle_before_execve(hook_local_t *hook_local, char **__user u_filen if (cplen > 0) { hook_local->data0 = cplen; hook_local->data1 = (uint64_t)u_filename_p; + logkfi("call su uid: %d, to_uid: %d, sctx: %s, cplen: %d\n", uid, to_uid, sctx, cplen); } else { void *uptr = copy_to_user_stack(sh_path, sizeof(sh_path)); if (uptr && !IS_ERR(uptr)) { *u_filename_p = (char *__user)uptr; } + logkfi("call su uid: %d, to_uid: %d, sctx: %s, uptr: %llx\n", uid, to_uid, sctx, uptr); } - logkfi("call su uid: %d, to_uid: %d, sctx: %s, cplen: %d\n", uid, to_uid, sctx, cplen); } else { filp_close(filp, 0); // command @@ -327,12 +326,13 @@ static void handle_before_execve(hook_local_t *hook_local, char **__user u_filen if (argv_cplen > 0) { int rc = set_user_arg_ptr(0, *uargv, 0, sp); if (rc < 0) { // todo: modify entire argv + logkfi("call apd argv error, uid: %d, to_uid: %d, sctx: %s, rc: %d\n", uid, to_uid, sctx, rc); } } } logkfi("call apd uid: %d, to_uid: %d, sctx: %s, cplen: %d, %d\n", uid, to_uid, sctx, cplen, argv_cplen); } - kvfree(profile); + } else if (!strcmp(SUPERCMD, filename)) { // key const char __user *p1 = get_user_arg_ptr(0, *uargv, 1); diff --git a/kernel/patch/android/kpuserd.c b/kernel/patch/android/userd.c similarity index 88% rename from kernel/patch/android/kpuserd.c rename to kernel/patch/android/userd.c index 37236a66..01565a36 100644 --- a/kernel/patch/android/kpuserd.c +++ b/kernel/patch/android/userd.c @@ -244,24 +244,36 @@ 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/.atrace.rc" - -static const char patch_rc[] = "" - "\n" - "on late-init\n" - " rm " REPLACE_RC_FILE "\n" - "on post-fs-data\n" - " exec -- " SUPERCMD " %s " KPATCH_DEV_PATH " %s android_user post-fs-data-init -k\n" - " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user post-fs-data -k\n" - "on nonencrypted\n" - " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" - "on property:vold.decrypt=trigger_restart_framework\n" - " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" - "on property:sys.boot_completed=1\n" - " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user boot-completed -k\n" - "\n\n" - ""; +#define ORIGIN_RC_FILE "/init.environ.rc" +#define REPLACE_RC_FILE "/dev/anduser.rc" + +static const char user_rc_data[] = { // + "\n" + "\n" + "on early-init\n" + " exec -- " SUPERCMD " %s " KPATCH_DEV_PATH " %s android_user early-init -k\n" + + "on post-fs-data\n" + " exec -- " SUPERCMD " %s " KPATCH_DEV_PATH " %s android_user post-fs-data-init -k\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user post-fs-data-init -k\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user post-fs-data -k\n" + + "on nonencrypted\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" + + "on property:vold.decrypt=trigger_restart_framework\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user services -k\n" + + "on property:sys.boot_completed=1\n" + " rm " REPLACE_RC_FILE "\n" + " rm " KPATCH_DEV_PATH "\n" + " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user boot-completed -k\n" + "\n\n" + "" +}; + +// todo: struct file *do_filp_open(int dfd, struct filename *pathname, const struct open_flags *op) +// todo: import rc // 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) @@ -291,17 +303,21 @@ static void before_openat(hook_fargs4_t *args, void *udata) goto out; } + loff_t off = 0; const char *ori_rc_data = kernel_read_file(ORIGIN_RC_FILE, &ori_len); if (!ori_rc_data) goto out; + kernel_write(newfp, ori_rc_data, ori_len, &off); + if (off != ori_len) { + log_boot("write replace rc error: %x\n", off); + goto free; + } - char *replace_rc_data = vmalloc(sizeof(patch_rc) + 10 * SUPER_KEY_LEN); + char added_rc_data[2048]; const char *sk = get_superkey(); - sprintf(replace_rc_data, patch_rc, sk, sk, sk, sk, sk, sk, sk, sk, sk, sk); + sprintf(added_rc_data, user_rc_data, sk, sk, sk, sk, sk, sk, sk, sk, sk, sk, sk, sk, sk, sk); - loff_t off = 0; - kernel_write(newfp, replace_rc_data, strlen(replace_rc_data), &off); - kernel_write(newfp, ori_rc_data, ori_len, &off); - if (off != strlen(replace_rc_data) + ori_len) { + kernel_write(newfp, added_rc_data, strlen(added_rc_data), &off); + if (off != strlen(added_rc_data) + ori_len) { log_boot("write replace rc error: %x\n", off); goto free; } @@ -321,7 +337,6 @@ static void before_openat(hook_fargs4_t *args, void *udata) free: filp_close(newfp, 0); kvfree(ori_rc_data); - kvfree(replace_rc_data); out: args->local.data2 = 1; diff --git a/kernel/patch/include/uapi/scdefs.h b/kernel/patch/include/uapi/scdefs.h index 576ab4ea..e0879e63 100644 --- a/kernel/patch/include/uapi/scdefs.h +++ b/kernel/patch/include/uapi/scdefs.h @@ -74,6 +74,8 @@ struct su_profile #define APATCH_BIN_FLODER "/data/adb/ap/bin/" #define APATCH_LOG_FLODER "/data/adb/ap/log/" #define SAFE_MODE_FLAG_FILE "/dev/.sefemode" +#define EARLY_INIT_LOG_0 "/dev/early_init_0.log" +#define EARLY_INIT_LOG_1 "/dev/early_init_1.log" #define ALL_ALLOW_SCONTEXT "u:r:magisk:s0" diff --git a/tools/image.c b/tools/image.c index 20daecf0..6428377f 100644 --- a/tools/image.c +++ b/tools/image.c @@ -60,7 +60,7 @@ int32_t get_kernel_info(kernel_info_t *kinfo, const char *img, int32_t imglen) if (!strncmp("UNCOMPRESSED_IMG", img, strlen("UNCOMPRESSED_IMG"))) { kinfo->img_offset = 0x14; - tools_loge_exit("kernel image with UNCOMPRESSED_IMG header\n"); + tools_logw("kernel image with UNCOMPRESSED_IMG header\n"); } kinfo->is_be = 0; diff --git a/user/android/android_user.c b/user/android/android_user.c index 764a8622..2c9040d2 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -34,8 +34,8 @@ static char pkg_cfg_path[] = APATCH_FLODER "package_config"; static char su_path_path[] = APATCH_FLODER "su_path"; static char skip_sepolicy_path[] = APATCH_FLODER "skip_sepolicy"; -static char boot0_log_path[] = ADB_FLODER "kpatch_0.log"; -static char boot1_log_path[] = ADB_FLODER "kpatch_1.log"; +static char post_fs_data_log_0[] = APATCH_LOG_FLODER "post_fs_data_0.log"; +static char post_fs_data_log_1[] = APATCH_LOG_FLODER "post_fs_data_1.log"; extern const char *key; static bool from_kernel = false; @@ -181,51 +181,77 @@ static void fork_for_result(const char *exec, char *const *argv) } } -// static void save_dmegs(const char *file) -// { -// char *dmesg_argv[] = { -// "/system/bin/dmesg", -// NULL, -// }; -// pid_t pid = fork(); - -// if (pid < 0) { -// log_kernel("%d fork for dmesg error: %d\n", getpid(), pid); -// } else if (pid == 0) { -// int fd = open(file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); -// dup2(fd, 1); -// dup2(fd, 2); -// close(fd); -// int rc = execv(dmesg_argv[0], dmesg_argv); -// log_kernel("%d exec dmesg > %s error: %s\n", getpid(), file, strerror(errno)); -// } else { -// int status; -// wait(&status); -// log_kernel("%d wait dmesg status: 0x%x\n", getpid(), status); -// } -// } +static void save_dmegs(const char *file) +{ + char *dmesg_argv[] = { + "/system/bin/dmesg", + NULL, + }; + pid_t pid = fork(); + + if (pid < 0) { + log_kernel("%d fork for dmesg error: %d\n", getpid(), pid); + } else if (pid == 0) { + int fd = open(file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + int rc = execv(dmesg_argv[0], dmesg_argv); + log_kernel("%d exec dmesg > %s error: %s\n", getpid(), file, strerror(errno)); + } else { + int status; + wait(&status); + log_kernel("%d wait dmesg status: 0x%x\n", getpid(), status); + } +} + +static void early_init() +{ + struct su_profile profile = { .uid = getuid() }; + sc_su(key, &profile); + + log_kernel("%d starting android user early-init\n", getpid()); + + save_dmegs(EARLY_INIT_LOG_0); + + // todo: + + save_dmegs(EARLY_INIT_LOG_1); +} static void post_fs_data_init() { struct su_profile profile = { .uid = getuid() }; sc_su(key, &profile); - char *dmesg_argv[] = { "/system/bin/dmesg", ">", boot0_log_path, NULL }; + char current_exe[256] = { '\0' }; + readlink("/proc/self/exe", current_exe, sizeof(current_exe) - 1); + + log_kernel("%d starting android user post-fs-data-init, exec: %s\n", getpid(), current_exe); + + char *dmesg_argv[] = { "/system/bin/dmesg", ">", post_fs_data_log_0, NULL }; fork_for_result(dmesg_argv[0], dmesg_argv); - log_kernel("%d starting android user post-fs-data-init\n", getpid()); + if (!strcmp(current_exe, KPATCH_DEV_PATH)) { + char *const cp_argv[] = { "/system/bin/mv", current_exe, KPATCH_DATA_PATH, NULL }; + fork_for_result(cp_argv[0], cp_argv); + return; + } if (access(APATCH_FLODER, F_OK)) mkdir(APATCH_FLODER, 0700); if (access(APATCH_LOG_FLODER, F_OK)) mkdir(APATCH_LOG_FLODER, 0700); - char current_exe[512] = { '\0' }; - if (from_kernel && readlink("/proc/self/exe", current_exe, sizeof(current_exe) - 1)) { - char *const cp_argv[] = { "/system/bin/cp", current_exe, KPATCH_DATA_PATH, NULL }; - fork_for_result(cp_argv[0], cp_argv); + save_dmegs(post_fs_data_log_0); - char *const rm_argv[] = { "/system/bin/rm", current_exe, NULL }; - fork_for_result(rm_argv[0], rm_argv); - } + char *cp_argv[] = { "/system/bin/cp", KPATCH_DEV_PATH, KPATCH_DATA_PATH, NULL }; + fork_for_result(cp_argv[0], cp_argv); + + cp_argv[1] = EARLY_INIT_LOG_0; + cp_argv[2] = APATCH_LOG_FLODER; + fork_for_result(cp_argv[0], cp_argv); + + cp_argv[1] = EARLY_INIT_LOG_1; + fork_for_result(cp_argv[0], cp_argv); if (!access(skip_sepolicy_path, F_OK)) { char *argv[] = { magiskpolicy_path, "--magisk", "--live", NULL }; @@ -237,8 +263,7 @@ static void post_fs_data_init() log_kernel("%d finished android user post-fs-data-init.\n", getpid()); - char *dmesg_argv_1[] = { "/system/bin/dmesg", ">", boot1_log_path, NULL }; - fork_for_result(dmesg_argv_1[0], dmesg_argv_1); + save_dmegs(post_fs_data_log_1); } static struct option const longopts[] = { @@ -264,7 +289,9 @@ int android_user(int argc, char **argv) } } - if (!strcmp("post-fs-data-init", scmd)) { + if (!strcmp("early-init", scmd)) { + early_init(); + } else if (!strcmp("post-fs-data-init", scmd)) { post_fs_data_init(); } else if (!strcmp("post-fs-data", scmd) || !strcmp("services", scmd) || !strcmp("boot-completed", scmd)) { struct su_profile profile = { @@ -286,7 +313,7 @@ int android_user(int argc, char **argv) fork_for_result(APD_PATH, apd_argv); char log_path[128] = { '\0' }; - sprintf(log_path, "%s/kpatch_%s.log", APATCH_LOG_FLODER, scmd); + sprintf(log_path, "%s/trigger_%s.log", APATCH_LOG_FLODER, scmd); char *dmesg_argv[] = { "/system/bin/dmesg", ">", log_path, NULL }; fork_for_result(dmesg_argv[0], dmesg_argv); From f364e51e3fcc6d7e70ff36859aac85a2b22e5164 Mon Sep 17 00:00:00 2001 From: bmax Date: Sun, 3 Mar 2024 09:57:05 +0800 Subject: [PATCH 47/51] a --- kernel/linux/include/uapi/linux/stat.h | 195 +++++++++++++++++++++++++ kernel/patch/android/userd.c | 11 +- kernel/patch/include/uapi/scdefs.h | 1 + user/android/android_user.c | 21 ++- 4 files changed, 215 insertions(+), 13 deletions(-) create mode 100644 kernel/linux/include/uapi/linux/stat.h diff --git a/kernel/linux/include/uapi/linux/stat.h b/kernel/linux/include/uapi/linux/stat.h new file mode 100644 index 00000000..a768842a --- /dev/null +++ b/kernel/linux/include/uapi/linux/stat.h @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_STAT_H +#define _UAPI_LINUX_STAT_H + +#include + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#define S_IFMT 00170000 +#define S_IFSOCK 0140000 +#define S_IFLNK 0120000 +#define S_IFREG 0100000 +#define S_IFBLK 0060000 +#define S_IFDIR 0040000 +#define S_IFCHR 0020000 +#define S_IFIFO 0010000 +#define S_ISUID 0004000 +#define S_ISGID 0002000 +#define S_ISVTX 0001000 + +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) + +#define S_IRWXU 00700 +#define S_IRUSR 00400 +#define S_IWUSR 00200 +#define S_IXUSR 00100 + +#define S_IRWXG 00070 +#define S_IRGRP 00040 +#define S_IWGRP 00020 +#define S_IXGRP 00010 + +#define S_IRWXO 00007 +#define S_IROTH 00004 +#define S_IWOTH 00002 +#define S_IXOTH 00001 + +#endif + +/* + * Timestamp structure for the timestamps in struct statx. + * + * tv_sec holds the number of seconds before (negative) or after (positive) + * 00:00:00 1st January 1970 UTC. + * + * tv_nsec holds a number of nanoseconds (0..999,999,999) after the tv_sec time. + * + * __reserved is held in case we need a yet finer resolution. + */ +struct statx_timestamp +{ + __s64 tv_sec; + __u32 tv_nsec; + __s32 __reserved; +}; + +/* + * Structures for the extended file attribute retrieval system call + * (statx()). + * + * The caller passes a mask of what they're specifically interested in as a + * parameter to statx(). What statx() actually got will be indicated in + * st_mask upon return. + * + * For each bit in the mask argument: + * + * - if the datum is not supported: + * + * - the bit will be cleared, and + * + * - the datum will be set to an appropriate fabricated value if one is + * available (eg. CIFS can take a default uid and gid), otherwise + * + * - the field will be cleared; + * + * - otherwise, if explicitly requested: + * + * - the datum will be synchronised to the server if AT_STATX_FORCE_SYNC is + * set or if the datum is considered out of date, and + * + * - the field will be filled in and the bit will be set; + * + * - otherwise, if not requested, but available in approximate form without any + * effort, it will be filled in anyway, and the bit will be set upon return + * (it might not be up to date, however, and no attempt will be made to + * synchronise the internal state first); + * + * - otherwise the field and the bit will be cleared before returning. + * + * Items in STATX_BASIC_STATS may be marked unavailable on return, but they + * will have values installed for compatibility purposes so that stat() and + * co. can be emulated in userspace. + */ +struct statx +{ + /* 0x00 */ + __u32 stx_mask; /* What results were written [uncond] */ + __u32 stx_blksize; /* Preferred general I/O size [uncond] */ + __u64 stx_attributes; /* Flags conveying information about the file [uncond] */ + /* 0x10 */ + __u32 stx_nlink; /* Number of hard links */ + __u32 stx_uid; /* User ID of owner */ + __u32 stx_gid; /* Group ID of owner */ + __u16 stx_mode; /* File mode */ + __u16 __spare0[1]; + /* 0x20 */ + __u64 stx_ino; /* Inode number */ + __u64 stx_size; /* File size */ + __u64 stx_blocks; /* Number of 512-byte blocks allocated */ + __u64 stx_attributes_mask; /* Mask to show what's supported in stx_attributes */ + /* 0x40 */ + struct statx_timestamp stx_atime; /* Last access time */ + struct statx_timestamp stx_btime; /* File creation time */ + struct statx_timestamp stx_ctime; /* Last attribute change time */ + struct statx_timestamp stx_mtime; /* Last data modification time */ + /* 0x80 */ + __u32 stx_rdev_major; /* Device ID of special file [if bdev/cdev] */ + __u32 stx_rdev_minor; + __u32 stx_dev_major; /* ID of device containing file [uncond] */ + __u32 stx_dev_minor; + /* 0x90 */ + __u64 stx_mnt_id; + __u32 stx_dio_mem_align; /* Memory buffer alignment for direct I/O */ + __u32 stx_dio_offset_align; /* File offset alignment for direct I/O */ + /* 0xa0 */ + __u64 __spare3[12]; /* Spare space for future expansion */ + /* 0x100 */ +}; + +/* + * Flags to be stx_mask + * + * Query request/result mask for statx() and struct statx::stx_mask. + * + * These bits should be set in the mask argument of statx() to request + * particular items when calling statx(). + */ +#define STATX_TYPE 0x00000001U /* Want/got stx_mode & S_IFMT */ +#define STATX_MODE 0x00000002U /* Want/got stx_mode & ~S_IFMT */ +#define STATX_NLINK 0x00000004U /* Want/got stx_nlink */ +#define STATX_UID 0x00000008U /* Want/got stx_uid */ +#define STATX_GID 0x00000010U /* Want/got stx_gid */ +#define STATX_ATIME 0x00000020U /* Want/got stx_atime */ +#define STATX_MTIME 0x00000040U /* Want/got stx_mtime */ +#define STATX_CTIME 0x00000080U /* Want/got stx_ctime */ +#define STATX_INO 0x00000100U /* Want/got stx_ino */ +#define STATX_SIZE 0x00000200U /* Want/got stx_size */ +#define STATX_BLOCKS 0x00000400U /* Want/got stx_blocks */ +#define STATX_BASIC_STATS 0x000007ffU /* The stuff in the normal stat struct */ +#define STATX_BTIME 0x00000800U /* Want/got stx_btime */ +#define STATX_MNT_ID 0x00001000U /* Got stx_mnt_id */ +#define STATX_DIOALIGN 0x00002000U /* Want/got direct I/O alignment info */ + +#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx expansion */ + +#ifndef __KERNEL__ +/* + * This is deprecated, and shall remain the same value in the future. To avoid + * confusion please use the equivalent (STATX_BASIC_STATS | STATX_BTIME) + * instead. + */ +#define STATX_ALL 0x00000fffU +#endif + +/* + * Attributes to be found in stx_attributes and masked in stx_attributes_mask. + * + * These give information about the features or the state of a file that might + * be of use to ordinary userspace programs such as GUIs or ls rather than + * specialised tools. + * + * Note that the flags marked [I] correspond to the FS_IOC_SETFLAGS flags + * semantically. Where possible, the numerical value is picked to correspond + * also. Note that the DAX attribute indicates that the file is in the CPU + * direct access state. It does not correspond to the per-inode flag that + * some filesystems support. + * + */ +#define STATX_ATTR_COMPRESSED 0x00000004 /* [I] File is compressed by the fs */ +#define STATX_ATTR_IMMUTABLE 0x00000010 /* [I] File is marked immutable */ +#define STATX_ATTR_APPEND 0x00000020 /* [I] File is append-only */ +#define STATX_ATTR_NODUMP 0x00000040 /* [I] File is not to be dumped */ +#define STATX_ATTR_ENCRYPTED 0x00000800 /* [I] File requires key to decrypt in fs */ +#define STATX_ATTR_AUTOMOUNT 0x00001000 /* Dir: Automount trigger */ +#define STATX_ATTR_MOUNT_ROOT 0x00002000 /* Root of a mount */ +#define STATX_ATTR_VERITY 0x00100000 /* [I] Verity protected file */ +#define STATX_ATTR_DAX 0x00200000 /* File is currently in DAX state */ + +#endif /* _UAPI_LINUX_STAT_H */ \ No newline at end of file diff --git a/kernel/patch/android/userd.c b/kernel/patch/android/userd.c index 01565a36..7ea65cf1 100644 --- a/kernel/patch/android/userd.c +++ b/kernel/patch/android/userd.c @@ -30,6 +30,7 @@ #include #include #include +#include static const void *kernel_read_file(const char *path, loff_t *len) { @@ -108,12 +109,18 @@ static void pre_user_exec_init() { log_boot("event: %s\n", EXTRA_EVENT_PRE_EXEC_INIT); try_extract_kpatch(EXTRA_EVENT_PRE_EXEC_INIT); + + // struct file *work_dir = filp_open(KPATCH_DEV_WORK_DIR, O_DIRECTORY | O_CREAT, S_IRUSR); + // if (!work_dir || IS_ERR(work_dir)) { + // log_boot("creat work dir error: %s\n", KPATCH_DEV_WORK_DIR); + // return; + // } + // filp_close(work_dir, 0); } static void pre_init_second_stage() { log_boot("event: %s\n", EXTRA_EVENT_PRE_SECOND_STAGE); - try_extract_kpatch(EXTRA_EVENT_PRE_SECOND_STAGE); } static void on_first_app_process() @@ -267,6 +274,8 @@ static const char user_rc_data[] = { // "on property:sys.boot_completed=1\n" " rm " REPLACE_RC_FILE "\n" " rm " KPATCH_DEV_PATH "\n" + " rm " EARLY_INIT_LOG_0 "\n" + " rm " EARLY_INIT_LOG_1 "\n" " exec -- " SUPERCMD " %s " KPATCH_DATA_PATH " %s android_user boot-completed -k\n" "\n\n" "" diff --git a/kernel/patch/include/uapi/scdefs.h b/kernel/patch/include/uapi/scdefs.h index e0879e63..af41d3eb 100644 --- a/kernel/patch/include/uapi/scdefs.h +++ b/kernel/patch/include/uapi/scdefs.h @@ -66,6 +66,7 @@ struct su_profile #define ANDROID_SU_PATH "/system/bin/kp" #define KPATCH_DATA_PATH "/data/adb/kpatch" #define KPATCH_DEV_PATH "/dev/kpatch" +#define KPATCH_DEV_WORK_DIR "/dev/kpatch_work/" #define APD_PATH "/data/adb/apd" #define SUPERCMD "/system/bin/truncate" diff --git a/user/android/android_user.c b/user/android/android_user.c index 2c9040d2..7c003372 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -229,12 +229,9 @@ static void post_fs_data_init() log_kernel("%d starting android user post-fs-data-init, exec: %s\n", getpid(), current_exe); - char *dmesg_argv[] = { "/system/bin/dmesg", ">", post_fs_data_log_0, NULL }; - fork_for_result(dmesg_argv[0], dmesg_argv); - if (!strcmp(current_exe, KPATCH_DEV_PATH)) { - char *const cp_argv[] = { "/system/bin/mv", current_exe, KPATCH_DATA_PATH, NULL }; - fork_for_result(cp_argv[0], cp_argv); + char *const args[] = { "/system/bin/mv", current_exe, KPATCH_DATA_PATH, NULL }; + fork_for_result(args[0], args); return; } @@ -243,15 +240,15 @@ static void post_fs_data_init() save_dmegs(post_fs_data_log_0); - char *cp_argv[] = { "/system/bin/cp", KPATCH_DEV_PATH, KPATCH_DATA_PATH, NULL }; - fork_for_result(cp_argv[0], cp_argv); + char *log_args[] = { "/system/bin/mv", KPATCH_DEV_PATH, KPATCH_DATA_PATH, NULL }; + fork_for_result(log_args[0], log_args); - cp_argv[1] = EARLY_INIT_LOG_0; - cp_argv[2] = APATCH_LOG_FLODER; - fork_for_result(cp_argv[0], cp_argv); + log_args[1] = EARLY_INIT_LOG_0; + log_args[2] = APATCH_LOG_FLODER; + fork_for_result(log_args[0], log_args); - cp_argv[1] = EARLY_INIT_LOG_1; - fork_for_result(cp_argv[0], cp_argv); + log_args[1] = EARLY_INIT_LOG_1; + fork_for_result(log_args[0], log_args); if (!access(skip_sepolicy_path, F_OK)) { char *argv[] = { magiskpolicy_path, "--magisk", "--live", NULL }; From 7c1a2508ca7a48c095a9029deef7738f6a78eefb Mon Sep 17 00:00:00 2001 From: bmax Date: Sun, 3 Mar 2024 09:58:52 +0800 Subject: [PATCH 48/51] a --- user/android/android_user.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/user/android/android_user.c b/user/android/android_user.c index 7c003372..14bc6a1a 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -240,11 +240,7 @@ static void post_fs_data_init() save_dmegs(post_fs_data_log_0); - char *log_args[] = { "/system/bin/mv", KPATCH_DEV_PATH, KPATCH_DATA_PATH, NULL }; - fork_for_result(log_args[0], log_args); - - log_args[1] = EARLY_INIT_LOG_0; - log_args[2] = APATCH_LOG_FLODER; + char *log_args[] = { "/system/bin/mv", EARLY_INIT_LOG_0, APATCH_LOG_FLODER, NULL }; fork_for_result(log_args[0], log_args); log_args[1] = EARLY_INIT_LOG_1; From 4c42f34259402a32f72230f806ef0c530f007fec Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 5 Mar 2024 10:20:24 +0800 Subject: [PATCH 49/51] a --- tools/patch.c | 6 +++++- user/android/android_user.c | 7 ++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tools/patch.c b/tools/patch.c index 4f97f673..59b1c24d 100644 --- a/tools/patch.c +++ b/tools/patch.c @@ -97,7 +97,11 @@ void print_preset_info(preset_t *preset) while (pos < setup->additional + ADDITIONAL_LEN) { int len = *pos; if (!len) break; - fprintf(stdout, "%s\n", strndup(++pos, len)); + pos++; + char backup = *(pos + len); + *(pos + len) = 0; + fprintf(stdout, "%s\n", pos); + *(pos + len) = backup; pos += len; } } diff --git a/user/android/android_user.c b/user/android/android_user.c index 14bc6a1a..24446315 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -32,7 +32,6 @@ struct allow_pkg_info static char magiskpolicy_path[] = APATCH_BIN_FLODER "magiskpolicy"; static char pkg_cfg_path[] = APATCH_FLODER "package_config"; static char su_path_path[] = APATCH_FLODER "su_path"; -static char skip_sepolicy_path[] = APATCH_FLODER "skip_sepolicy"; static char post_fs_data_log_0[] = APATCH_LOG_FLODER "post_fs_data_0.log"; static char post_fs_data_log_1[] = APATCH_LOG_FLODER "post_fs_data_1.log"; @@ -246,10 +245,8 @@ static void post_fs_data_init() log_args[1] = EARLY_INIT_LOG_1; fork_for_result(log_args[0], log_args); - if (!access(skip_sepolicy_path, F_OK)) { - char *argv[] = { magiskpolicy_path, "--magisk", "--live", NULL }; - fork_for_result(magiskpolicy_path, argv); - } + char *argv[] = { magiskpolicy_path, "--magisk", "--live", NULL }; + fork_for_result(magiskpolicy_path, argv); load_config_su_path(); load_config_allow_uids(); From 1c25d30f1328bcf0bddc64d9261490e269a69b01 Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 5 Mar 2024 10:21:50 +0800 Subject: [PATCH 50/51] a --- kpm-demo/shmem/.gitignore | 19 ------------------ kpm-demo/shmem/Makefile | 30 ---------------------------- kpm-demo/shmem/link.lds | 5 ----- kpm-demo/shmem/main.c | 41 --------------------------------------- 4 files changed, 95 deletions(-) delete mode 100644 kpm-demo/shmem/.gitignore delete mode 100644 kpm-demo/shmem/Makefile delete mode 100644 kpm-demo/shmem/link.lds delete mode 100644 kpm-demo/shmem/main.c diff --git a/kpm-demo/shmem/.gitignore b/kpm-demo/shmem/.gitignore deleted file mode 100644 index 2085cbfc..00000000 --- a/kpm-demo/shmem/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -# Prerequisites -*.d - -# Object files -*.o -*.ko -*.obj -*.elf - -# Libraries -*.lib -*.a -*.la -*.lo - -*.bin -*.elf - -*.kpm diff --git a/kpm-demo/shmem/Makefile b/kpm-demo/shmem/Makefile deleted file mode 100644 index 8b0ffa18..00000000 --- a/kpm-demo/shmem/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -ifndef TARGET_COMPILE - $(error TARGET_COMPILE not set) -endif - -ifndef KP_DIR - KP_DIR = ../.. -endif - - -CC = $(TARGET_COMPILE)gcc -LD = $(TARGET_COMPILE)ld - -INCLUDE_DIRS := . include patch/include linux/include linux/arch/arm64/include linux/tools/arch/arm64/include - -INCLUDE_FLAGS := $(foreach dir,$(INCLUDE_DIRS),-I$(KP_DIR)/kernel/$(dir)) - -objs := main.o - -all: shmem.kpm - -shmem.kpm: ${objs} - ${CC} -r -o $@ $^ - -%.o: %.c - ${CC} $(CFLAGS) $(INCLUDE_FLAGS) -Tlink.lds -c -O2 -o $@ $< - -.PHONY: clean -clean: - rm -rf *.kpm - find . -name "*.o" | xargs rm -f \ No newline at end of file diff --git a/kpm-demo/shmem/link.lds b/kpm-demo/shmem/link.lds deleted file mode 100644 index d599a67a..00000000 --- a/kpm-demo/shmem/link.lds +++ /dev/null @@ -1,5 +0,0 @@ -SECTIONS { - .plt (NOLOAD) : { BYTE(0) } - .init.plt (NOLOAD) : { BYTE(0) } - .text.ftrace_trampoline (NOLOAD) : { BYTE(0) } -} \ No newline at end of file diff --git a/kpm-demo/shmem/main.c b/kpm-demo/shmem/main.c deleted file mode 100644 index 98a9f14f..00000000 --- a/kpm-demo/shmem/main.c +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2024 bmax121. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include - -KPM_NAME("kpm-shmem"); -KPM_VERSION("1.0.0"); -KPM_LICENSE("GPL v2"); -KPM_AUTHOR("bmax121"); -KPM_DESCRIPTION("Share memory between processes"); - -/* - * This module's main functionality is to map any address of any process to any other process. - * Of course, this means you can easily manipulate data of other processes. -*/ - -static long init(const char *args, const char *event, void *__user reserved) -{ - return 0; -} - -static long control0(const char *args, char *__user out_msg, int outlen) -{ - return 0; -} - -static long exit(void *__user reserved) -{ - return 0; -} - -KPM_INIT(init); -KPM_CTL0(control0); -KPM_EXIT(exit); From df23c454d6fd14235cdf001774b855c90664f093 Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 5 Mar 2024 13:59:00 +0800 Subject: [PATCH 51/51] a --- user/android/android_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user/android/android_user.c b/user/android/android_user.c index 624e2a0f..2f736203 100644 --- a/user/android/android_user.c +++ b/user/android/android_user.c @@ -229,7 +229,7 @@ static void post_fs_data_init() log_kernel("%d starting android user post-fs-data-init, exec: %s\n", getpid(), current_exe); if (!strcmp(current_exe, KPATCH_DEV_PATH)) { - char *const args[] = { "/system/bin/mv", current_exe, KPATCH_DATA_PATH, NULL }; + char *const args[] = { "/system/bin/cp", "-f", current_exe, KPATCH_DATA_PATH, NULL }; fork_for_result(args[0], args); return; } @@ -239,10 +239,10 @@ static void post_fs_data_init() save_dmegs(post_fs_data_log_0); - char *log_args[] = { "/system/bin/mv", EARLY_INIT_LOG_0, APATCH_LOG_FLODER, NULL }; + char *log_args[] = { "/system/bin/cp", "-f", EARLY_INIT_LOG_0, APATCH_LOG_FLODER, NULL }; fork_for_result(log_args[0], log_args); - log_args[1] = EARLY_INIT_LOG_1; + log_args[2] = EARLY_INIT_LOG_1; fork_for_result(log_args[0], log_args); char *argv[] = { magiskpolicy_path, "--magisk", "--live", NULL };