调用kallsyms_lookup_name触发段错误的内核模块问题排查
问题:kprobe获取kallsyms_lookup_name指针后调用触发段错误
- 已知
kallsyms_lookup_name未被内核导出,但不少模块可通过技巧访问该函数 - 尝试用kprobe获取该函数指针,调用时触发段错误,已将代码简化为最小复现版本
- 内核版本:6.2.13-arch1-1,已开启
CONFIG_KALLSYMS与CONFIG_KALLSYMS_ALL配置项 - 试过修正指针偏移、更换获取方法、更换目标符号等方案,均无法解决问题
- dmesg错误提示:
Missing ENDBR: kallsyms_lookup_name+0x4/0xd0
复现代码
typedef unsigned long (*kallsymsFn)(const char *); // 日志工具函数,无它仍会触发段错误 static void log_symbol(void *symbol) { char *fname_lookup = kzalloc(NAME_MAX, GFP_KERNEL); if (!fname_lookup) return; sprint_symbol(fname_lookup, symbol); printk(KERN_INFO "Got '%s'.\n", fname_lookup); kfree(fname_lookup); } // 模块初始化函数 static int memflow_init(void) { struct kprobe kp = {0}; int ret = 0; kp.symbol_name = "kallsyms_lookup_name"; printk(KERN_INFO "Regsitered kprobe.\n"); ret = register_kprobe(&kp); if (ret < 0) return ret; kallsymsFn kallsyms = (kallsymsFn)kp.addr; log_symbol(kallsyms); unregister_kprobe(&kp); printk(KERN_INFO "Unregsietered kprobe.\n"); // 调用指针时触发段错误 log_symbol(kallsyms("kvm_lock")); return 0; }
关键dmesg日志
[ +3.821286] Regsitered kprobe. [ +0.000815] Got 'kallsyms_lookup_name+0x4/0xd0'. [ +0.048238] Unregsietered kprobe. [ +0.000003] traps: Missing ENDBR: kallsyms_lookup_name+0x4/0xd0 ... [ +0.000004] ? kallsyms_lookup_name+0x4/0xd0 [ +0.000012] memflow_init+0x82/0xc0 [memflow 21eb138fb4e295ab5c057ad4052116921bf19468] [ +0.000018] ? kallsyms_lookup_name+0x4/0xd0 [ +0.000008] ? __pfx_init_module+0x10/0x10 [memflow 21eb138fb4e295ab5c057ad4052116921bf19468]
内容的提问来源于stack exchange,提问作者Tacodiva
相关产品推荐
相关产品推荐

