Thursday, July 20, 2017

uefi - Login broken after 15.10 -> 16.04 LTS upgrade, related to NVIDIA driver


I have just updated my system from 15.10 to 16.04 via sudo do-release-upgrade. During this process, it displayed a screen with the following message:



Your system has UEFI Secure Boot enabled. UEFI Secure Boot is not compatible with the use of third-party drivers.


(...) Ubuntu will still be able to boot on your system but these third-party drivers will not be available for your hardware.


Disable UEFI Secure Boot? (yes | no)



Since the only third-party drivers that I am using are the NVIDIA graphics drivers, and since they have been working fine with Ubuntu 15.10 and Secure Boot enabled, I chose the "no" option here. I don't see why I should disable this for no good reason, and I assumed I can just reinstall the third-party driver via the system settings GUI after the update.


Alas, no. Upon reboot, my login screen appeared in very low resolution. When trying to log in it immediately throws me back to the login screen.


I have tried the following to fix the situation:


sudo apt-get purge nvidia*
sudo reboot

This leads to a purple screen and no reaction to Ctrl-Alt-F1. Logging in via SSH, I then did:


sudo apt-get install nvidia-current
sudo reboot

which again brings me the former scenario, with a very low-res login screen, and no way to log on.


This is a pretty bad upgrade experience. Did anyone else have this, and what can I do to fix this? (while keeping UEFI Secure Boot enabled) Thanks.



Through Ubuntu 15.10, Ubuntu's handling of Secure Boot stopped at GRUB -- that is, Ubuntu's version of Shim would launch Ubuntu's version of GRUB, which would launch any Linux kernel, whether or not it was signed. This was a very low bar of support for Secure Boot. For comparison, Fedora's GRUB would launch only signed Linux kernels, and Fedora's kernels, when they detected that Secure Boot was active, would load only signed kernel binaries. The intent of Fedora's more-robust Secure Boot support was to protect the system against "rogue" kernel modules, which could, in theory, take over the computer at a very low level. Ubuntu 15.10 and earlier lacked such protection.


Starting with 16.04, Ubuntu follows a stricter Secure Boot module, more like what Fedora's been doing for quite a while. This has security benefits, but as you've seen, it also has problems. If a third-party driver is not signed with a cryptographic key that the Ubuntu version of the Linux kernel recognizes as valid, it won't be loaded. This mostly impacts the closed-source Nvidia and AMD/ATI video drivers, but there are other drivers that can be affected, too.


There are (or might be) several workarounds to this problem:



  • Disable Secure Boot -- This is the easiest solution. You can do it by mucking with your firmware settings or (I think) by adjusting the Shim settings. (I'm not sure how to do it by tweaking Shim's settings, but I'm pretty sure that's possible.)

  • Don't use third-party kernel modules -- If you restrict yourself to open source drivers included in Ubuntu's standard Linux kernel, you should be fine, since Canonical signs all such drivers (AFAIK). Note that there should be pretty good Nvidia support using such drivers; your system probably fell back to sub-optimal drivers because it thought that the closed-source drivers were available. I don't know offhand how to switch from one to the other, but this question is about doing so with AMD/ATI drivers, so it may be a helpful starting point.

  • Sign the relevant modules -- In theory, signing the commercial modules yourself should get them working. Unfortunately, I don't have a pointer for instructions on how to do this, and in fact I'm not even entirely sure that it's possible to do this with a stock Ubuntu kernel; such a kernel might honor only modules that are signed with Canonical's key, which of course you don't possess.

  • Compile your own kernel -- If you compile your own kernel, you can set its options as you see fit, including loosening the restrictions on loading unsigned modules. You'd then need to sign the kernel with your own EFI key and add the public version of that key to your MOK list. Here's a question and answers about compiling your own kernel.

  • Switch to an older GRUB -- Because an older GRUB will launch unsigned kernels, you could install such a GRUB (from Ubuntu 15.10 or before) and have it launch an unsigned kernel. Note that maintaining that older GRUB would be likely to be a pain.

  • Switch to a boot loader that doesn't honor Secure Boot -- If you were to sign a boot loader like SYSLINUX or ELILO with your own key and add the public version of that key to your MOK list, that boot loader would ignore the Secure Boot settings, just like an older version of GRUB. You could then launch an unsigned kernel.


Note that the only two of these options that I'm 100% certain would work are to disable Secure Boot or to avoid third-party kernel modules. I avoid third-party kernel modules like the plague, so I have no personal experience with using them in a Secure Boot environment. Aside from disabling Secure Boot, building your own kernel might be the next-most-likely to work, followed by using an older GRUB or using a boot loader that doesn't honor Secure Boot. Building your own kernel was once common, but few people do that any more, and with modern kernels, the time investment to learn how to configure a kernel, not to mention actually doing so, can be significant. Using an older GRUB or another boot loader might be easier, but you'll need to know enough to be able to set that up. The easier way is likely to be to dual-boot with an older Ubuntu that you install second -- but be aware that Ubuntu 16.04 is likely to restore its GRUB at some point, whereupon you'll need to re-install the older Ubuntu's GRUB.


No comments:

Post a Comment

11.10 - Can't boot from USB after installing Ubuntu

I bought a Samsung series 5 notebook and a very strange thing happened: I installed Ubuntu 11.10 from a usb pen drive but when I restarted (...