## -*- mode: moinmoin -*- ## eg '== GNU C Library buffer overflow in __nss_hostname_digits_dots() (CVE-2015-0235 aka GHOST) ==' == Multiple Vulnerabilities in GNU GRUB (CVE-2020-14372, CVE-2020-25632, CVE-2020-25647, CVE-2020-27749, CVE-2020-27779, CVE-2021-20225, CVE-2021-20233, CVE-2021-3418) == ## Description. Should contain a high level description and optional low level description along with how the vulnerability can be exploited and the result of exploitation It was discovered that multiple vulnerabilities existed in GNU GRUB, that could potentially lead to the ability to bypass UEFI Secure Boot restrictions. A local attacker with administrative privileges (or with physical access to the system) could use this issue to circumvent GRUB2 module signature checking, resulting in the ability to load arbitrary GRUB2 modules that have not been signed by a trusted authority and hence bypass UEFI Secure Boot. The following CVEs were assigned for these various vulnerabilities: || '''CVE''' || '''Description''' || || [[ https://ubuntu.com/security/CVE-2020-14372 | CVE-2020-14372 ]] || grub2: acpi command allows privileged user to load crafted ACPI tables when secure boot is enabled. || || [[ https://ubuntu.com/security/CVE-2021-20233 | CVE-2021-20233 ]] || grub2: memory corruption in menu rendering. || || [[ https://ubuntu.com/security/CVE-2020-25632 | CVE-2020-25632 ]] || grub2: use-after-free in rmmod command. || || [[ https://ubuntu.com/security/CVE-2020-27779 | CVE-2020-27779 ]] || grub2: cutmem command allows privileged user to disable certain memory regions thereby disabling Secure Boot protections. || || [[ https://ubuntu.com/security/CVE-2021-20225 | CVE-2021-20225 ]] || grub2: option parser contains a heap buffer which allows a privileged user to execute arbitrary code when secure boot is enabled. || || [[ https://ubuntu.com/security/CVE-2020-27749 | CVE-2020-27749 ]] || grub2: stack buffer overflow in handling command line options allows a privileged user to execute arbitrary code when secure boot is enabled. || || [[ https://ubuntu.com/security/CVE-2021-3418 | CVE-2021-3418 ]] || grub2: GRUB 2.05 reintroduced CVE-2020-15705, grub fails to validate kernel signatures when booted directly without shim, allowing secure boot to be bypassed. (This issue did not affect grub as distributed in Ubuntu.) || || [[ https://ubuntu.com/security/CVE-2020-25647 | CVE-2020-25647 ]] || grub2: memory corruption from crafted USB device descriptors allows a local user to execute arbitrary code when secure boot is enabled. (The GRUB2 USB module is disabled in the signed Ubuntu EFI image, thus Ubuntu is not affected.) || === Remediation Plans === Correcting the issues discovered in GRUB2 is multi-step process due to UEFI Secure Boot to ultimately ensure that vulnerable versions of grub can no longer be loaded. ==== GRUB updates ==== As part of this update, to ensure a unified approach across all Ubuntu releases the version of grub for UEFI systems used in older Ubuntu versions is updated so that a single GRUB2 version can be used for all releases. We will do this by: * adding additional source package `grub2-unsigned` which generates a single version of a GRUB2 EFI binary * binary copying that `grub2-unsigned` source package across all older Ubuntu releases. * modifying the `grub2-signed` package to include the archive signed binary EFI GRUB2 component produced from the `grub2-unsigned` package * publishing a `grub2` update that contains solely packaging changes to permit the successful upgrade and installation of the `grub-efi-amd64-signed` binary package produced by the `grub2-signed` source package. Because of the complexities of the changes to GRUB2 itself (over 100 patches to GRUB2 upstream) as well as the packaging changes above, we will first be publishing the GRUB2 updates via the SRU -proposed process to get more widespread testing before landing the updates in the updates or security pockets. Please consider helping to test these updates; [[ https://bugs.launchpad.net/ubuntu/+source/grub2-unsigned/+bug/1917509 | Launchpad Bug 1917509 ]] can be used to report feedback. Because Secure Boot does not apply to BIOS based boot environments, we will not be publishing updates for GRUB2 on those systems. ==== Shim updates ==== As a reminder, shim is a small program that UEFI firmware boots into which verifies the validity of GRUB2 and then hands off the boot process to GRUB2. The shim binary is signed by Microsoft's CA. As part of the update process, the [[ https://github.com/rhboot/shim/ | shim upstream ]] has incorporated two separate revocation mechanisms, a vendor specific revocation database (DBX) as well as the [[ https://github.com/rhboot/shim/blob/main/SBAT.md | Secure Boot Advanced Targeting (SBAT) ]] scheme. Because of this, we will be publishing an update to shim as well; however, due to the complex set of changes to shim upstream, updates for shim will arrive at a later point. Important: note that applying shim updates when they arrive *without* applying the GRUB2 updates will result in an unsuccessful boot while under UEFI Secure Boot. ==== fwupd updates ==== Because of the changes in shim and GRUB2 adding SBAT support, fwupd (the firmware management utility) will also need an update to attach an SBAT section to the binary. This update will also come later. ==== ISO and other image respins ==== Once GRUB2, fwupd, and shim updates have all landed as updates in the Ubuntu archive, we will then re-spin ISO images as well as cloud images, where necessary. ==== Revocations ==== As part of the update process, there will be two sets of revocations: * Revoking all prior signed shims, via the [[ https://uefi.org/revocationlistfile | UEFI DBX revocation list ]] * Revoking the vulnerable GRUB2 binaries published since the [[ https://wiki.ubuntu.com/SecurityTeam/KnowledgeBase/GRUB2SecureBootBypass | BootHole vulnerabilities ]] were addressed. For the [[ SecurityTeam/KnowledgeBase/GRUB2SecureBootBypass | BootHole vulnerabilities ]], the 2012 Ubuntu signing key and two GRUB2 binaries were included in the UEFI DBX revocation list published in August 2020. With this update, we are instead pushing those into the vendor DBX revocation list to be included in the shim binary, along with revocation hashes for all signed GRUB2 binaries published since the Boot\Hole fixes were published (i.e. to include all GRUB2 binaries vulnerable to the set of CVES included here; these were signed with our newer 2017 Archive signing key). All older signed shim binaries will be included as part of the upcoming UEFI DBX revocation list update. Additionally, we are including in our vendor DBX revocation list the set of signed kernels that were vulnerable to [[ https://ubuntu.com/security/CVE-2020-15780 | CVE-2020-15780 ]] and [[ https://ubuntu.com/security/CVE-2019-20908 | CVE-2019-20908 ]] which allowed Secure Boot bypass. ==== Final Steps to Mitigation ==== Once all the pieces above have landed and things have settled, the UEFI DBX revocation list will be published in the Ubuntu Archive as an update to the [[ https://launchpad.net/ubuntu/+source/secureboot-db | secureboot-db package ]]. Again the ordering of the application of updates is important! In particular, the UEFI DBX revocation list is not revertible from firmware, and if the other pieces of the boot process are not in place, applying it in isolation can result in systems not bootable under Secure Boot. Dual-boot and multi-boot users need to take special care to update all their operating systems before installing DBX updates, whether received from Ubuntu, another operating system, or via the UEFI Forum. Updating the DBX list is similar to a BIOS update: Secure Boot is a feature of the motherboard and is shared in common among all operating systems on the computer. An update from another operating system may include DBX updates that will prevent you from booting unrelated operating systems. We expect other operating systems to release staggered updates that will provide new shim and GRUB bootloaders before they release DBX updates. We do not know when other operating system vendors will release DBX updates. Please plan to boot into every operating system on your multi-boot systems and install updates as soon as your other operating system distributions publish updates for this issue. === Fixed Versions === ## Versions section should include: ## - version fixed in upstream ## - version first introduced in upstream (if applicable) ## - version fixed in Ubuntu ## - reference to the USN This issue was fixed in grub2 in 2.06. Ubuntu 14.04 ESM, 16.04 LTS, 18.04 LTS, 20.04 LTS, and 20.10 were affected. A fixed version of grub2 was included with the Ubuntu 21.04 release. To address the issue, ensure that the appropriate versions of the `grub-efi-amd64-signed` or `grub-efi-arm64-signed` from the [[ https://launchpad.net/ubuntu/+source/grub2-signed | `grub2-signed` ]] source package are installed. || '''Release''' || '''Base Package and Version''' || '''Signed Version''' || '''Status''' || || 21.04 || [[ https://launchpad.net/ubuntu/+source/grub2-unsigned/2.04-1ubuntu42 | grub2-unsigned 2.04-1ubuntu42 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.164 | grub2-signed 1.164 ]] || published in Ubuntu 21.04 || || 20.10 || [[ https://launchpad.net/ubuntu/+source/grub2-unsigned/2.04-1ubuntu44.2 | grub2-unsigned 2.04-1ubuntu44.2 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.167.2 | grub2-signed 1.167.2 ]] || Published in [[ https://ubuntu.com/security/notices/USN-4992-1 | groovy-security ]] || || 20.04 LTS || [[ https://launchpad.net/ubuntu/+source/grub2-unsigned/2.04-1ubuntu44.2 | grub2-unsigned 2.04-1ubuntu44.2 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.167.2 | grub2-signed 1.167.2 ]] || Published in [[ https://ubuntu.com/security/notices/USN-4992-1 | focal-security ]] || || 18.04 LTS || [[ https://launchpad.net/ubuntu/+source/grub2-unsigned/2.04-1ubuntu44.1.2 | grub2-unsigned 2.04-1ubuntu44.1.2 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.167~18.04.5 | grub2-signed 1.167~18.04.5 ]] || Published in [[ https://ubuntu.com/security/notices/USN-4992-1 | bionic-security ]] || || 16.04 LTS || [[ https://launchpad.net/ubuntu/+source/grub2-unsigned/2.04-1ubuntu44.1.2 | grub2-unsigned 2.04-1ubuntu44.1.2 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.167~16.04.6 | grub2-signed 1.167~16.04.6 ]] || Published in xenial-updates || || 14.04 ESM || [[ https://launchpad.net/ubuntu/+source/grub2-unsigned/2.04-1ubuntu42 | grub2-unsigned 2.04-1ubuntu42 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.164 | grub2-signed 1.164 ]] || Unpublished || ## Timeline. Should include at a minimum: ## - when Ubuntu was notified ## - when USN was issued ==== Timeline ==== * 2021-03-02: Issue is made public ## ==== Public Cloud Image updates ==== * Amazon AWS: * Windows Azure: * Google Compute Engine: * Ubuntu Core Images: === References === * https://lists.gnu.org/archive/html/grub-devel/2021-03/msg00007.html * https://discourse.ubuntu.com/t/grub2-secureboot-bypass-2021-and-one-grub/21200 * https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1917509 * https://access.redhat.com/security/vulnerabilities/RHSB-2021-003 * https://www.debian.org/security/2021-GRUB-UEFI-SecureBoot * https://www.suse.com/support/kb/doc/?id=000019892 === Recovery === In the unlikely case that updating `grub2`/`grub2-signed` results in boot failure, the system can be recovered by downgrading `grub2`/`grub2-signed` from a separate running Ubuntu session. In the case of a physical machine, this can be done via the bootable Ubuntu Live CD / USB installer. In the case of a machine in the cloud, a separate instance on the same cloud availability-zone is required. In both cases, the final steps are the same - mount the root volume / device from the affected system into the livecd / separate cloud instance, chroot into this and use `apt` to downgrade `grub2`/`grub2-signed`: ==== Prepare the chroot ==== Preparing the chroot will be different depending on if this is a physical install or cloud instance. ===== Physical machine ===== 1. [[ https://ubuntu.com/tutorials?topic=desktop | Create a bootable Ubuntu CD/DVD/USB image ]] and then when booting this, select ‘Try Ubuntu without installing’. You can find current installation media at http://releases.ubuntu.com/ and old installation media at http://old-releases.ubuntu.com/releases/. 2. Within the livecd environment, mount the root partition from the affected disk as well as various ephemeral file-systems, and chroot into it: {{{ $ sudo mount $ROOT_PARTITION /mnt # see with ‘gdisk -l /dev/ $ for i in /sys /proc /run /dev /dev/pts ; do sudo mount --bind "$i" "/mnt$i"; done $ sudo mv /mnt/etc/resolv.conf /mnt/etc/resolv.conf.bak # will restore later $ sudo cp -L /etc/resolv.conf /mnt/etc/ $ sudo chroot /mnt $ mount /boot/efi }}} ===== Cloud instances (e.g. AWS EC2) ===== These instructions use AWS EC2 as an example but the process is similar in other clouds where the root disk can be detached from the VM. Google Compute Environment instructions can be found at https://cloud.google.com/compute/docs/disks/detach-reattach-boot-disk. Azure requires deleting the VM to attach the root disk to a separate instance for recovery, those instructions can be found at https://docs.microsoft.com/en-us/archive/blogs/mckittrick/how-to-delete-a-vm-and-attach-the-os-disk-as-a-data-disk-to-a-recovery-vm-arm. 1. Create a second cloud instance (if one does not already exist) in the same availability zone as the affected machine 2. Determine the root EBS volume of the affected instance, stop that instance and detach the root volume, then attach it to the second cloud instance from above {{{ instance_a=i-XXXXXXXX # the affected instance instance_b=i-YYYYYYYY # the second instance root_device=$(aws ec2 describe-instances \ --instance-ids $instance_a \ --output text \ --query 'Reservations[*].Instances[*].RootDeviceName') volume=$(aws ec2 describe-instances \ --instance-ids $instance_a \ --output text \ --query 'Reservations[*].Instances[*].BlockDeviceMappings[?DeviceName==`'$root_device'`].[Ebs.VolumeId]') aws ec2 stop-instances --instance-ids $instance_a aws ec2 detach-volume --volume-id $volume --output text --query 'State' aws ec2 attach-volume --volume-id $volume --instance-id $instance_b --device /dev/sdj }}} 3. `ssh` into the second instance 4. Mount the affected volume and chroot into it {{{ $ sudo mount /dev/xvdj1 /mnt $ sudo mount /dev/xvdj15 /mnt/boot/efi $ for i in /sys /proc /run /dev /dev/pts; do sudo mount --bind "$i" "/mnt$i"; done $ sudo mv /mnt/etc/resolv.conf /mnt/etc/resolv.conf.bak # will restore later $ sudo cp -L /etc/resolv.conf /mnt/etc/ $ sudo cp /cdrom/ubuntu/pool/main/g/grub2*/*deb /mnt/tmp $ sudo chroot /mnt }}} ==== Downgrade `grub2`/`grub2-signed` to the previous version for recovery ==== The previous version of `grub2`/`grub2-signed` will be different depending on the given Ubuntu release - these are summarized in the following table for amd64 (for other architectures, navigate to them via https://launchpad.net/ubuntu/+source/grub2 and https://launchpad.net/ubuntu/+source/grub2-signed for your release): ## Fix versions here || '''Release''' || '''Previous grub2 Version''' || '''Previous grub2-signed Version''' || || 20.10 || [[ https://launchpad.net/ubuntu/+source/grub2/2.04-1ubuntu35.4/+build/21030665/ | grub2 2.04-1ubuntu35.4 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.155.4/+build/21040298/ | grub2-signed 1.155.4 ]] || || 20.04 LTS || [[ https://launchpad.net/ubuntu/+source/grub2/2.04-1ubuntu26.9/+build/21030698/ | grub2 2.04-1ubuntu26.9 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.142.11/+build/21030711/ | grub2-signed 1.142.11 ]] || || 18.04 LTS || [[ https://launchpad.net/ubuntu/+source/grub2/2.02-2ubuntu8.21/+build/20779904/ | grub2 2.02-2ubuntu8.21 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.93.24/+build/20807543/ | grub2-signed 1.93.24 ]] || || 16.04 LTS || [[ https://launchpad.net/ubuntu/+source/grub2/2.02~beta2-36ubuntu3.29/+build/20308617/ | grub2 2.02~beta2-36ubuntu3.29 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.66.29/+build/20308624/ | grub2-signed 1.66.23 ]] || || 14.04 ESM || [[ https://launchpad.net/ubuntu/+source/grub2/2.02~beta2-9ubuntu1.17/+build/16522994/ | grub2 2.02~beta2-9ubuntu1.17 ]] || [[ https://launchpad.net/ubuntu/+source/grub2-signed/1.34.20/+build/16548803/ | grub2-signed 1.34.20 ]] || Once the required versions are identified from the table above, `grub2`/`grub2-signed` can be downgraded as follows from within the chroot environment. Since the previous versions are no longer available via apt, we must download the previous versions of debs and install them with dpkg. This example uses the versions for Ubuntu 18.04 LTS with typical installation packages, so these should be replaced with the appropriate versions for the given install and for packages (see '`dpkg -l | grep grub`' to see what to fetch via `wget`). Eg: {{{ # inside chroot from above (can use the links from the above table for # GRUB2_LP_URL and GRUB2_SIGNED_LP_URL) GRUB2_VERSION=2.02-2ubuntu8.21 GRUB2_LP_URL=https://launchpad.net/ubuntu/+source/grub2/$GRUB2_VERSION/+build/20779904/+files GRUB2_SIGNED_VERSION=1.93.24 GRUB2_SIGNED_LP_URL=https://launchpad.net/ubuntu/+source/grub2-signed/$GRUB2_SIGNED_VERSION/+build/20807543/+files $ cd /tmp # on focal, omit grub-efi and grub-efi-amd64 $ for i in grub-common grub-efi grub-efi-amd64 grub-efi-amd64-bin grub2-common ; do wget $GRUB2_LP_URL/${i}_${GRUB2_VERSION}_amd64.deb ; done $ wget $GRUB2_SIGNED_LP_URL/grub-efi-amd64-signed_${GRUB2_SIGNED_VERSION}+${GRUB2_VERSION}_amd64.deb $ dpkg -i ./grub*.deb $ cp -df /etc/resolv.conf.bak /etc/resolv.conf }}} Then finally exit the chroot and unmount the root device / volume (and detach + re-attach it to the original instance for a cloud instance).