This is due to Lenovo firmware not supporting EFI_VARIABLE_APPEND_WRITE. One of the shim developers has already rewritten MokManager.efi to work on affected Lenovo machines although it's unclear how long it will take this to be merged and pulled downstream by Ubuntu. You can follow the issue on shim's github issue tracker here.
If you can't wait (guilty as charged), you can compile shim and test it yourself.
If you don't have git
, gnu-efi
, libnss3-tools
and pesign
you'll need to install them first (more info on setting up an EFI development environment can be found here, I'm using a fairly new installation of Ubuntu 16.04, but it's possible that I've installed required other libraries/tools and forgotten about them--just look for errors when compiling and install any missing packages as neccesary):
sudo apt-get install git gnu-efi libnss3-tools pesign
Next, clone the branch of the git repository with the patch:
cd /src
git clone -b fix-lenovo-write https://github.com/lcp/shim.git
cd shim
Next you'll need to modify the Makefile (shim developers aren't using Ubuntu)
gedit Makefile
Make the following changes (credit to this post):
-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
Next you'll need to comment out an unused variable in shim.c:
gedit shim.c
Make the following change at line 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;
Compile shim:
make
Turn off secure boot temporarily:
sudo mokutil --disable-validation
Set your password, reboot, and follow the instructions to disable secure boot (password is tricky, it asks you to enter certain characters from the password rather than the whole thing).
Backup MokManager.efi and double check that it is backed up:
sudo mv /boot/efi/EFI/ubuntu/MokManager.efi /boot/efi/EFI/ubuntu/MokManager.efi.bak
sudo ls /boot/efi/EFI/ubuntu/
Move your patched version of MokManager to the EFI partition.
sudo mv ./MokManager.efi.signed /boot/efi/EFI/ubuntu/MokManager.efi
Enroll your key (modify as necessary depending on where you key is and what it's named):
sudo mokutil --import MOK.der
Set password, reboot and follow instructions to enroll MOK. It should succeed on Lenovo machines now.
Revert to the original version of MokManager and renable secure-boot:
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
Set password, reboot, follow instructions.
Sign your modules, load them with modprobe and enjoy!
Note: hopefully this will be officially patched in most distribution's repos fairly soon. This answer is an option for exceptionally impatient people who are comfortable building the patch from source and testing it. It worked on my machine (Lenovo P50) but that doesn't mean that it will work for everyone. If you aren't comfortable with building efi applications from source just wait for the patched version to hit the repos (at which point I'll update this answer).