项目的一个需求,需要通过符号地址查找函数kallsyms_lookup_name获取内核模块函数的地址,意外发现了一个bug,

这个bug已经在高版本修复,至少在4.18.0内核里已经修复。

  开始直接查找模块的某个函数,比如helloworld模块的hello_test函数,可以直接调用kallsyms_lookup_name("hello_test"),

获得helloworld模块的hello_test函数的地址。

  但是,如果内核符号表里面有重名的函数,这种方法获取的符号地址可能不是想要的。内核提供了一种指定内核模块

查找符号地址的方法,调用形式如下:

  kallsyms_lookup_name("helloworld:hello_test")

  模块加载后,直接down机了,crash core文件后,找到异常代码行如下:

  

 

 

vmcore-dmesg.txt文件中异常信息:

[  398.898146] BUG: unable to handle kernel paging request at ffffffffc03ef0a5
[  398.898628] IP: [<ffffffff81109d49>] module_kallsyms_lookup_name+0x39/0xc0
[  398.899100] PGD 1a16067 PUD 1a18067 PMD 1039d02067 PTE 8000001b9439b061

反汇编后,显示出错代码行:

crash> dis -l FFFFFFFF81109D49
/usr/src/debug/kernel-3.10.0-693.21.1.el7/linux-3.10.0-693.21.1.el7.x86_64/kernel/module.c: 3776

  从代码来看,module_kallsyms_lookup_name输入参数为const char*类型,其内容是不可修改的,

此函数尝试把‘:’符号修改为‘\0’,就会出现访问异常。

  看来内核代码作者也会犯基本的编程错误:)