diff --git a/kernel/kpm/Makefile b/kernel/kpm/Makefile index 3f75542d..58126fbd 100644 --- a/kernel/kpm/Makefile +++ b/kernel/kpm/Makefile @@ -3,4 +3,4 @@ obj-y += compact.o obj-y += super_access.o ccflags-y += -Wno-implicit-function-declaration -Wno-strict-prototypes -Wno-int-conversion -Wno-gcc-compat -ccflags-y += -Wno-declaration-after-statement -Wno-unused-function \ No newline at end of file +ccflags-y += -Wno-declaration-after-statement -Wno-unused-function diff --git a/kernel/kpm/compact.c b/kernel/kpm/compact.c index 9bece752..8af317c0 100644 --- a/kernel/kpm/compact.c +++ b/kernel/kpm/compact.c @@ -13,7 +13,7 @@ #include #include #include -#include /* 包含 ARM64 重定位类型定义 */ +#include #include #include #include @@ -29,74 +29,72 @@ #include "../allowlist.h" #include "../manager.h" -unsigned long sukisu_compact_find_symbol(const char* name); - -// ====================================================================== -// 兼容函数 for KPM - -static -int sukisu_is_su_allow_uid(uid_t uid) { +static int sukisu_is_su_allow_uid(uid_t uid) +{ return ksu_is_allow_uid(uid) ? 1 : 0; } -static -int sukisu_get_ap_mod_exclude(uid_t uid) { - // Not supported - return 0; +static int sukisu_get_ap_mod_exclude(uid_t uid) +{ + return 0; /* Not supported */ } -static -int sukisu_is_uid_should_umount(uid_t uid) { +static int sukisu_is_uid_should_umount(uid_t uid) +{ return ksu_uid_should_umount(uid) ? 1 : 0; } -static -int sukisu_is_current_uid_manager() { +static int sukisu_is_current_uid_manager(void) +{ return is_manager(); } -static -uid_t sukisu_get_manager_uid() { +static uid_t sukisu_get_manager_uid(void) +{ return ksu_manager_uid; } -// ====================================================================== +static void sukisu_set_manager_uid(uid_t uid, int force) +{ + if (force || ksu_manager_uid == -1) + ksu_manager_uid = uid; +} struct CompactAddressSymbol { - const char* symbol_name; - void* addr; + const char *symbol_name; + void *addr; }; -static struct CompactAddressSymbol address_symbol [] = { +unsigned long sukisu_compact_find_symbol(const char *name); + +static struct CompactAddressSymbol address_symbol[] = { { "kallsyms_lookup_name", &kallsyms_lookup_name }, { "compact_find_symbol", &sukisu_compact_find_symbol }, - { "is_run_in_sukisu_ultra", (void*)1 }, + { "is_run_in_sukisu_ultra", (void *)1 }, { "is_su_allow_uid", &sukisu_is_su_allow_uid }, { "get_ap_mod_exclude", &sukisu_get_ap_mod_exclude }, { "is_uid_should_umount", &sukisu_is_uid_should_umount }, { "is_current_uid_manager", &sukisu_is_current_uid_manager }, - { "get_manager_uid", &sukisu_get_manager_uid } + { "get_manager_uid", &sukisu_get_manager_uid }, + { "sukisu_set_manager_uid", &sukisu_set_manager_uid } }; -unsigned long sukisu_compact_find_symbol(const char* name) { +unsigned long sukisu_compact_find_symbol(const char* name) +{ int i; unsigned long addr; - // 先自己在地址表部分查出来 - for(i = 0; i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol)); i++) { - struct CompactAddressSymbol* symbol = &address_symbol[i]; - if(strcmp(name, symbol->symbol_name) == 0) { - return (unsigned long) symbol->addr; - } + for (i = 0; i < (sizeof(address_symbol) / sizeof(struct CompactAddressSymbol)); i++) { + struct CompactAddressSymbol *symbol = &address_symbol[i]; + + if (strcmp(name, symbol->symbol_name) == 0) + return (unsigned long)symbol->addr; } - // 通过内核来查 addr = kallsyms_lookup_name(name); - if(addr) { + if (addr) return addr; - } return 0; } - EXPORT_SYMBOL(sukisu_compact_find_symbol); diff --git a/kernel/kpm/compact.h b/kernel/kpm/compact.h index 01e8fa88..c9f69dce 100644 --- a/kernel/kpm/compact.h +++ b/kernel/kpm/compact.h @@ -1,6 +1,6 @@ -#ifndef ___SUKISU_KPM_COMPACT_H -#define ___SUKISU_KPM_COMPACT_H +#ifndef __SUKISU_KPM_COMPACT_H +#define __SUKISU_KPM_COMPACT_H -unsigned long sukisu_compact_find_symbol(const char* name); +extern unsigned long sukisu_compact_find_symbol(const char *name); -#endif \ No newline at end of file +#endif diff --git a/kernel/kpm/kpm.c b/kernel/kpm/kpm.c index 671acafc..7fedcddb 100644 --- a/kernel/kpm/kpm.c +++ b/kernel/kpm/kpm.c @@ -8,6 +8,7 @@ * 集成了 ELF 解析、内存布局、符号处理、重定位(支持 ARM64 重定位类型) * 并参照KernelPatch的标准KPM格式实现加载和控制 */ + #include #include #include @@ -23,7 +24,7 @@ #include #include #include -#include /* 包含 ARM64 重定位类型定义 */ +#include #include #include #include @@ -39,7 +40,7 @@ #include #include #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) && defined(CONFIG_MODULES) -#include // 需要启用 CONFIG_MODULES +#include #endif #include "kpm.h" #include "compact.h" @@ -54,131 +55,170 @@ #endif #endif -// ============================================================================================ - -noinline -NO_OPTIMIZE -void sukisu_kpm_load_module_path(const char* path, const char* args, void* ptr, void __user* result) { - // This is a KPM module stub. +noinline NO_OPTIMIZE void sukisu_kpm_load_module_path(const char *path, + const char *args, void *ptr, void __user *result) +{ int res = -1; - printk("KPM: Stub function called (sukisu_kpm_load_module_path). path=%s args=%s ptr=%p\n", path, args, ptr); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); -} -noinline -NO_OPTIMIZE -void sukisu_kpm_unload_module(const char* name, void* ptr, void __user* result) { - // This is a KPM module stub. - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_unload_module). name=%s ptr=%p\n", name, ptr); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); -} + printk("KPM: Stub function called (sukisu_kpm_load_module_path). " + "path=%s args=%s ptr=%p\n", path, args, ptr); -noinline -NO_OPTIMIZE -void sukisu_kpm_num(void __user* result) { - // This is a KPM module stub. - int res = 0; - printk("KPM: Stub function called (sukisu_kpm_num).\n"); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); -} + __asm__ volatile("nop"); -noinline -NO_OPTIMIZE -void sukisu_kpm_info(const char* name, void __user* out, void __user* result) { - // This is a KPM module stub. - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_info). name=%s buffer=%p\n", name, out); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); } - -noinline -NO_OPTIMIZE -void sukisu_kpm_list(void __user* out, unsigned int bufferSize, void __user* result) { - // This is a KPM module stub. - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_list). buffer=%p size=%d\n", out, bufferSize); - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); -} - -noinline -NO_OPTIMIZE -void sukisu_kpm_control(void __user* name, void __user* args, void __user* result) { - // This is a KPM module stub. - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_control). name=%p args=%p\n", name, args); - __asm__ volatile("nop"); // 精确控制循环不被优化 - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); -} - -noinline -NO_OPTIMIZE -void sukisu_kpm_version(void __user* out, unsigned int bufferSize, void __user* result) { - int res = -1; - printk("KPM: Stub function called (sukisu_kpm_version). buffer=%p size=%d\n", out, bufferSize); - if(copy_to_user(result, &res, sizeof(res)) < 1) printk("KPM: Copy to user failed."); -} - EXPORT_SYMBOL(sukisu_kpm_load_module_path); + +noinline NO_OPTIMIZE void sukisu_kpm_unload_module(const char *name, + void *ptr, void __user *result) +{ + int res = -1; + + printk("KPM: Stub function called (sukisu_kpm_unload_module). " + "name=%s ptr=%p\n", name, ptr); + + __asm__ volatile("nop"); + + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); +} EXPORT_SYMBOL(sukisu_kpm_unload_module); + +noinline NO_OPTIMIZE void sukisu_kpm_num(void __user *result) +{ + int res = 0; + + printk("KPM: Stub function called (sukisu_kpm_num).\n"); + + __asm__ volatile("nop"); + + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); +} EXPORT_SYMBOL(sukisu_kpm_num); + +noinline NO_OPTIMIZE void sukisu_kpm_info(const char *name, void __user *out, + void __user *result) +{ + int res = -1; + + printk("KPM: Stub function called (sukisu_kpm_info). " + "name=%s buffer=%p\n", name, out); + + __asm__ volatile("nop"); + + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); +} EXPORT_SYMBOL(sukisu_kpm_info); + +noinline NO_OPTIMIZE void sukisu_kpm_list(void __user *out, unsigned int bufferSize, + void __user *result) +{ + int res = -1; + + printk("KPM: Stub function called (sukisu_kpm_list). " + "buffer=%p size=%d\n", out, bufferSize); + + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); +} EXPORT_SYMBOL(sukisu_kpm_list); -EXPORT_SYMBOL(sukisu_kpm_version); + +noinline NO_OPTIMIZE void sukisu_kpm_control(void __user *name, void __user *args, + void __user *result) +{ + int res = -1; + + printk("KPM: Stub function called (sukisu_kpm_control). " + "name=%p args=%p\n", name, args); + + __asm__ volatile("nop"); + + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); +} EXPORT_SYMBOL(sukisu_kpm_control); -noinline -int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) +noinline NO_OPTIMIZE void sukisu_kpm_version(void __user *out, unsigned int bufferSize, + void __user *result) { - if(arg2 == SUKISU_KPM_LOAD) { + int res = -1; + + printk("KPM: Stub function called (sukisu_kpm_version). " + "buffer=%p size=%d\n", out, bufferSize); + + if (copy_to_user(result, &res, sizeof(res)) < 1) + printk("KPM: Copy to user failed."); +} +EXPORT_SYMBOL(sukisu_kpm_version); + +noinline int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4, + unsigned long arg5) +{ + if (arg2 == SUKISU_KPM_LOAD) { char kernel_load_path[256] = { 0 }; char kernel_args_buffer[256] = { 0 }; - if(arg3 == 0) { + if (arg3 == 0) return -1; - } - strncpy_from_user((char*)&kernel_load_path, (const char __user *)arg3, 255); - if(arg4 != 0) { - strncpy_from_user((char*)&kernel_args_buffer, (const char __user *)arg4, 255); - } - sukisu_kpm_load_module_path((const char*)&kernel_load_path, (const char*) &kernel_args_buffer, NULL, (void __user*) arg5); - } else if(arg2 == SUKISU_KPM_UNLOAD) { + strncpy_from_user((char *)&kernel_load_path, (const char __user *)arg3, 255); + + if (arg4 != 0) + strncpy_from_user((char *)&kernel_args_buffer, (const char __user *)arg4, 255); + + sukisu_kpm_load_module_path((const char *)&kernel_load_path, + (const char *)&kernel_args_buffer, NULL, (void __user *)arg5); + } else if (arg2 == SUKISU_KPM_UNLOAD) { char kernel_name_buffer[256] = { 0 }; - if(arg3 == 0) { + if (arg3 == 0) return -1; - } - strncpy_from_user((char*)&kernel_name_buffer, (const char __user *)arg3, 255); - sukisu_kpm_unload_module((const char*) &kernel_name_buffer, NULL, (void __user*) arg5); - } else if(arg2 == SUKISU_KPM_NUM) { - sukisu_kpm_num((void __user*) arg5); - } else if(arg2 == SUKISU_KPM_INFO) { + strncpy_from_user((char *)&kernel_name_buffer, (const char __user *)arg3, 255); + + sukisu_kpm_unload_module((const char *)&kernel_name_buffer, NULL, + (void __user *)arg5); + } else if (arg2 == SUKISU_KPM_NUM) { + sukisu_kpm_num((void __user *)arg5); + } else if (arg2 == SUKISU_KPM_INFO) { char kernel_name_buffer[256] = { 0 }; - if(arg3 == 0 || arg4 == 0) { + if (arg3 == 0 || arg4 == 0) return -1; - } - strncpy_from_user((char*)&kernel_name_buffer, (const char __user *)arg3, 255); - sukisu_kpm_info((const char*) &kernel_name_buffer, (char __user*) arg4, (void __user*) arg5); - } else if(arg2 == SUKISU_KPM_LIST) { - sukisu_kpm_list((char __user*) arg3, (unsigned int) arg4, (void __user*) arg5); - } else if(arg2 == SUKISU_KPM_VERSION) { - sukisu_kpm_version((char __user*) arg3, (unsigned int) arg4, (void __user*) arg5); - } else if(arg2 == SUKISU_KPM_CONTROL) { - sukisu_kpm_control((char __user*) arg3, (char __user*) arg4, (void __user*) arg5); + strncpy_from_user((char *)&kernel_name_buffer, (const char __user *)arg3, 255); + + sukisu_kpm_info((const char *)&kernel_name_buffer, (char __user *)arg4, + (void __user *)arg5); + } else if (arg2 == SUKISU_KPM_LIST) { + sukisu_kpm_list((char __user *)arg3, (unsigned int)arg4, (void __user *)arg5); + } else if (arg2 == SUKISU_KPM_CONTROL) { + sukisu_kpm_control((char __user *)arg3, (char __user *)arg4, (void __user *)arg5); + } else if (arg2 == SUKISU_KPM_VERSION) { + sukisu_kpm_version((char __user *)arg3, (unsigned int)arg4, (void __user *)arg5); } + return 0; } +EXPORT_SYMBOL(sukisu_handle_kpm); int sukisu_is_kpm_control_code(unsigned long arg2) { - return (arg2 >= CMD_KPM_CONTROL && arg2 <= CMD_KPM_CONTROL_MAX) ? 1 : 0; + return (arg2 >= CMD_KPM_CONTROL && + arg2 <= CMD_KPM_CONTROL_MAX) ? 1 : 0; +} + +int do_kpm(void __user *arg) +{ + struct ksu_kpm_cmd cmd; + + if (copy_from_user(&cmd, arg, sizeof(cmd))) { + pr_err("kpm: copy_from_user failed\n"); + return -EFAULT; + } + + return sukisu_handle_kpm(cmd.arg2, cmd.arg3, cmd.arg4, cmd.arg5); } -EXPORT_SYMBOL(sukisu_handle_kpm); diff --git a/kernel/kpm/kpm.h b/kernel/kpm/kpm.h index f9f98848..7e93ad22 100644 --- a/kernel/kpm/kpm.h +++ b/kernel/kpm/kpm.h @@ -1,44 +1,70 @@ -#ifndef ___SUKISU_KPM_H -#define ___SUKISU_KPM_H +#ifndef __SUKISU_KPM_H +#define __SUKISU_KPM_H + +#include +#include + +struct ksu_kpm_cmd { + __aligned_u64 arg2; + __aligned_u64 arg3; + __aligned_u64 arg4; + __aligned_u64 arg5; +}; int sukisu_handle_kpm(unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5); int sukisu_is_kpm_control_code(unsigned long arg2); +int do_kpm(void __user *arg); -// KPM控制代码 -#define CMD_KPM_CONTROL 28 -#define CMD_KPM_CONTROL_MAX 35 +#define KSU_IOCTL_KPM _IOC(_IOC_READ|_IOC_WRITE, 'K', 200, 0) -// 控制代码 +/* KPM Control Code */ +#define CMD_KPM_CONTROL 1 +#define CMD_KPM_CONTROL_MAX 10 -// prctl(xxx, 28, "PATH", "ARGS") -// success return 0, error return -N -#define SUKISU_KPM_LOAD 28 +/* Control Code */ +/* + * prctl(xxx, 1, "PATH", "ARGS") + * success return 0, error return -N + */ +#define SUKISU_KPM_LOAD 1 -// prctl(xxx, 29, "NAME") -// success return 0, error return -N -#define SUKISU_KPM_UNLOAD 29 +/* + * prctl(xxx, 2, "NAME") + * success return 0, error return -N + */ +#define SUKISU_KPM_UNLOAD 2 -// num = prctl(xxx, 30) -// error return -N -// success return +num or 0 -#define SUKISU_KPM_NUM 30 +/* + * num = prctl(xxx, 3) + * error return -N + * success return +num or 0 + */ +#define SUKISU_KPM_NUM 3 -// prctl(xxx, 31, Buffer, BufferSize) -// success return +out, error return -N -#define SUKISU_KPM_LIST 31 +/* + * prctl(xxx, 4, Buffer, BufferSize) + * success return +out, error return -N + */ +#define SUKISU_KPM_LIST 4 -// prctl(xxx, 32, "NAME", Buffer[256]) -// success return +out, error return -N -#define SUKISU_KPM_INFO 32 +/* + * prctl(xxx, 5, "NAME", Buffer[256]) + * success return +out, error return -N + */ +#define SUKISU_KPM_INFO 5 -// prctl(xxx, 33, "NAME", "ARGS") -// success return KPM's result value -// error return -N -#define SUKISU_KPM_CONTROL 33 +/* + * prctl(xxx, 6, "NAME", "ARGS") + * success return KPM's result value + * error return -N + */ +#define SUKISU_KPM_CONTROL 6 -// prctl(xxx, 34, buffer, bufferSize) -// success return KPM's result value -// error return -N -#define SUKISU_KPM_VERSION 34 +/* + * prctl(xxx, 7, buffer, bufferSize) + * success return KPM's result value + * error return -N + */ +#define SUKISU_KPM_VERSION 7 -#endif \ No newline at end of file +#endif diff --git a/kernel/kpm/super_access.c b/kernel/kpm/super_access.c index 236c39bf..9bb77798 100644 --- a/kernel/kpm/super_access.c +++ b/kernel/kpm/super_access.c @@ -13,7 +13,7 @@ #include #include #include -#include /* 包含 ARM64 重定位类型定义 */ +#include #include #include #include @@ -24,34 +24,37 @@ #include #include #include -#include "kpm.h" -#include "compact.h" #include #include +#include +#include +#include +#include +#include +#include <../fs/mount.h> +#include "kpm.h" +#include "compact.h" -// 结构体成员元数据 struct DynamicStructMember { - const char* name; + const char *name; size_t size; size_t offset; }; -// 结构体元数据(包含总大小) struct DynamicStructInfo { - const char* name; + const char *name; size_t count; size_t total_size; - struct DynamicStructMember* members; + struct DynamicStructMember *members; }; -// 定义结构体元数据的宏(直接使用 struct 名称) #define DYNAMIC_STRUCT_BEGIN(struct_name) \ static struct DynamicStructMember struct_name##_members[] = { #define DEFINE_MEMBER(struct_name, member) \ { \ .name = #member, \ - .size = sizeof(((struct struct_name*)0)->member), \ + .size = sizeof(((struct struct_name *)0)->member), \ .offset = offsetof(struct struct_name, member) \ }, @@ -64,19 +67,6 @@ struct DynamicStructInfo { .members = struct_name##_members \ }; -// ================================================================================== - -#include - -#define KERNEL_VERSION_6_1 KERNEL_VERSION(6, 1, 0) -#define KERNEL_VERSION_5_15 KERNEL_VERSION(5, 15, 0) -#define KERNEL_VERSION_6_12 KERNEL_VERSION(6, 12, 0) -#define KERNEL_VERSION_4_10 KERNEL_VERSION(4, 10, 0) - -#include <../fs/mount.h> -#include - -// 定义元数据 DYNAMIC_STRUCT_BEGIN(mount) DEFINE_MEMBER(mount, mnt_parent) DEFINE_MEMBER(mount, mnt) @@ -98,13 +88,11 @@ DYNAMIC_STRUCT_BEGIN(mnt_namespace) DEFINE_MEMBER(mnt_namespace, root) DEFINE_MEMBER(mnt_namespace, seq) DEFINE_MEMBER(mnt_namespace, mounts) -#if LINUX_VERSION_CODE < KERNEL_VERSION_5_15 +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) DEFINE_MEMBER(mnt_namespace, count) #endif DYNAMIC_STRUCT_END(mnt_namespace) -#include - #ifdef CONFIG_KPROBES DYNAMIC_STRUCT_BEGIN(kprobe) DEFINE_MEMBER(kprobe, addr) @@ -112,16 +100,13 @@ DYNAMIC_STRUCT_BEGIN(kprobe) DEFINE_MEMBER(kprobe, offset) DEFINE_MEMBER(kprobe, pre_handler) DEFINE_MEMBER(kprobe, post_handler) -#if LINUX_VERSION_CODE < KERNEL_VERSION_5_15 +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0) DEFINE_MEMBER(kprobe, fault_handler) #endif DEFINE_MEMBER(kprobe, flags) DYNAMIC_STRUCT_END(kprobe) #endif -#include -#include - DYNAMIC_STRUCT_BEGIN(vm_area_struct) DEFINE_MEMBER(vm_area_struct,vm_start) DEFINE_MEMBER(vm_area_struct,vm_end) @@ -130,9 +115,9 @@ DYNAMIC_STRUCT_BEGIN(vm_area_struct) DEFINE_MEMBER(vm_area_struct,vm_pgoff) DEFINE_MEMBER(vm_area_struct,vm_file) DEFINE_MEMBER(vm_area_struct,vm_private_data) - #ifdef CONFIG_ANON_VMA_NAME +#ifdef CONFIG_ANON_VMA_NAME DEFINE_MEMBER(vm_area_struct, anon_name) - #endif +#endif DEFINE_MEMBER(vm_area_struct, vm_ops) DYNAMIC_STRUCT_END(vm_area_struct) @@ -143,24 +128,18 @@ DYNAMIC_STRUCT_BEGIN(vm_operations_struct) DEFINE_MEMBER(vm_operations_struct, access) DYNAMIC_STRUCT_END(vm_operations_struct) -#include - DYNAMIC_STRUCT_BEGIN(netlink_kernel_cfg) DEFINE_MEMBER(netlink_kernel_cfg, groups) DEFINE_MEMBER(netlink_kernel_cfg, flags) DEFINE_MEMBER(netlink_kernel_cfg, input) -#if LINUX_VERSION_CODE < KERNEL_VERSION_6_12 DEFINE_MEMBER(netlink_kernel_cfg, cb_mutex) -#endif DEFINE_MEMBER(netlink_kernel_cfg, bind) DEFINE_MEMBER(netlink_kernel_cfg, unbind) -#if LINUX_VERSION_CODE < KERNEL_VERSION_6_1 +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) DEFINE_MEMBER(netlink_kernel_cfg, compare) #endif DYNAMIC_STRUCT_END(netlink_kernel_cfg) - -#include DYNAMIC_STRUCT_BEGIN(task_struct) DEFINE_MEMBER(task_struct, pid) DEFINE_MEMBER(task_struct, tgid) @@ -184,118 +163,116 @@ DYNAMIC_STRUCT_BEGIN(task_struct) #ifdef CONFIG_CGROUPS DEFINE_MEMBER(task_struct, cgroups) #endif -#if LINUX_VERSION_CODE > KERNEL_VERSION_4_10 #ifdef CONFIG_SECURITY DEFINE_MEMBER(task_struct, security) -#endif #endif DEFINE_MEMBER(task_struct, thread) DYNAMIC_STRUCT_END(task_struct) -// ===================================================================================================================== - #define STRUCT_INFO(name) &(name##_info) -static -struct DynamicStructInfo* dynamic_struct_infos[] = { +static struct DynamicStructInfo *dynamic_struct_infos[] = { STRUCT_INFO(mount), STRUCT_INFO(vfsmount), STRUCT_INFO(mnt_namespace), - #ifdef CONFIG_KPROBES - STRUCT_INFO(kprobe), - #endif +#ifdef CONFIG_KPROBES + STRUCT_INFO(kprobe), +#endif STRUCT_INFO(vm_area_struct), STRUCT_INFO(vm_operations_struct), STRUCT_INFO(netlink_kernel_cfg), STRUCT_INFO(task_struct) }; -// return 0 if successful -// return -1 if struct not defined -int sukisu_super_find_struct( - const char* struct_name, - size_t* out_size, - int* out_members -) { - size_t i; - for(i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { - struct DynamicStructInfo* info = dynamic_struct_infos[i]; - if(strcmp(struct_name, info->name) == 0) { - if(out_size) +/* + * return 0 if successful + * return -1 if struct not defined + */ +int sukisu_super_find_struct(const char *struct_name, size_t *out_size, int *out_members) +{ + for (size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { + struct DynamicStructInfo *info = dynamic_struct_infos[i]; + + if (strcmp(struct_name, info->name) == 0) { + if (out_size) *out_size = info->total_size; - if(out_members) + + if (out_members) *out_members = info->count; + return 0; } } + return -1; } EXPORT_SYMBOL(sukisu_super_find_struct); -// Dynamic access struct -// return 0 if successful -// return -1 if struct not defined -// return -2 if member not defined -int sukisu_super_access ( - const char* struct_name, - const char* member_name, - size_t* out_offset, - size_t* out_size -) { - size_t i; - for(i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { - struct DynamicStructInfo* info = dynamic_struct_infos[i]; - if(strcmp(struct_name, info->name) == 0) { - size_t i1; - for (i1 = 0; i1 < info->count; i1++) { +/* + * Dynamic access struct + * return 0 if successful + * return -1 if struct not defined + * return -2 if member not defined + */ +int sukisu_super_access(const char *struct_name, const char *member_name, size_t *out_offset, + size_t *out_size) +{ + for (size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { + struct DynamicStructInfo *info = dynamic_struct_infos[i]; + + if (strcmp(struct_name, info->name) == 0) { + for (size_t i1 = 0; i1 < info->count; i1++) { if (strcmp(info->members[i1].name, member_name) == 0) { - if(out_offset) + if (out_offset) *out_offset = info->members[i].offset; - if(out_size) + + if (out_size) *out_size = info->members[i].size; + return 0; } } + return -2; } } + return -1; } EXPORT_SYMBOL(sukisu_super_access); -// 动态 container_of 宏 #define DYNAMIC_CONTAINER_OF(offset, member_ptr) ({ \ (offset != (size_t)-1) ? (void*)((char*)(member_ptr) - offset) : NULL; \ }) -// Dynamic container_of -// return 0 if success -// return -1 if current struct not defined -// return -2 if target member not defined -int sukisu_super_container_of( - const char* struct_name, - const char* member_name, - void* ptr, - void** out_ptr -) { - if(ptr == NULL) { +/* + * Dynamic container_of + * return 0 if success + * return -1 if current struct not defined + * return -2 if target member not defined + */ +int sukisu_super_container_of(const char *struct_name, const char *member_name, void *ptr, + void **out_ptr) +{ + if (ptr == NULL) return -3; - } - size_t i; - for(i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { - struct DynamicStructInfo* info = dynamic_struct_infos[i]; - if(strcmp(struct_name, info->name) == 0) { - size_t i1; - for (i1 = 0; i1 < info->count; i1++) { + + for (size_t i = 0; i < (sizeof(dynamic_struct_infos) / sizeof(dynamic_struct_infos[0])); i++) { + struct DynamicStructInfo *info = dynamic_struct_infos[i]; + + if (strcmp(struct_name, info->name) == 0) { + for (size_t i1 = 0; i1 < info->count; i1++) { if (strcmp(info->members[i1].name, member_name) == 0) { - *out_ptr = (void*) DYNAMIC_CONTAINER_OF(info->members[i1].offset, ptr); + *out_ptr = (void *)DYNAMIC_CONTAINER_OF(info->members[i1].offset, ptr); + return 0; } } + return -2; } } + return -1; } EXPORT_SYMBOL(sukisu_super_container_of); - diff --git a/kernel/kpm/super_access.h b/kernel/kpm/super_access.h index 2514be89..4f02109d 100644 --- a/kernel/kpm/super_access.h +++ b/kernel/kpm/super_access.h @@ -6,34 +6,10 @@ #include "kpm.h" #include "compact.h" -// return 0 if successful -// return -1 if struct not defined -int sukisu_super_find_struct( - const char* struct_name, - size_t* out_size, - int* out_members -); - -// Dynamic access struct -// return 0 if successful -// return -1 if struct not defined -// return -2 if member not defined -int sukisu_super_access ( - const char* struct_name, - const char* member_name, - size_t* out_offset, - size_t* out_size -); - -// Dynamic container_of -// return 0 if success -// return -1 if current struct not defined -// return -2 if target member not defined -int sukisu_super_container_of( - const char* struct_name, - const char* member_name, - void* ptr, - void** out_ptr -); +extern int sukisu_super_find_struct(const char *struct_name, size_t *out_size, int *out_members); +extern int sukisu_super_access(const char *struct_name, const char *member_name, size_t *out_offset, + size_t *out_size); +extern int sukisu_super_container_of(const char *struct_name, const char *member_name, void *ptr, + void **out_ptr); #endif \ No newline at end of file diff --git a/kernel/supercalls.c b/kernel/supercalls.c index 77b5218c..35c1629b 100644 --- a/kernel/supercalls.c +++ b/kernel/supercalls.c @@ -542,6 +542,9 @@ static const struct ksu_ioctl_cmd_map ksu_ioctl_handlers[] = { { .cmd = KSU_IOCTL_DYNAMIC_MANAGER, .name = "SET_DYNAMIC_MANAGER", .handler = do_dynamic_manager, .perm_check = manager_or_root}, { .cmd = KSU_IOCTL_GET_MANAGERS, .name = "GET_MANAGERS", .handler = do_get_managers, .perm_check = manager_or_root}, { .cmd = KSU_IOCTL_ENABLE_UID_SCANNER, .name = "SET_ENABLE_UID_SCANNER", .handler = do_enable_uid_scanner, .perm_check = manager_or_root}, +#ifdef CONFIG_KPM + { .cmd = KSU_IOCTL_KPM, .name = "KPM_OPERATION", .handler = do_kpm, .perm_check = manager_or_root}, +#endif { .cmd = 0, .name = NULL, .handler = NULL, .perm_check = NULL} // Sentine }; diff --git a/kernel/supercalls.h b/kernel/supercalls.h index 023d6d3d..8fbbfd5e 100644 --- a/kernel/supercalls.h +++ b/kernel/supercalls.h @@ -5,6 +5,10 @@ #include #include "ksu.h" +#ifdef CONFIG_KPM +#include "kpm/kpm.h" +#endif + // Magic numbers for reboot hook to install fd #define KSU_INSTALL_MAGIC1 0xDEADBEEF #define KSU_INSTALL_MAGIC2 0xCAFEBABE