今天在练习linux字符驱动的sample程序时,发生了这么一件问题:
编译生成对应的ko文件之后,执行如下命令:
$ sudo insmod globalmem.ko
insmod: ERROR: could not insert module globalmem.ko: Cannot allocate memory
执行dmesg:
[ 222.277600] globalmem: module verification failed: signature and/or required key missing - tainting kernel
[ 222.277885] globalmem_devp alloc memory failed
[ 826.170703] globalmem_devp alloc memory failed
[ 1277.363984] globalmem_devp alloc memory failed
[ 2367.372724] globalmem_devp alloc memory failed
[ 2838.667398] globalmem_devp alloc memory failed
在网上调查了一下,这个问题指的是:
linux内核从3.7 开始加入模块签名检查机制,如果内核选项CONFIG_MODULE_SIG和CONFIG_MODULE_SIG_FORCE打开的话,当加载模块时内核会检查模块的签名,如果签名不存在或者签名内容不一致,会强制退出模块的加载。所以为模块签名就尤为重要。如果是内核选项CONFIG_MODULE_SIG_ALL打开,内核编译模块时会自动为模块签名。否则就要自己对模块签名。
怎样对驱动程序进行签名呢?添加到内核中,随着内核一起重新编译一下,应该是一种方案
但是现在不能重新编译内核,怎么用手动的方法添加一下签名呢?
经过调查,可以使用如下的方法来手动给驱动程序添加内核签名:
Manually signing modules
If you ever need to manually sign a kernel module, you can use the scripts/sign-file script available in the Linux kernel source tree. It requires four arguments:
The hash algorithm to use, such as sha512.
The private key location.
The certificate (which includes the public key) location.
The kernel module to sign.
In this case, the key pair does not need to be named signing_file.priv and such, nor do they need to be in the root of the Linux kernel source tree location.
root #perl /usr/src/linux/scripts/sign-file sha512 /usr/src/linux/kernel-signkey.priv /usr/src/linux/kernel-signkey.x509 vxlan.ko
For Kernel 4.3.3 or higher the perl script is no more. "sign-file" is an executable and its usage is as shown bellow, Note how the perl has been removed from the beginning of the command. The location of the certificates have also moved from the root source directory /usr/src/linux to the /usr/src/linux/certs directory and now uses signing-key.pem instead of signing-key.priv.
See command bellow:
root #/usr/src/linux/scripts/sign-file sha512 /usr/src/linux/certs/signing_key.pem /usr/src/linux/certs/signing_key.x509 vxlan.ko
Using the command for kernels prior to kernel version 4.3.3 on kernels after this version will produce error:
root #Unrecognized character \ ; marked by <-- HERE after <-- HERE near column 1 at /usr/src/linux/scripts/sign-file line 1.
另外一种方法是,将签名校验关闭,但是这个需要重编内核才能做到:
在Makefile文件中添加CONFIG_MODULE_SIG=n这条语句