2

由于我在 Ubuntu 16.04 上启用了安全启动,因此我需要签署 vboxdrv。

我使用以下方法创建签名密钥:

openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=Descriptive name/"

然后我签署模块:

sudo /usr/src/linux-headers-$(uname -r)/scripts/sign-file sha256 ./MOK.priv ./MOK.der $(modinfo -n vboxdrv)

但是,当我打电话时:

modinfo vboxdrv

模块未确认签名:

$ modinfo vboxdrv filename: /lib/modules/4.4.0-22-generic/updates/dkms/vboxdrv.ko version: 5.0.18_Ubuntu (0x00240000) license: GPL description: Oracle VM VirtualBox Support Driver author: Oracle Corporation srcversion: 316C2AE8082B5DFBAABE7EA depends:
vermagic: 4.4.0-22-generic SMP mod_unload modversions parm: force_async_tsc:force the asynchronous TSC mode (int)

然后我运行:

sudo mokutil --import MOK.der

然后重新启动,提示我导入机器所有者密钥。

但是,这会失败(无效的参数 (2))。

我认为这是由于模块没有提前签名,因为运行 modinfo vboxdrv 应该确认模块已签名。

4

1 回答 1

3

这是因为联想固件不支持 EFI_VARIABLE_APPEND_WRITE。一位 shim 开发人员已经重写了 MokManager.efi 以在受影响的联想机​​器上工作,尽管尚不清楚它需要多长时间才能被 Ubuntu 合并并拉到下游。您可以在此处关注 shim 的 github 问题跟踪器上的问题。

如果你不能等待(有罪的指控),你可以编译 shim 并自己测试它。

如果您没有git, gnu-efi,libnss3-tools并且pesign您需要先安装它们(有关设置 EFI 开发环境的更多信息可以在这里找到,我使用的是相当新的 Ubuntu 16.04 安装,但有可能我'已经安装了所需的其他库/工具并忘记了它们——只需在编译时查找错误并根据需要安装任何丢失的包):

sudo apt-get install git gnu-efi libnss3-tools pesign

接下来,使用补丁克隆 git 存储库的分支:

cd /src
git clone -b fix-lenovo-write https://github.com/lcp/shim.git
cd shim

接下来,您需要修改 Makefile(垫片开发人员不使用 Ubuntu)

gedit Makefile

进行以下更改(归功于此帖子):

-OBJCOPY_GTE224  = $(shell expr `$(OBJCOPY) --version |grep ^"GNU objcopy" | sed 's/^.version //g' | cut -f1-2 -d.` \>= 2.24)
+#OBJCOPY_GTE224  = $(shell expr `$(OBJCOPY) --version |grep ^"GNU objcopy" | sed 's/^.version //g' | cut -f1-2 -d.` \>= 2.24)
+OBJCOPY_GTE224  = 1

-LIB_PATH       = /usr/lib64
+LIB_PATH       = /usr/lib

-EFI_PATH       := /usr/lib64/gnuefi
+EFI_PATH       := /usr/lib

接下来,您需要在 shim.c 中注释掉一个未使用的变量:

gedit shim.c

在第 1118 行进行以下更改:

@@ -1118,7 +1118,7 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
        EFI_STATUS efi_status;
        char *buffer;
        int i;
-       unsigned int size;
+       //unsigned int size;
        EFI_IMAGE_SECTION_HEADER *Section;
        char *base, *end;
        PE_COFF_LOADER_IMAGE_CONTEXT context;

编译垫片:

make

暂时关闭安全启动:

sudo mokutil --disable-validation

设置您的密码,重新启动,然后按照说明禁用安全启动(密码很棘手,它要求您输入密码中的某些字符而不是整个内容)。

备份 MokManager.efi 并仔细检查它是否已备份:

sudo mv /boot/efi/EFI/ubuntu/MokManager.efi /boot/efi/EFI/ubuntu/MokManager.efi.bak
sudo ls /boot/efi/EFI/ubuntu/

将您的 MokManager 补丁版本移动到 EFI 分区。

sudo mv ./MokManager.efi.signed /boot/efi/EFI/ubuntu/MokManager.efi

注册您的密钥(根据您的密钥位置和名称进行必要的修改):

sudo mokutil --import MOK.der

设置密码,重启并按照说明注册 MOK。它现在应该在联想机器上成功了。

恢复到 MokManager 的原始版本并启用安全启动:

sudo mv /boot/efi/EFI/ubuntu/MokManager.efi ./MokManager.efi.signed
sudo mv /boot/efi/EFI/ubuntu/MokManager.efi.bak /boot/efi/EFI/ubuntu/MokManager.efi
sudo mokutil --enable-validation

设置密码,重新启动,按照说明进行操作。

签署您的模块,使用 modprobe 加载它们并享受!

注意:希望这将很快在大多数发行版的回购中正式修补。对于非常不耐烦的人来说,这个答案是一个选择,他们愿意从源代码构建补丁并对其进行测试。它适用于我的机器(联想 P50),但这并不意味着它适用于所有人。如果您不习惯从源代码构建 efi 应用程序,只需等待修补版本到达存储库(此时我将更新此答案)。

于 2016-07-09T07:21:30.643 回答