#801485 grub-common: Config script sets wrong "root=" param for other installations that use dm-crypt root

Package:
grub-common
Source:
grub2
Description:
GRand Unified Bootloader (common files)
Submitter:
Date:
2015-10-11 04:15:05 UTC
Severity:
important
#801485#5
Date:
2015-10-11 04:06:02 UTC
From:
To:
The update-grub2 script regenerates grub's configuration by calling the
/etc/grub.d/* scripts, it tries to determine the root= parameter for
each parameter. If an installation uses cryptsetup for the root
partition, this parameter needs to point to the dm-crypt mapping for
the opened device, which is usually opened through a script in the
initramfs asking the user for a key.

The "10_linux" script responsible fails to handle this situation
correctly for installations other than the one currently running which
use a different dm-crypt root partition.

The script simply points "root=" to the currently mounted root
partition, which may be wrong for other installation and render those
installations unbootable. Because update-grub2 regenerates all entries
on every launch, this even corrupts a configuration that was correctly
set up by the user.

To illustrate: I was running an installation that maps encrypted
/dev/sda1 to encrypted /dev/mapper/alpha, using this as its root
device. I also have another installation that maps encrypted /dev/sdb2
to /dev/mapper/bravo and uses it as root. Running update-grub2 on the
first installation will tell installation 2 to boot by mounting a disk
with /dev/mapper/alpha's UUID as root. This will always break
installation 2.

My proposed fix is to look at the initramfs of every installation
before creating its installation. When Debian uses a dm-crypt device as
root, it creates a script "conf/conf.d/cryptroot" in the initramfs.
This script contains all information necessary to retrieve the correct
root= parameter for the installation. Some string manipulation extracts
the device target, i.e. the name under which the decrypted device will
show up under /dev/mapper/.

Note that /dev/mapper/sdXX_crypt is a purely arbitrary name generated
by the installer and has nothing to do  with /dev/sdXX. My proposed fix
thus also works if the encrypted device happens to be at a node other
than /dev/sdXX as long as the dm-crypt device is mounted by its UUID,
not by its node.

Patch follows:
--- /etc/grub.d/10_linux	2015-10-10 18:45:08.755900038 -0700
+++ ./10_linux_fix	2015-10-10 18:36:45.725983101 -0700
@@ -177,8 +177,18 @@
 	linux	${rel_dirname}/${basename}.efi.signed
root=${linux_root_device_thisversion} ro ${args}
 EOF
   else
+	cryptroot=$(zcat /boot/${initrd} | cpio -i --to-stdout
conf/conf.d/cryptroot  | cut -d, -f1 -| cut -d= -f2)
+		if [ x"$cryptroot" != "" ]; then
+#	printf "${basename}" "is using cryptsetup, overriding ROOT to
" "$newroot";
+
+	rootparam="/dev/mapper/"$cryptroot;
+	echo ''
+	else
+	rootparam="UUID="${linux_root_device_thisversion};
+		fi
+
     sed "s/^/$submenu_indentation/" << EOF
-	linux	${rel_dirname}/${basename}
root=${linux_root_device_thisversion} ro ${args}
+	linux	${rel_dirname}/${basename} root=$rootparam ro
${args}
 EOF
   fi
   if test -n "${initrd}" ; then