From 4bd83bc0d54826ae314ce42d17e053e144c50bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?= Date: Tue, 21 Jul 2020 00:03:15 +0700 Subject: [PATCH 1/2] sbsigntool: rewrite post-install kernel hook * run the hook on target filesystem * Use ls | awk to check ownership and permission, instead of relying on GNU-stat. * libify signing code, in order to support uefi bundle in the future * Stop append signature to the efi signed by current key/cert. While we're at it, * add post-remove script to remove unsigned file if exist --- .../files/kernel.d/sbsigntool.post-install | 66 +++++++++++-------- .../files/kernel.d/sbsigntool.post-remove | 13 ++++ srcpkgs/sbsigntool/template | 4 +- 3 files changed, 53 insertions(+), 30 deletions(-) create mode 100644 srcpkgs/sbsigntool/files/kernel.d/sbsigntool.post-remove diff --git a/srcpkgs/sbsigntool/files/kernel.d/sbsigntool.post-install b/srcpkgs/sbsigntool/files/kernel.d/sbsigntool.post-install index bc450dbc428..70918527711 100644 --- a/srcpkgs/sbsigntool/files/kernel.d/sbsigntool.post-install +++ b/srcpkgs/sbsigntool/files/kernel.d/sbsigntool.post-install @@ -9,7 +9,35 @@ PKGNAME="$1" VERSION="$2" msg() { - echo "EFI sbsign hook: $1" + echo "sbsigntool: $1" +} + +do_sign() { + _kernel="$1" + if [ ! -f "$_kernel" ]; then + msg "$_kernel not found" + return 1 + fi + # Ignore efi file signed with this key + if usr/bin/sbverify -c "$ROOTDIR/$EFI_CERT_FILE" "$_kernel" >/dev/null 2>&1; then + return 0 + fi + if ! usr/bin/sbsign ${EFI_SIGN_ENGINE:+"--engine=$EFI_SIGN_ENGINE"} \ + -k "$ROOTDIR/$EFI_KEY_FILE" -c "$ROOTDIR/$EFI_CERT_FILE" \ + "$_kernel" + then + msg "failed to sign $_kernel" + return 1 + fi + if ! usr/bin/sbverify -c "$ROOTDIR/$EFI_CERT_FILE" "$_kernel.signed"; then + msg "failed to verify the signature" + return 1 + fi + + if [ "x${EFI_KEEP_UNSIGNED}" = "x1" ]; then + mv -f "$_kernel" "$_kernel.unsigned" + fi + mv -f "$_kernel.signed" "$_kernel" } . "${ROOTDIR}/etc/default/sbsigntool-kernel-hook" @@ -17,38 +45,18 @@ if [ "x${SBSIGN_EFI_KERNEL}" != x1 ]; then exit 0 fi -if [ ! -f "${EFI_KEY_FILE}" ] || [ ! -f "${EFI_CERT_FILE}" ]; then +if [ ! -f "$ROOTDIR/$EFI_KEY_FILE" ] || [ ! -f "$ROOTDIR/$EFI_CERT_FILE" ]; then msg "key and/or certificate is not available" exit 1 fi -key_stat=$(stat --dereference --format="%a %u" "${EFI_KEY_FILE}") - -# check if go=00 owner=0 -if [ "${key_stat}" = "${key_stat%00 0}" ]; then - msg "Please chown root:root '${EFI_KEY_FILE}'" - msg "and chmod go-rwx '${EFI_KEY_FILE}'" - exit 1 -fi - -# this part is completely untested -options="" -if [ "x${EFI_SIGN_ENGINE}" != x ]; then - options="--engine=${EFI_SIGN_ENGINE}" -fi - -if ! sbsign $options -k "${EFI_KEY_FILE}" -c "${EFI_CERT_FILE}" \ - "/boot/vmlinuz-${VERSION}"; then - msg "failed to sign kernel" - exit 1 -fi - -if ! sbverify -c "${EFI_CERT_FILE}" "/boot/vmlinuz-${VERSION}.signed"; then - msg "failed to verify the signature" +# All POSIX comformance ls should work +if ! ls -Ll "$ROOTDIR/$EFI_KEY_FILE" "$ROOTDIR/$EFI_CERT_FILE" | + awk '$1 !~ /^-...------$/ || $3 != "root" { exit 1 }' +then + msg "$EFI_KEY_FILE and $EFI_CERT_FILE must be owned by root." + msg "and not readable by other users." exit 1 fi -if [ "x${EFI_KEEP_UNSIGNED}" = "x1" ]; then - mv -f "/boot/vmlinuz-${VERSION}" "/boot/vmlinuz-${VERSION}.unsigned" -fi -mv -f "/boot/vmlinuz-${VERSION}.signed" "/boot/vmlinuz-${VERSION}" +do_sign "boot/vmlinuz-$VERSION" diff --git a/srcpkgs/sbsigntool/files/kernel.d/sbsigntool.post-remove b/srcpkgs/sbsigntool/files/kernel.d/sbsigntool.post-remove new file mode 100644 index 00000000000..5d3f73602af --- /dev/null +++ b/srcpkgs/sbsigntool/files/kernel.d/sbsigntool.post-remove @@ -0,0 +1,13 @@ +#!/bin/sh +# +# Kernel hook for sbsigntool. +# +# Arguments passed to this script: $1 pkgname, $2 version. +# + +PKGNAME="$1" +VERSION="$2" + +if [ -f "boot/vmlinuz-$VERSION.unsigned" ]; then + rm -f "boot/vmlinuz-${VERSION}.unsigned" +fi diff --git a/srcpkgs/sbsigntool/template b/srcpkgs/sbsigntool/template index 6e39cac66d9..6ee86139b27 100644 --- a/srcpkgs/sbsigntool/template +++ b/srcpkgs/sbsigntool/template @@ -1,7 +1,7 @@ # Template file for 'sbsigntool' pkgname=sbsigntool version=0.9.4 -revision=2 +revision=3 archs="x86_64* i686* aarch64* arm*" wrksrc=sbsigntools-$version build_style=gnu-configure @@ -59,4 +59,6 @@ post_install() { # and I'm not sure about their interaction vinstall ${FILESDIR}/kernel.d/sbsigntool.post-install 744 \ etc/kernel.d/post-install 40-sbsigntool + vinstall ${FILESDIR}/kernel.d/sbsigntool.post-remove 744 \ + etc/kernel.d/post-remove 40-sbsigntool } From 53bdcc8d3e0f41f29ed5dccaa0496ed1052bd7de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?= Date: Thu, 6 Aug 2020 19:06:30 +0700 Subject: [PATCH 2/2] refind: rewrite kernel post-install hook - refind-install only supports installing into {/boot,/boot/efi,/efi}/EFI/{BOOT,refind}/refind.conf, there're no point trying to fiddling with anything else. - That configuration file should always exist, simplify all logic behind that decision. --- srcpkgs/refind/files/kernel.post-install | 44 +++++++++++------------- srcpkgs/refind/template | 2 +- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/srcpkgs/refind/files/kernel.post-install b/srcpkgs/refind/files/kernel.post-install index 88b261aaacd..68e60414928 100755 --- a/srcpkgs/refind/files/kernel.post-install +++ b/srcpkgs/refind/files/kernel.post-install @@ -13,41 +13,39 @@ if [ "z$UPDATE_REFIND_CONF" != "z1" ]; then fi # Default refind.conf -: "${REFIND_CONF:=/boot/EFI/refind/refind.conf}" - -zrefind_dir="${REFIND_CONF%/*}" -mkdir -p "$zrefind_dir" -touch "$REFIND_CONF" +: "${REFIND_CONF:=boot/EFI/refind/refind.conf}" +REFIND_CONF=${REFIND_CONF#/} +[ -n "${REFIND_CONF}" ] || exit 0 + +# refind-install only supports those two paths +refind_dir= +case "$REFIND_CONF" in +*/EFI/[Bb][Oo][Oo][Tt]/refind.conf) + refind_dir="/EFI/BOOT" ;; +*/EFI/refind/refind.conf) + refind_dir="/EFI/refind" ;; +*) + echo >&2 "unsupported \$REFIND_CONF: $REFIND_CONF" + exit 1 ;; +esac tmpfile=$(mktemp /tmp/refind.XXXXXXX) -zefi_mountpoint=$(df -P "$REFIND_CONF" | awk 'NR==2{print $6}') -zicon="${zrefind_dir#$zefi_mountpoint}/icons/os_void.png" zversion=$(echo "$VERSION" | sed 's/[.]/[.]/g') -zentry=$(cat <"$tmpfile" + # Clean itself if this is force reconfigure + sed "/^menuentry \"Void Linux $zversion\" [{]\$/,/[}]/d" <"$REFIND_CONF" +) >"$tmpfile" mv "$tmpfile" "$REFIND_CONF" diff --git a/srcpkgs/refind/template b/srcpkgs/refind/template index 5e9865b9667..d7f8f2fba1c 100644 --- a/srcpkgs/refind/template +++ b/srcpkgs/refind/template @@ -1,7 +1,7 @@ # Template file for 'refind' pkgname=refind version=0.12.0 -revision=1 +revision=2 archs="x86_64* i686* aarch64*" makedepends="gnu-efi-libs" depends="bash dosfstools efibootmgr"