From 6a43e037faab2f3d084fce8b16d864f18b033a48 Mon Sep 17 00:00:00 2001 From: liqiang <liqiang64@huawei.com> Date: Mon, 17 Jun 2024 11:18:43 +0800 Subject: [PATCH] refactor syscall wrapper for aarch64, reduce the memory range to o be writable Signed-off-by: liqiang <liqiang64@huawei.com> --- qtfs/include/symbol_wrapper.h | 14 ++++++++++++-- qtfs/qtfs/syscall.c | 25 ++++++++++++------------- qtfs/qtfs_common/symbol_wrapper.c | 18 ++++++------------ 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/qtfs/include/symbol_wrapper.h b/qtfs/include/symbol_wrapper.h index cef2cd9..4ce500f 100644 --- a/qtfs/include/symbol_wrapper.h +++ b/qtfs/include/symbol_wrapper.h @@ -72,8 +72,18 @@ static inline int make_ro(unsigned long address) #ifdef __aarch64__ extern void (*update_mapping_prot)(phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot); -extern unsigned long start_rodata, end_rodata; -#define section_size (end_rodata - start_rodata) +static inline int make_rw(unsigned long address) +{ + update_mapping_prot(__pa_symbol(address & PAGE_MASK), (unsigned long)(address & PAGE_MASK), PAGE_SIZE, PAGE_KERNEL); + return 0; +} + +static inline int make_ro(unsigned long address) +{ + update_mapping_prot(__pa_symbol(address & PAGE_MASK), (unsigned long)(address & PAGE_MASK), PAGE_SIZE, PAGE_KERNEL_RO); + return 0; +} + #endif int qtfs_syscall_replace_start(void); diff --git a/qtfs/qtfs/syscall.c b/qtfs/qtfs/syscall.c index a02a225..7b139a4 100644 --- a/qtfs/qtfs/syscall.c +++ b/qtfs/qtfs/syscall.c @@ -441,22 +441,22 @@ int qtfs_syscall_init(void) symbols_origin[SYMBOL_SYSCALL_MOUNT] = qtfs_kern_syms.sys_call_table[__NR_mount]; symbols_origin[SYMBOL_SYSCALL_UMOUNT] = qtfs_kern_syms.sys_call_table[__NR_umount2]; symbols_origin[SYMBOL_SYSCALL_EPOLL_CTL] = qtfs_kern_syms.sys_call_table[__NR_epoll_ctl]; -#ifdef __x86_64__ + make_rw((unsigned long)qtfs_kern_syms.sys_call_table); + make_rw((unsigned long)qtfs_kern_syms.sys_call_table + PAGE_SIZE); +#ifdef __x86_64__ qtfs_kern_syms.sys_call_table[__NR_mount] = (unsigned long *)__x64_sys_qtfs_mount; qtfs_kern_syms.sys_call_table[__NR_umount2] = (unsigned long *)__x64_sys_qtfs_umount; qtfs_kern_syms.sys_call_table[__NR_epoll_ctl] = (unsigned long *)__x64_sys_qtfs_epoll_ctl; - make_ro((unsigned long)qtfs_kern_syms.sys_call_table); #endif #ifdef __aarch64__ - // disable write protection - update_mapping_prot(__pa_symbol(start_rodata), (unsigned long)start_rodata, section_size, PAGE_KERNEL); qtfs_kern_syms.sys_call_table[__NR_mount] = (unsigned long *)__arm64_sys_qtfs_mount; qtfs_kern_syms.sys_call_table[__NR_umount2] = (unsigned long *)__arm64_sys_qtfs_umount; qtfs_kern_syms.sys_call_table[__NR_epoll_ctl] = (unsigned long *)__arm64_sys_qtfs_epoll_ctl; - // enable write protection - update_mapping_prot(__pa_symbol(start_rodata), (unsigned long)start_rodata, section_size, PAGE_KERNEL_RO); #endif + // enable write protection + make_ro((unsigned long)qtfs_kern_syms.sys_call_table); + make_ro((unsigned long)qtfs_kern_syms.sys_call_table + PAGE_SIZE); qtfs_debug("qtfs use qtfs_mount instead of mount and umount\n"); qtfs_debug("qtfs use qtfs_epoll_ctl instead of epoll_ctl\n"); return 0; @@ -464,23 +464,22 @@ int qtfs_syscall_init(void) int qtfs_syscall_fini(void) { -#ifdef __x86_64__ make_rw((unsigned long)qtfs_kern_syms.sys_call_table); + make_rw((unsigned long)qtfs_kern_syms.sys_call_table + PAGE_SIZE); +#ifdef __x86_64__ qtfs_kern_syms.sys_call_table[__NR_mount] = (unsigned long *)symbols_origin[SYMBOL_SYSCALL_MOUNT]; qtfs_kern_syms.sys_call_table[__NR_umount2] = (unsigned long *)symbols_origin[SYMBOL_SYSCALL_UMOUNT]; qtfs_kern_syms.sys_call_table[__NR_epoll_ctl] = (unsigned long *)symbols_origin[SYMBOL_SYSCALL_EPOLL_CTL]; - /*set mkdir syscall to the original one */ - make_ro((unsigned long)qtfs_kern_syms.sys_call_table); #endif #ifdef __aarch64__ - // disable write protection - update_mapping_prot(__pa_symbol(start_rodata), (unsigned long)start_rodata, section_size, PAGE_KERNEL); qtfs_kern_syms.sys_call_table[__NR_mount] = (unsigned long *)symbols_origin[SYMBOL_SYSCALL_MOUNT]; qtfs_kern_syms.sys_call_table[__NR_umount2] = (unsigned long *)symbols_origin[SYMBOL_SYSCALL_UMOUNT]; qtfs_kern_syms.sys_call_table[__NR_epoll_ctl] = (unsigned long *)symbols_origin[SYMBOL_SYSCALL_EPOLL_CTL]; - // enable write protection - update_mapping_prot(__pa_symbol(start_rodata), (unsigned long)start_rodata, section_size, PAGE_KERNEL_RO); #endif + // enable write protection + make_ro((unsigned long)qtfs_kern_syms.sys_call_table); + make_ro((unsigned long)qtfs_kern_syms.sys_call_table + PAGE_SIZE); + qtfs_info("qtfs mount umount and epoll_ctl resumed\n"); atomic_inc(&replace_available); return 0; diff --git a/qtfs/qtfs_common/symbol_wrapper.c b/qtfs/qtfs_common/symbol_wrapper.c index 84c1bd5..5ceaf5f 100644 --- a/qtfs/qtfs_common/symbol_wrapper.c +++ b/qtfs/qtfs_common/symbol_wrapper.c @@ -55,7 +55,6 @@ struct pt_regs; #endif #ifdef __aarch64__ void (*update_mapping_prot)(phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot); -unsigned long start_rodata, end_rodata; // symbols not finded in sys call table enum qtfs_sym_a64 { @@ -132,9 +131,7 @@ int qtfs_kallsyms_hack_init(void) #ifdef __aarch64__ update_mapping_prot = (void *)qtfs_kallsyms_lookup_name("update_mapping_prot"); - start_rodata = (unsigned long)qtfs_kallsyms_lookup_name("__start_rodata"); - end_rodata = (unsigned long)qtfs_kallsyms_lookup_name("__end_rodata"); - if (update_mapping_prot == NULL || (void *)start_rodata == NULL || (void *)end_rodata == NULL) { + if (update_mapping_prot == NULL) { qtfs_err("failed to init memory protect handler"); return -1; } @@ -170,33 +167,30 @@ int qtfs_syscall_replace_start(void) } symbols_origin[SYMBOL_SYSCALL_CONNECT] = qtfs_kern_syms.sys_call_table[__NR_connect]; + make_rw((unsigned long)&qtfs_kern_syms.sys_call_table[__NR_connect]); #ifdef __x86_64__ - make_rw((unsigned long)qtfs_kern_syms.sys_call_table); qtfs_kern_syms.sys_call_table[__NR_connect] = (unsigned long *)__x64_sys_qtfs_connect; - make_ro((unsigned long)qtfs_kern_syms.sys_call_table); #endif #ifdef __aarch64__ - update_mapping_prot(__pa_symbol(start_rodata), (unsigned long)start_rodata, section_size, PAGE_KERNEL); qtfs_kern_syms.sys_call_table[__NR_connect] = (unsigned long *)__arm64_sys_qtfs_connect; - update_mapping_prot(__pa_symbol(start_rodata), (unsigned long)start_rodata, section_size, PAGE_KERNEL_RO); #endif + make_ro((unsigned long)&qtfs_kern_syms.sys_call_table[__NR_connect]); return 0; } void qtfs_syscall_replace_stop(void) { + make_rw((unsigned long)&qtfs_kern_syms.sys_call_table[__NR_connect]); #ifdef __x86_64__ - make_rw((unsigned long)qtfs_kern_syms.sys_call_table); qtfs_kern_syms.sys_call_table[__NR_connect] = (void *)qtfs_kallsyms_lookup_name("__x64_sys_connect"); - make_ro((unsigned long)qtfs_kern_syms.sys_call_table); #endif #ifdef __aarch64__ - update_mapping_prot(__pa_symbol(start_rodata), (unsigned long)start_rodata, section_size, PAGE_KERNEL); qtfs_kern_syms.sys_call_table[__NR_connect] = (void *)qtfs_kallsyms_lookup_name("__arm64_sys_connect"); - update_mapping_prot(__pa_symbol(start_rodata), (unsigned long)start_rodata, section_size, PAGE_KERNEL_RO); #endif + make_ro((unsigned long)&qtfs_kern_syms.sys_call_table[__NR_connect]); + atomic_inc(&replace_available); } -- 2.37.1 (Apple Git-137.1)