diff --git a/backport-aarch64-Keep-_relocate-from-being-dirtied-by-_reloca.patch b/backport-aarch64-Keep-_relocate-from-being-dirtied-by-_reloca.patch new file mode 100644 index 0000000000000000000000000000000000000000..c6efb63ed76a374448d5f15c27f96b6d4e2da828 --- /dev/null +++ b/backport-aarch64-Keep-_relocate-from-being-dirtied-by-_reloca.patch @@ -0,0 +1,105 @@ +From de8c3582d2eb280bf6b358349e04a959b945f1a5 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Fri, 1 Jul 2022 15:52:51 -0400 +Subject: [PATCH] aarch64: Keep _relocate() from being dirtied by _relocate() + +[Patch is a gnu-efi patch we apply to the bundled copy.] + +This could all be wrong, but the fix seems to work. Here's my theory of +what's going on. We have a bug report that says: + + No EFI system partition + Booting /efi\boot\bootaa64.efi + No EFI system partition + Failed to persist EFI variables + "Synchronous Abort" handler, esr 0x02000000 + elr: fffffffffeb48a28 lr : fffffffffeb3f024 (reloc) + elr: 000000003ca1aa28 lr : 000000003ca11024 + x0 : 000000003ca0d000 x1 : 000000003ca22018 + x2 : 000000003ca22000 x3 : 0000000000000018 + x4 : 0000000000001488 x5 : 0000000000000000 + x6 : 0000000000001000 x7 : 0000000000000000 + x8 : 0000000000000007 x9 : 0000000000003ca0 + x10: 000000003ca3e040 x11: 00000000b0b87665 + x12: 000000007c70ea25 x13: 000000005a827999 + x14: 000000006ed9eba1 x15: 000000008f1bbcdc + x16: 000000003df97394 x17: 00000000b7ce40b7 + x18: 0000000000000011 x19: 000000003caeb000 + x20: 0000000000000000 x21: 000000003dc1ba50 + x22: 000000003caff2f8 x23: 0000000000000001 + x24: 000000003caff000 x25: 000000003caff3c0 + x26: 000000003caff3c8 x27: 000000003caff3d0 + x28: 000000003caff3d8 x29: 000000003db3e600 + + Code: 8b000021 f82068a1 8b030042 cb030084 (f100009f) + UEFI image [0x000000003ca0d000:0x000000003ca24fff] pc=0xda28 '/efi\boot\fbaa64.efi' + Resetting CPU ... + + resetting ... + +When I disassemble it, "8b000021 f82068a1 8b030042 cb030084 (f100009f)" +at 0xda28 (aka 0x3ca1aa28 in our register dump above) is: + + da18: 8b000021 add x1, x1, x0 + da1c: f82068a1 str x1, [x5, x0] + da20: 8b030042 add x2, x2, x3 + da24: cb030084 sub x4, x4, x3 + da28: f100009f cmp x4, #0x0 + +Of course the Arm ARM says "cmp" cannot fault in this way, and %esr is +less than helpful, for reasons I don't understand. I believe what is +happening is this. Farther up in the file is the function +StatusToString(), as seen here: + + 000000000000d960 : + d960: d0000022 adrp x2, 13000 + d964: aa0103e3 mov x3, x1 + d968: 911f0042 add x2, x2, #0x7c0 + d96c: f9400441 ldr x1, [x2, #8] + d970: b5000081 cbnz x1, d980 + d974: b0000022 adrp x2, 12000 + d978: 91124842 add x2, x2, #0x492 + d97c: 17fffc32 b ca44 + d980: f8410444 ldr x4, [x2], #16 + d984: eb03009f cmp x4, x3 + d988: 54ffff21 b.ne d96c // b.any + d98c: 17fffe47 b d2a8 + +I believe when _relocate() gets to the relocations for 0xd960 the page +being processed is evicted from the i$ and moved into the d$, and then +when execution continues, the i$ raises an exception because it doesn't +have the page in question, and it can't stall execution to fill it, +because it's now owned (and dirty) in the other cache. + +There are a couple of ways to solve this, but I've taken the laziest +one: align the code in _relocate() to its own page boundary. This +partially works because our link order means this code is actually the +last function in .text, and so no relocations will ever land on this +page. + +Signed-off-by: Peter Jones +[rharwood@redhat.com: adapt to shim] +Signed-off-by: Robbie Harwood +--- + gnu-efi/gnuefi/reloc_aarch64.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/gnu-efi/gnuefi/reloc_aarch64.c b/gnu-efi/gnuefi/reloc_aarch64.c +index 086727961c2..0022abdaca7 100644 +--- a/gnu-efi/gnuefi/reloc_aarch64.c ++++ b/gnu-efi/gnuefi/reloc_aarch64.c +@@ -48,6 +48,11 @@ EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn, + unsigned long *addr; + int i; + ++ /* ++ * We need this code to not be on the same page as any relocations. ++ */ ++ __asm__(".balign 4096\n"); ++ + for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { + switch (dyn[i].d_tag) { + case DT_RELA: +-- +2.35.1 + diff --git a/shim.spec b/shim.spec index 7f27b6c4348acb488e1aa92ab85f1b9e18eb4aa1..ac43af0547464f9d69201ae0a6eeb7cdf7edc3d8 100644 --- a/shim.spec +++ b/shim.spec @@ -25,7 +25,7 @@ Name: shim Version: 15.6 -Release: 14 +Release: 15 Summary: First-stage UEFI bootloader ExclusiveArch: x86_64 aarch64 License: BSD @@ -72,6 +72,7 @@ Patch35:backport-pe-only-process-RelocDir-Size-of-reloc-section.patch Patch36:backport-Correctly-free-memory-allocated-in-handle_image.patch Patch37:backport-CVE-2023-3446.patch Patch38:backport-CVE-2023-5678.patch +Patch39:backport-aarch64-Keep-_relocate-from-being-dirtied-by-_reloca.patch # Feature for shim SMx support Patch9000:Feature-shim-openssl-add-ec-support.patch @@ -195,6 +196,9 @@ make test /usr/src/debug/%{name}-%{version}-%{release}/* %changelog +* Mon Dec 25 2023 zhangruifang - 15.6-15 +- backport patchs from upstream + * Mon Dec 18 2023 jinlun - 15.6-14 - fix CVE-2023-3446 CVE-2023-5678