From c6008bd3e667456fc1e588ba785e22f57507bde7 Mon Sep 17 00:00:00 2001 From: bmax Date: Tue, 26 Mar 2024 18:48:21 +0800 Subject: [PATCH] a --- kernel/patch/common/utils.c | 52 +++++++++++++++++++++---------------- kernel/patch/ksyms/libs.c | 32 +++-------------------- kernel/patch/patch.c | 19 +++++++------- 3 files changed, 41 insertions(+), 62 deletions(-) diff --git a/kernel/patch/common/utils.c b/kernel/patch/common/utils.c index 5558fd80..045757d7 100644 --- a/kernel/patch/common/utils.c +++ b/kernel/patch/common/utils.c @@ -22,7 +22,6 @@ static inline int compat_xt_data_copy_to_user(void __user *dst, const void *src, kfunc_direct_call(xt_data_to_user, dst, src, size, size, size); } -// todo: static method extern int kfunc_def(bits_to_user)(unsigned long *bits, unsigned int maxbit, unsigned int maxlen, void __user *p, int compat); @@ -31,21 +30,22 @@ static inline int compat_bits_copy_to_user(void __user *dst, const void *src, in kfunc_direct_call(bits_to_user, (unsigned long *)src, size * sizeof(unsigned long), size, dst, 0); } -// todo: n > page_size -int trace_seq_copy_to_user(void __user *to, const void *from, int n) +__noinline int trace_seq_copy_to_user(void __user *to, const void *from, int n) { + // todo: n > page_size + if (n > page_size) return 0; + unsigned char trace_seq_data[page_size + 0x20]; struct trace_seq *trace_seq = (struct trace_seq *)trace_seq_data; int *fp = (int *)(((uintptr_t)trace_seq) + page_size); int *plen = fp; int *preadpos = fp + 1; int *pfull = fp + 2; - unsigned char *pbuffer = (unsigned char *)trace_seq; *plen = n; *preadpos = 0; *pfull = 0; - if (n > page_size) return 0; - memcpy(pbuffer, from, n); + + memcpy((void *)trace_seq, from, n); int sz = kfunc(trace_seq_to_user)(trace_seq, to, n); return sz; } @@ -60,29 +60,35 @@ int seq_buf_copy_to_user(void __user *to, const void *from, int n) return kfunc(seq_buf_to_user)(&seq_buf, to, n); } -// return copied length +/** + * @brief + * + * @param to + * @param from + * @param n + * @return int copied lenght + */ int __must_check compat_copy_to_user(void __user *to, const void *from, int n) { - int copy_len = 0; + int cplen = 0; + if (kfunc(seq_buf_to_user)) { - copy_len = seq_buf_copy_to_user((void *__user)to, from, n); - // } - // else if (kfunc(bits_to_user)) { - // // bits_to_user, str_to_user - // int ret = compat_bits_copy_to_user(to, from, n); - // if (ret == n) return -EFAULT; - // copy_len = n - ret; - // } else if (kfunc(xt_data_to_user)) { - // // xt_data_to_user, xt_obj_to_user - // int ret = compat_xt_data_copy_to_user(to, from, n); - // if (ret == n) return -EFAULT; - // copy_len = n - ret; + cplen = seq_buf_copy_to_user(to, from, n); + } else if (kfunc(xt_data_to_user)) { + // xt_data_to_user, xt_obj_to_user + cplen = compat_xt_data_copy_to_user(to, from, n); + if (!cplen) cplen = n; + } else if (kfunc(bits_to_user)) { + // bits_to_user, str_to_user + cplen = compat_bits_copy_to_user(to, from, n); } else if (kfunc(trace_seq_to_user)) { - copy_len = trace_seq_copy_to_user((void *__user)to, from, n); + cplen = trace_seq_copy_to_user(to, from, n); } else { - // alt: copy_arg_to_user, + logke("no compat_copy_to_user\n"); + // copy_arg_to_user, } - return copy_len; + logkd("copy rc %d\n", cplen); + return cplen; } KP_EXPORT_SYMBOL(compat_copy_to_user); diff --git a/kernel/patch/ksyms/libs.c b/kernel/patch/ksyms/libs.c index 1c83c94f..9dcac23b 100644 --- a/kernel/patch/ksyms/libs.c +++ b/kernel/patch/ksyms/libs.c @@ -206,22 +206,8 @@ static void _linux_lib_argv_split_sym_match(const char *name, unsigned long addr #include #include -int kfunc_def(seq_buf_printf)(struct seq_buf *s, const char *fmt, ...) = 0; int kfunc_def(seq_buf_to_user)(struct seq_buf *s, char __user *ubuf, int cnt) = 0; -int kfunc_def(seq_buf_puts)(struct seq_buf *s, const char *str) = 0; -int kfunc_def(seq_buf_putc)(struct seq_buf *s, unsigned char c) = 0; -int kfunc_def(seq_buf_putmem)(struct seq_buf *s, const void *mem, unsigned int len) = 0; -int kfunc_def(seq_buf_putmem_hex)(struct seq_buf *s, const void *mem, unsigned int len) = 0; -int kfunc_def(seq_buf_bitmask)(struct seq_buf *s, const unsigned long *maskp, int nmaskbits) = 0; - -int kfunc_def(trace_seq_printf)(struct trace_seq *s, const char *fmt, ...) = 0; int kfunc_def(trace_seq_to_user)(struct trace_seq *s, char __user *ubuf, int cnt) = 0; -int kfunc_def(trace_seq_puts)(struct trace_seq *s, const char *str) = 0; -int kfunc_def(trace_seq_putc)(struct trace_seq *s, unsigned char c) = 0; -int kfunc_def(trace_seq_putmem)(struct trace_seq *s, const void *mem, unsigned int len) = 0; -int kfunc_def(trace_seq_putmem_hex)(struct trace_seq *s, const void *mem, unsigned int len) = 0; -int kfunc_def(trace_seq_bitmask)(struct trace_seq *s, const unsigned long *maskp, int nmaskbits) = 0; - int kfunc_def(xt_data_to_user)(void __user *dst, const void *src, int usersize, int size, int aligned_size) = 0; int kfunc_def(bits_to_user)(unsigned long *bits, unsigned int maxbit, unsigned int maxlen, void __user *p, int compat) = 0; @@ -230,21 +216,9 @@ static void _linux_lib_seq_buf_sym_match(const char *name, unsigned long addr) { kfunc_match(seq_buf_to_user, name, addr); kfunc_match(trace_seq_to_user, name, addr); - if (kfunc(seq_buf_to_user)) { - kfunc_match(seq_buf_printf, name, addr); - kfunc_match(seq_buf_puts, name, addr); - // kfunc_match(seq_buf_putc, name, addr); - kfunc_match(seq_buf_putmem, name, addr); - // kfunc_match(seq_buf_putmem_hex, name, addr); - // kfunc_match(seq_buf_bitmask, name, addr); - } else { - kfunc_match(trace_seq_printf, name, addr); - kfunc_match(trace_seq_puts, name, addr); - // kfunc_match(trace_seq_putc, name, addr); - kfunc_match(trace_seq_putmem, name, addr); - // kfunc_match(trace_seq_putmem_hex, name, addr); - // kfunc_match(trace_seq_bitmask, name, addr); - } + kfunc_match(xt_data_to_user, name, addr); + // todo: static function + kfunc_match(bits_to_user, name, addr); } // linux/include/kernel.h diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index 7fe65218..726d4efa 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -95,7 +95,7 @@ static void before_rest_init(hook_fargs4_t *args, void *udata) return; } -static int pre_ki_kpm(const patch_extra_item_t *extra, const char *args, const void *data, void *udata) +static int pre_kernel_init(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) { @@ -110,7 +110,7 @@ static int pre_ki_kpm(const patch_extra_item_t *extra, const char *args, const v static void before_kernel_init(hook_fargs4_t *args, void *udata) { log_boot("event: %s\n", EXTRA_EVENT_PRE_KERNEL_INIT); - on_each_extra_item(pre_ki_kpm, 0); + on_each_extra_item(pre_kernel_init, 0); } static void after_kernel_init(hook_fargs4_t *args, void *udata) @@ -138,14 +138,13 @@ int patch() ret |= rc; } - log_boot("kernel init: %llx\n", get_preset_patch_sym()->kernel_init - kernel_va); - // // kernel_init - // unsigned long kernel_init_addr = get_preset_patch_sym()->kernel_init; - // if (kernel_init_addr) { - // 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; - // } + // kernel_init + unsigned long kernel_init_addr = get_preset_patch_sym()->kernel_init; + if (kernel_init_addr) { + 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; + } return ret; }