diff --git a/linker-version.pl b/linker-version.pl deleted file mode 100644 index 148cd1d..0000000 --- a/linker-version.pl +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/perl -w -# -# Modify the linker version in the EFI/PE header -# -# NOTE: only use this script when the signature doesn't match after -# a binutils upgrade -# - -use strict; - -# The target version of binutils: 2.32 -my $major_linker_version = 2; -my $minor_linker_version = 32; - -my ($file) = @ARGV; - -die "$file: $!\n" unless open(my $fh, '+<', $file); -# Set MajorLinkerVersion at 0x9a -die "seek $file: $!\n" unless seek($fh, 0x9a, 0); -die "write $file: $!\n" unless print $fh pack('C', $major_linker_version); -# Set MinorLinkerVersion at 0x9b -die "seek $file: $!\n" unless seek($fh, 0x9b, 0); -die "write $file: $!\n" unless print $fh pack('C', $minor_linker_version); -close($fh); diff --git a/shim-bsc1182776-fix-crash-at-exit.patch b/shim-bsc1182776-fix-crash-at-exit.patch index d4e5c7b..eb62137 100644 --- a/shim-bsc1182776-fix-crash-at-exit.patch +++ b/shim-bsc1182776-fix-crash-at-exit.patch @@ -1,7 +1,58 @@ -From 74d26654d55a4f32e58b76757efca50ceedefef4 Mon Sep 17 00:00:00 2001 +From 999983b82c611d7d3b864f5f46764645f4eed096 Mon Sep 17 00:00:00 2001 +From: Stuart Hayes +Date: Fri, 8 Feb 2019 15:48:20 -0500 +Subject: [PATCH 1/2] Hook exit when shim_lock protocol installed + +A recent commit moved where the shim_lock protocol is loaded and +unloaded, but did not move where exit was hooked and unhooked. Exit +needs to be hooked when the protocol is installed, so that the protocol +will be uninstalled on exit. Otherwise, the system can crash if, for +example, shim loads grub, the user exits grub, shim is run again, which +installs a second instance of the protocol, and then grub tries to use +the shim_lock protocol that was installed by the first instance of shim. + +Signed-off-by: Stuart Hayes +Upstream-commit-id: 06c92591e94 +(cherry picked from commit b5e10f70c7a495dc1788e3604803ee633f1e5f76) +--- + shim.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/shim.c b/shim.c +index 6ce30a06..e9ab8f1a 100644 +--- a/shim.c ++++ b/shim.c +@@ -2517,9 +2517,9 @@ shim_init(void) + loader_is_participating = 0; + } + +- hook_exit(systab); + } + ++ hook_exit(systab); + return install_shim_protocols(); + } + +@@ -2537,9 +2537,10 @@ shim_fini(void) + * Remove our hooks from system services. + */ + unhook_system_services(); +- unhook_exit(); + } + ++ unhook_exit(); ++ + /* + * Free the space allocated for the alternative 2nd stage loader + */ +-- +2.29.2 + + +From 13eeece966bf2e5b2d1c1cca0c8b47bbded0f98e Mon Sep 17 00:00:00 2001 From: Gary Lin Date: Fri, 5 Mar 2021 15:00:29 +0800 -Subject: [PATCH] Restore loaded image of shim at Exit() +Subject: [PATCH 2/2] Restore loaded image of shim at Exit() When grub2 invoked Exit() in AArch64 AAVMF, the VM crashed with the following messsages: @@ -24,17 +75,18 @@ that we can restore the loaded image both in start_image() and do_exit(). Signed-off-by: Gary Lin +(cherry picked from commit 74d26654d55a4f32e58b76757efca50ceedefef4) --- replacements.c | 2 ++ shim.c | 41 ++++++++++++++++++++++++----------------- shim.h | 1 + 3 files changed, 27 insertions(+), 17 deletions(-) -Index: shim-15+git47/replacements.c -=================================================================== ---- shim-15+git47.orig/replacements.c -+++ shim-15+git47/replacements.c -@@ -159,6 +159,8 @@ do_exit(EFI_HANDLE ImageHandle, EFI_STAT +diff --git a/replacements.c b/replacements.c +index 944c779d..1d06b0cf 100644 +--- a/replacements.c ++++ b/replacements.c +@@ -159,6 +159,8 @@ do_exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus, shim_fini(); @@ -43,11 +95,11 @@ Index: shim-15+git47/replacements.c efi_status = gBS->Exit(ImageHandle, ExitStatus, ExitDataSize, ExitData); if (EFI_ERROR(efi_status)) { -Index: shim-15+git47/shim.c -=================================================================== ---- shim-15+git47.orig/shim.c -+++ shim-15+git47/shim.c -@@ -58,6 +58,8 @@ +diff --git a/shim.c b/shim.c +index e9ab8f1a..b5882768 100644 +--- a/shim.c ++++ b/shim.c +@@ -62,6 +62,8 @@ static EFI_SYSTEM_TABLE *systab; static EFI_HANDLE global_image_handle; @@ -56,7 +108,7 @@ Index: shim-15+git47/shim.c static CHAR16 *second_stage; static void *load_options; -@@ -1861,13 +1863,24 @@ static EFI_STATUS shim_read_header(void +@@ -1863,13 +1865,24 @@ static EFI_STATUS shim_read_header(void *data, unsigned int datasize, return efi_status; } @@ -82,7 +134,7 @@ Index: shim-15+git47/shim.c EFI_IMAGE_ENTRY_POINT entry_point; EFI_PHYSICAL_ADDRESS alloc_address; UINTN alloc_pages; -@@ -1882,7 +1895,7 @@ EFI_STATUS start_image(EFI_HANDLE image_ +@@ -1884,7 +1897,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) * binary in order to find our path */ efi_status = gBS->HandleProtocol(image_handle, &EFI_LOADED_IMAGE_GUID, @@ -91,7 +143,7 @@ Index: shim-15+git47/shim.c if (EFI_ERROR(efi_status)) { perror(L"Unable to init protocol\n"); return efi_status; -@@ -1891,14 +1904,14 @@ EFI_STATUS start_image(EFI_HANDLE image_ +@@ -1893,14 +1906,14 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) /* * Build a new path from the existing one plus the executable name */ @@ -108,7 +160,7 @@ Index: shim-15+git47/shim.c efi_status = parseNetbootinfo(image_handle); if (EFI_ERROR(efi_status)) { perror(L"Netboot parsing failed: %r\n", efi_status); -@@ -1914,7 +1927,7 @@ EFI_STATUS start_image(EFI_HANDLE image_ +@@ -1916,7 +1929,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) data = sourcebuffer; datasize = sourcesize; #if defined(ENABLE_HTTPBOOT) @@ -117,7 +169,7 @@ Index: shim-15+git47/shim.c efi_status = httpboot_fetch_buffer (image_handle, &sourcebuffer, &sourcesize); -@@ -1930,7 +1943,7 @@ EFI_STATUS start_image(EFI_HANDLE image_ +@@ -1932,7 +1945,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) /* * Read the new executable off disk */ @@ -126,7 +178,7 @@ Index: shim-15+git47/shim.c if (EFI_ERROR(efi_status)) { perror(L"Failed to load image %s: %r\n", PathName, efi_status); -@@ -1949,13 +1962,13 @@ EFI_STATUS start_image(EFI_HANDLE image_ +@@ -1951,13 +1964,13 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) * We need to modify the loaded image protocol entry before running * the new binary, so back it up */ @@ -143,7 +195,7 @@ Index: shim-15+git47/shim.c perror(L"Unable to update loaded image file path\n"); efi_status = EFI_OUT_OF_RESOURCES; goto restore; -@@ -1964,7 +1977,7 @@ EFI_STATUS start_image(EFI_HANDLE image_ +@@ -1966,7 +1979,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) /* * Verify and, if appropriate, relocate and execute the executable */ @@ -152,7 +204,7 @@ Index: shim-15+git47/shim.c &alloc_address, &alloc_pages); if (EFI_ERROR(efi_status)) { perror(L"Failed to load image: %r\n", efi_status); -@@ -1981,13 +1994,7 @@ EFI_STATUS start_image(EFI_HANDLE image_ +@@ -1983,13 +1996,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath) efi_status = entry_point(image_handle, systab); restore: @@ -167,11 +219,11 @@ Index: shim-15+git47/shim.c done: if (PathName) FreePool(PathName); -Index: shim-15+git47/shim.h -=================================================================== ---- shim-15+git47.orig/shim.h -+++ shim-15+git47/shim.h -@@ -163,6 +163,7 @@ extern EFI_STATUS LogError_(const char * +diff --git a/shim.h b/shim.h +index 3db7df9d..38627abf 100644 +--- a/shim.h ++++ b/shim.h +@@ -160,6 +160,7 @@ extern EFI_STATUS LogError_(const char *file, int line, const char *func, CHAR16 extern EFI_STATUS VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list args); extern VOID PrintErrors(VOID); extern VOID ClearErrors(VOID); @@ -179,3 +231,6 @@ Index: shim-15+git47/shim.h extern EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath); extern EFI_STATUS import_mok_state(EFI_HANDLE image_handle); +-- +2.29.2 + diff --git a/shim.changes b/shim.changes index c38904f..bc933fe 100644 --- a/shim.changes +++ b/shim.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Mar 11 03:15:03 UTC 2021 - Gary Ching-Pang Lin + +- Refresh shim-bsc1182776-fix-crash-at-exit.patch to do the cleanup + also when Secure Boot is disabled (bsc#1183213, bsc#1182776) +- Merged linker-version.pl into timestamp.pl and add the linker + version to signature files accordingly + ------------------------------------------------------------------- Mon Mar 8 03:13:13 UTC 2021 - Gary Ching-Pang Lin diff --git a/shim.spec b/shim.spec index 480441a..92cd074 100644 --- a/shim.spec +++ b/shim.spec @@ -59,7 +59,6 @@ Source10: strip_signature.sh Source11: signature-sles.x86_64.asc Source12: signature-opensuse.aarch64.asc Source13: signature-sles.aarch64.asc -Source14: linker-version.pl Source50: dbx-cert.tar.xz # vendor-dbx.bin is generated by generate-vendor-dbx.sh in dbx-cert.tar.xz Source51: vendor-dbx.bin @@ -246,14 +245,6 @@ for suffix in "${suffixes[@]}"; do # alternative: verify signature #sbverify --cert MicCorThiParMarRoo_2010-10-05.pem shim-signed.efi if test -n "$signature"; then -%ifarch x86_64 - # Modify MajorLinkerVersion and MinorLinkerVersion in the - # EFI/PE header to match the one for the SLE signature. - if test "$suffix" = "sles"; then - chmod 755 %{SOURCE14} - %{SOURCE14} shim.efi - fi -%endif head -1 "$signature" > hash1 cp shim.efi shim.efi.bak # pe header contains timestamp and checksum. we need to diff --git a/signature-opensuse.aarch64.asc b/signature-opensuse.aarch64.asc index f299123..089ac97 100644 --- a/signature-opensuse.aarch64.asc +++ b/signature-opensuse.aarch64.asc @@ -1,6 +1,7 @@ hash: 96275dfd6282a522b011177ee049296952ac794832091f937fbbf92869028629 # 2069-04-10 06:07:54 timestamp: babababa +linker: 2002 checksum: ef25 -----BEGIN AUTHENTICODE SIGNATURE----- MIIhwQYJKoZIhvcNAQcCoIIhsjCCIa4CAQExDzANBglghkgBZQMEAgEFADBcBgor diff --git a/signature-opensuse.x86_64.asc b/signature-opensuse.x86_64.asc index 30037d7..db5adf3 100644 --- a/signature-opensuse.x86_64.asc +++ b/signature-opensuse.x86_64.asc @@ -1,6 +1,7 @@ hash: f5e892dd6ec4c2defa4a495c09219b621379b64da3d1b2e34adf4b5f1102bd39 # 1970-01-01 00:00:00 timestamp: 0 +linker: 2002 checksum: 65ba -----BEGIN AUTHENTICODE SIGNATURE----- MIIhVgYJKoZIhvcNAQcCoIIhRzCCIUMCAQExDzANBglghkgBZQMEAgEFADBcBgor diff --git a/signature-sles.aarch64.asc b/signature-sles.aarch64.asc index d88c3c8..4a26792 100644 --- a/signature-sles.aarch64.asc +++ b/signature-sles.aarch64.asc @@ -1,6 +1,7 @@ hash: f31fd461c5e99510403fc97c1da2d8a9cbe270597d32badf8fd66b77495f8d94 # 2069-04-10 06:07:54 timestamp: babababa +linker: 2002 checksum: 61c9 -----BEGIN AUTHENTICODE SIGNATURE----- MIIh9AYJKoZIhvcNAQcCoIIh5TCCIeECAQExDzANBglghkgBZQMEAgEFADBcBgor diff --git a/signature-sles.x86_64.asc b/signature-sles.x86_64.asc index 52b2c33..1107256 100644 --- a/signature-sles.x86_64.asc +++ b/signature-sles.x86_64.asc @@ -1,6 +1,7 @@ hash: 040b3bc339e9b6f9acd828b88f3482a5c3f64e67e5a714ba1da8a70453b34af6 # 1970-01-01 00:00:00 timestamp: 0 +linker: 2002 checksum: 15eb -----BEGIN AUTHENTICODE SIGNATURE----- MIIhRgYJKoZIhvcNAQcCoIIhNzCCITMCAQExDzANBglghkgBZQMEAgEFADBcBgor diff --git a/timestamp.pl b/timestamp.pl index 38a5d15..9a93bab 100644 --- a/timestamp.pl +++ b/timestamp.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -# Copyright (c) 2012,2013 SUSE Linux Products GmbH +# Copyright (c) 2012-2021 SUSE LLC # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -33,7 +33,7 @@ timestamp.pl [OPTIONS] FILE... =item B<--set-form-file=FILE> -parse timestamp and checksum from file +parse timestamp, checksum, and linker version from file =item B<--help, -h> @@ -74,6 +74,7 @@ usage(0) if ($options{'help'}); my $set_timestamp; my $set_checksum; +my $set_linker; if ($options{'set-from-file'}) { die "$options{'set-from-file'}: $!\n" unless open(my $fh, '<', $options{'set-from-file'}); @@ -82,14 +83,17 @@ if ($options{'set-from-file'}) { if (/^timestamp: ([0-9a-f]+)/) { $set_timestamp = pack('L', hex($1)); next; + } elsif (/^linker: ([0-9a-f]+)/) { + $set_linker = pack('S', hex($1)); + next; } elsif (/^checksum: ([0-9a-f]+)/) { $set_checksum = pack('S', hex($1)); next; } - last if $set_timestamp && $set_checksum; + last if $set_timestamp && $set_checksum && $set_linker; } close($fh); - die "file didn't contain timestamp and checksum\n" unless $set_timestamp && $set_checksum; + die "file didn't contain timestamp, checksum, or linker\n" unless $set_timestamp && $set_checksum && $set_linker; } sub do_show($) @@ -104,6 +108,11 @@ sub do_show($) print strftime("# %Y-%m-%d %H:%M:%S\n", gmtime($timestamp)); printf ("timestamp: %x\n", $timestamp); + die "seek $file: $!\n" unless seek($fh, 154, 0); + die "read $file: $!\n" unless read($fh, $value, 2); + + printf ("linker: %x\n", unpack('S', $value)); + die "seek $file: $!\n" unless seek($fh, 216, 0); die "read $file: $!\n" unless read($fh, $value, 2); @@ -119,12 +128,14 @@ sub do_set($) die "seek $file: $!\n" unless seek($fh, 136, 0); die "write $file: $!\n" unless print $fh $set_timestamp; + die "seek $file: $!\n" unless seek($fh, 154, 0); + die "write $file: $!\n" unless print $fh $set_linker; + die "seek $file: $!\n" unless seek($fh, 216, 0); die "read $file: $!\n" unless print $fh $set_checksum; close($fh); } - for my $file (@ARGV) { if ($options{'set-from-file'}) { do_set($file);