2013/06/03

Kernel Module Insert Failure: disagrees about version of symbol module_layout, Unknown symbol __fentry__ and __stack_chk_fail





由於沒有我家那台 NAS 的 kernel 的 source code 及 config 所以在編一些 kernel module 時發生了一堆問題,這篇文章整理了發生的問題。

在開始之前,我要大力抨擊我用的這家 NAS 公司,請他們儘快將 kernel source code 公佈及把 /proc/config.gz 打開,這不只是為 GPL 的問題,也是對我們這些玩家的友善表現。

Q1: disagrees about version of symbol module_layout



喔,版本不合,先看一下自己編出來 module version

$ modprobe --dump-modversions ./vboxguest.ko | grep module_layout
0x8495e121 module_layout

隨便找個 "they" module 來參考

$ modprobe --dump-modversion /lib/modules/3.1.2/ath.ko | grep module_layout
0x2b701e76 module_layout

至此,大概就知道要把 module_layout 的版本改成 0x2b701e76。推薦使用 hte 這套軟體,Ubuntu 就 apt-get install ht。hte 怎麼用?先用它找到 ELF section __versions 的 offset,之後再直接 goto 到那個位置,最後修改結果如下:

$ readelf -x __versions vboxguest.ko 

Hex dump of section '__versions':
0x00000000 21e19584 00000000 6d6f6475 6c655f6c !.......module_l
0x00000010 61796f75 74000000 00000000 00000000 ayout...........
0x00000020 00000000 00000000 00000000 00000000 ................
0x00000030 00000000 00000000 00000000 00000000 ................

題外話,module 在編譯時除了放 version 外,還有 info,它就放在 .modinfo section。

$ modinfo ./vboxguest.ko 
filename:       ./vboxguest.ko
version:        4.1.12_Ubuntu
license:        GPL
description:    Oracle VM VirtualBox Guest Additions for Linux Module
author:         Oracle Corporation
srcversion:     9E8128FBCF872CA4EA6525A
alias:          pci:v000080EEd0000CAFEsv00000000sd00000000bc*sc*i*
depends:        
vermagic:       3.2.0-41-generic SMP mod_unload modversions 

$ readelf -x .modinfo vboxguest.ko 

Hex dump of section '.modinfo':
0x00000000 76657273 696f6e3d 342e312e 31325f55 version=4.1.12_U
0x00000010 62756e74 75006c69 63656e73 653d4750 buntu.license=GP
0x00000020 4c006465 73637269 7074696f 6e3d4f72 L.description=Or
0x00000030 61636c65 20564d20 56697274 75616c42 acle VM VirtualB
0x00000040 6f782047 75657374 20416464 6974696f ox Guest Additio
0x00000050 6e732066 6f72204c 696e7578 204d6f64 ns for Linux Mod
0x00000060 756c6500 61757468 6f723d4f 7261636c ule.author=Oracl
0x00000070 6520436f 72706f72 6174696f 6e007372 e Corporation.sr
0x00000080 63766572 73696f6e 3d394538 31323846 cversion=9E8128F
0x00000090 42434638 37324341 34454136 35323541 BCF872CA4EA6525A
0x000000a0 00616c69 61733d70 63693a76 30303030 .alias=pci:v0000
0x000000b0 38304545 64303030 30434146 45737630 80EEd0000CAFEsv0
0x000000c0 30303030 30303073 64303030 30303030 0000000sd0000000
0x000000d0 3062632a 73632a69 2a006465 70656e64 0bc*sc*i*.depend
0x000000e0 733d0076 65726d61 6769633d 332e322e s=.vermagic=3.2.
0x000000f0 302d3431 2d67656e 65726963 20534d50 0-41-generic SMP
0x00000100 206d6f64 5f756e6c 6f616420 6d6f6476  mod_unload modv
0x00000110 65727369 6f6e7320 00                ersions .



Q2: Unknown symbol __fentry__ (err 0)



錯誤訊息

[13101.595874] xxxxx: Unknown symbol __fentry__ (err 0)

Unknown symbol 的問題,我在前幾篇文章有提到解法,但是 __fentry__ 卻在 /proc/kallsyms 裡找不到。

這個追一下 kernel source code 可以發現跟 ktrace 有關,把 kernel config CONFIG_KTRACE 關掉即可。


Q3: Unknown symbol __stack_chk_fail (err 0)



錯誤訊息

[13102.472194] xxxxx: Unknown symbol __stack_chk_fail (err 0)

這個問題有玩 stack overflow 過的來都會很熟悉,這個編 module 時加個 CFLAGS += -fno-stack-protector 就行。估計是廠商為了 downsize kernel 所以關了一堆東西。

Reference

  • 解析 Linux 內核可裝載模塊的版本檢查機制, http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmodules/
  • 有人遇到过 Unknown symbol __stack_chk_fail 这样的问题么, http://bbs.chinaunix.net/thread-2049091-1-1.html
  • 模塊不能插入的問題解決 disagrees about version of symbol struct_module, http://lagignition.blog.163.com/blog/static/12873002320109135292479/

(真是一個失敗的標題)

No comments: