[Merge] ~juliank/grub/+git/ubuntu:juliank/check-signed-kernels into ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu
Steve Langasek
steve.langasek at canonical.com
Fri Jun 8 05:23:01 UTC 2018
Review: Needs Fixing
Diff comments:
> diff --git a/debian/grub-check-signatures b/debian/grub-check-signatures
> new file mode 100755
> index 0000000..6443c8c
> --- /dev/null
> +++ b/debian/grub-check-signatures
> @@ -0,0 +1,55 @@
> +#!/bin/sh
> +
> +set -e
> +
> +. /usr/share/debconf/confmodule
> +
> +# Check if we are on an EFI system
> +are_efi() {
system_is_efi(), please.
However, we should be checking not only that the system is efi, but that secureboot is enabled. At minimum, that should mean checking the output of mokutil --sb-state, or if that's not an appropriate dependency, checking the content of /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c directly.
> + test -d /sys/firmware/efi/
> + return $?
> +}
> +
> +# Check if a given kernel image is sized
> +is_signed() {
> + tmp=$(mktemp)
> + sbattach --detach $tmp $1 >/dev/null # that's ugly...
> + test "$(wc -c < $tmp)" -ge 16 # Just _some_ minimum size
> + result=$?
> + rm $tmp
> + return $result
> +}
> +
> +# Check that our current kernel and every newer one is signed
> +have_signed() {
> + uname_r="$(uname -r)"
> + for kernel in $(grep '^\s*linux' /boot/grub/grub.cfg | awk '{print $2}' | uniq); do
> + this_uname_r="$(echo "$kernel" | sed -nr 's#^/vmlinuz-(.*)#\1#p' | sed 's#\.efi\.signed$##')"
> + if test -e /boot/$kernel && ! is_signed /boot/$kernel; then
> + return 1
> + fi
> + if [ "$uname_r" = "$this_uname_r" ]; then
> + return 0
> + fi
> + done
> + return 0
> +}
> +
> +# Only reached from show_warning
> +error() {
> + echo "E: Your kernels are unsigned. This system will fail to boot in a secure boot environment." >&2
> + exit 1
> +}
> +
> +# Either shows a debconf note or prints an error with error() above if
> +# that fails
> +show_warning() {
> + db_title "Unsigned kernel" || error
> + db_fset grub2/unsigned_kernels seen 0 || error
> + db_input critical grub2/unsigned_kernels || error
> + db_go || error
> +}
> +
> +if are_efi && ! have_signed; then
> + show_warning
> +fi
> diff --git a/debian/update-grub b/debian/update-grub
> index 0c43327..5b57e5e 100644
> --- a/debian/update-grub
> +++ b/debian/update-grub
> @@ -1,3 +1,4 @@
> #!/bin/sh
> set -e
> -exec grub-mkconfig -o /boot/grub/grub.cfg "$@"
> +grub-mkconfig -o /boot/grub/grub.cfg "$@" 3>&-
> +/usr/share/grub/grub-check-signatures
Is it really necessary to make this part of update-grub, and have it run each time grub or a kernel is upgraded? I would expect us to only run this check at the point in time that we are switching the grub policy to enforce kernel signatures, because this is a behavior change in grub that carries significant risk. I don't think it's the responsibility of the grub package to check on every run that a new kernel the user has installed is secureboot-compatible.
Also, I expect us to *block* the upgrade of the grub package based on the result of this check, which this does not do. (We should avoid calling grub-install --target=x86_64-efi if doing so will render the system unbootable; and the only reasonable way to bubble this up is as a package installation failure.)
--
https://code.launchpad.net/~juliank/grub/+git/ubuntu/+merge/345403
Your team Ubuntu Core Development Team is subscribed to branch ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu.
More information about the Ubuntu-reviews
mailing list