KVM:模块验证失败:签名和/或所需的密钥丢失 - 污染内核。

34

我正在使用 Ubuntu 14.04 LTS 和内核版本 3.13.11.4
我尝试加载已打补丁的 KVM 模块 kvmkvm-intel,但遇到以下错误

kvm: 模块验证失败:签名和/或所需密钥丢失 - 污染内核
以及 kvm: 模块污点错误,不创建跟踪事件.

所使用的源代码是创建当前运行镜像的相同源代码。
我检查了符号,并确保错误不是由于在导出函数的打补丁文件中未包含 EXPORT_SYMBOL_GPL() 引起的。

我还看到一些关于不同内核版本导致此错误的内容,但我使用的是与创建打补丁 kvm 模块时相同的源代码构建的内核。
一切都编译完毕而没有警告。 谢谢帮忙!

4个回答

33

不需要重新配置内核,只需在模块自己的Makefile顶部添加一行 CONFIG_MODULE_SIG=n 即可解决此错误 (module verification failed)。

CONFIG_MODULE_SIG=n

# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
    obj-m := hello.o

# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)

default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif

4
你试过了吗?我发现添加"CONFIG_MODULE_SIG=n"后,仍会打印"module verification failed: signature and/or required key missing - tainting kernel"信息。 - Nan Xiao
2
我同时使用Suse(3.12)和RHEL 7(3.10.0),结果相同。我也在kernelnewbies.org上讨论了这个问题,但目前似乎没有令人满意的答案。你能帮忙看看这个邮件线程吗?非常感谢! - Nan Xiao
2
这对我来说在不同的模块上绝对有效:rtl8188和Ubuntu 15.1 - JohnAllen
5
糟糕的回答!定义 CONFIG_MODULE_SIG=n 会导致模块编译时 module.h 解析错误,从而造成内核和模块结构布局的分歧。为什么这里有那么多赞? - Ilya Matveychikov
2
@IlyaMatveychikov 我记得当我在Ubuntu 14.04上构建Linux设备驱动程序中的一些示例模块时,尝试解决此问题。我发现它在不进行任何更改的情况下适用于Ubuntu默认内核。我猜你知道更好的方法来解决这个问题 - 你介意发布一个答案来修复这个问题吗?我猜其他人也遇到了这个问题(虽然它可能不适用于更新的内核 - 不确定)。 - artm
显示剩余5条评论

21
进入内核源代码目录并执行以下操作(例如):
./scripts/sign-file sha512 ./signing_key.priv ./signing_key.x509 /lib/modules/3.10.1/kernel/drivers/char/my_module.ko

对于内核版本4.4.*,密钥的位置应如下所示:
./scripts/sign-file sha512 ./certs/signing_key.pem ./certs/signing_key.x509 path/to/your/kernel/module.ko 

检查你的内核使用的摘要算法,方法是打开`.config`文件并在`CONFIG_MODULE_SIG`配置值中阅读它。
CONFIG_MODULE_SIG=y CONFIG_MODULE_SIG_ALL=y CONFIG_MODULE_SIG_SHA512=y CONFIG_MODULE_SIG_HASH="sha512"

注意:如果您正在使用未构建的现有内核,请通过查看相应的配置文件(主要位于/proc/*或/boot/*)来检查内核使用的摘要算法。对于Ubuntu来说,在/boot/config-$(uname -r)中。

2
这应该是答案,它签署了自定义构建模块。 - TerrenceSun
我刚刚安装了CentOS9,但在/usr/src/kernel目录下找不到certs/signing_key.pem和./certs/signing_key.x509。 - clevertension
我刚刚安装了CentOS 9,但在/usr/src/kernel目录下找不到certs/signing_key.pem和./certs/signing_key.x509这两个文件。 - undefined

16
似乎您的系统供应商已经在内核上启用了内核模块签名验证,这意味着它不会加载供应商未签名的任何模块。换句话说,您的补丁模块没有被正确签名,内核将拒绝加载它。
这么做的目的是为了防止恶意软件和rootkit加载恶意内核模块。
我建议您联系供应商。您的平台可能有一个选项可以禁用签名检查。否则,您的供应商可能能够为您签署该模块。您甚至可能拥有密钥和签名验证算法的详细信息,并可以自行签署它。
如果不知道您运行的平台,很难给出更具体的建议。

1
我使用了这个页面来对我的模块进行签名:http://wiki.gentoo.org/wiki/Signed_kernel_module_support。 - user2743

13

一般而言,如果您正在构建自定义内核并使用 make oldconfig 命令,则会从 /boot 复制现有的 config-* 文件。现在,大多数内核模块需要由 Linux 供应商签名。因此,在编译内核之前,请编辑 .config 文件并禁用 CONFIG_MODULE_SIG_ALL 和 CONFIG_MODULE_SIG。

CONFIG_MODULE_SIG=n
CONFIG_MODULE_SIG_ALL=n
# CONFIG_MODULE_SIG_FORCE is not set 
# CONFIG_MODULE_SIG_SHA1 is not set
# CONFIG_MODULE_SIG_SHA224 is not set
# CONFIG_MODULE_SIG_SHA256 is not set
# CONFIG_MODULE_SIG_SHA384 is not set

2
所以这里需要重新编译内核吗?或许这是一个愚蠢的问题,但我是Linux的初学者,重新编译内核对我来说就像红灯一样。我只是想让以太网连接正常工作。看起来我需要额外的软件包来完成这个任务(但我没有,因为WiFi也不工作)。 - rank1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接