Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport fix for PrintErrMesg in early EFI boot #189

Open
wants to merge 1 commit into
base: release4.2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions 0320-Avoid-crash-calling-PrintErrMesg-from-efi_multiboot2.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
From f590c56d1b6aab01c7e1c7c8adfbb7dd64f3a412 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <[email protected]>
Date: Mon, 19 Aug 2024 15:29:52 +0100
Subject: [PATCH] Avoid crash calling PrintErrMesg from efi_multiboot2

Although code is compiled with -fpic option data is not position
independent. This causes data pointer to become invalid if
code is not relocated properly which is what happens for
efi_multiboot2 which is called by multiboot entry code.

Code tested adding
PrintErrMesg(L"Test message", EFI_BUFFER_TOO_SMALL);
in efi_multiboot2 before calling efi_arch_edd (this function
can potentially call PrintErrMesg).

Before the patch (XenServer installation on Qemu, xen replaced
with vanilla xen.gz):
Booting `XenServer (Serial)'Booting `XenServer (Serial)'
Test message: !!!! X64 Exception Type - 0E(#PF - Page-Fault) CPU Apic ID - 00000000 !!!!
ExceptionData - 0000000000000000 I:0 R:0 U:0 W:0 P:0 PK:0 SS:0 SGX:0
RIP - 000000007DC29E46, CS - 0000000000000038, RFLAGS - 0000000000210246
RAX - 0000000000000000, RCX - 0000000000000050, RDX - 0000000000000000
RBX - 000000007DAB4558, RSP - 000000007EFA1200, RBP - 0000000000000000
RSI - FFFF82D040467A88, RDI - 0000000000000000
R8 - 000000007EFA1238, R9 - 000000007EFA1230, R10 - 0000000000000000
R11 - 000000007CF42665, R12 - FFFF82D040467A88, R13 - 000000007EFA1228
R14 - 000000007EFA1225, R15 - 000000007DAB45A8
DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
GS - 0000000000000030, SS - 0000000000000030
CR0 - 0000000080010033, CR2 - FFFF82D040467A88, CR3 - 000000007EC01000
CR4 - 0000000000000668, CR8 - 0000000000000000
DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 000000007E9E2000 0000000000000047, LDTR - 0000000000000000
IDTR - 000000007E4E5018 0000000000000FFF, TR - 0000000000000000
FXSAVE_STATE - 000000007EFA0E60
!!!! Find image based on IP(0x7DC29E46) (No PDB) (ImageBase=000000007DC28000, EntryPoint=000000007DC2B917) !!!!

After the patch:
Booting `XenServer (Serial)'Booting `XenServer (Serial)'
Test message: Buffer too small
BdsDxe: loading Boot0000 "UiApp" from Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(462CAA21-7614-4503-836E-8AB6F4662331)
BdsDxe: starting Boot0000 "UiApp" from Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(462CAA21-7614-4503-836E-8AB6F4662331)

Fixes: 9180f5365524 ("x86: add multiboot2 protocol support for EFI platforms")
Signed-off-by: Frediano Ziglio <[email protected]>
---
xen/common/efi/boot.c | 46 ++++++++++++++++++++++++++++++-------------
1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index d3c6b055ae67..060b91751e1b 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -286,19 +286,36 @@ static bool __init match_guid(const EFI_GUID *guid1, const EFI_GUID *guid2)
/* generic routine for printing error messages */
static void __init PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode)
{
- static const CHAR16* const ErrCodeToStr[] __initconstrel = {
- [~EFI_ERROR_MASK & EFI_NOT_FOUND] = L"Not found",
- [~EFI_ERROR_MASK & EFI_NO_MEDIA] = L"The device has no media",
- [~EFI_ERROR_MASK & EFI_MEDIA_CHANGED] = L"Media changed",
- [~EFI_ERROR_MASK & EFI_DEVICE_ERROR] = L"Device error",
- [~EFI_ERROR_MASK & EFI_VOLUME_CORRUPTED] = L"Volume corrupted",
- [~EFI_ERROR_MASK & EFI_ACCESS_DENIED] = L"Access denied",
- [~EFI_ERROR_MASK & EFI_OUT_OF_RESOURCES] = L"Out of resources",
- [~EFI_ERROR_MASK & EFI_VOLUME_FULL] = L"Volume is full",
- [~EFI_ERROR_MASK & EFI_SECURITY_VIOLATION] = L"Security violation",
- [~EFI_ERROR_MASK & EFI_CRC_ERROR] = L"CRC error",
- [~EFI_ERROR_MASK & EFI_COMPROMISED_DATA] = L"Compromised data",
- [~EFI_ERROR_MASK & EFI_BUFFER_TOO_SMALL] = L"Buffer too small",
+#define ERROR_MESSAGE_LIST \
+ ERROR_MESSAGE(EFI_NOT_FOUND, "Not found") \
+ ERROR_MESSAGE(EFI_NO_MEDIA, "The device has no media") \
+ ERROR_MESSAGE(EFI_MEDIA_CHANGED, "Media changed") \
+ ERROR_MESSAGE(EFI_DEVICE_ERROR, "Device error") \
+ ERROR_MESSAGE(EFI_VOLUME_CORRUPTED, "Volume corrupted") \
+ ERROR_MESSAGE(EFI_ACCESS_DENIED, "Access denied") \
+ ERROR_MESSAGE(EFI_OUT_OF_RESOURCES, "Out of resources") \
+ ERROR_MESSAGE(EFI_VOLUME_FULL, "Volume is full") \
+ ERROR_MESSAGE(EFI_SECURITY_VIOLATION, "Security violation") \
+ ERROR_MESSAGE(EFI_CRC_ERROR, "CRC error") \
+ ERROR_MESSAGE(EFI_COMPROMISED_DATA, "Compromised data") \
+ ERROR_MESSAGE(EFI_BUFFER_TOO_SMALL, "Buffer too small")
+
+ static const struct ErrorStrings {
+ CHAR16 start;
+#undef ERROR_MESSAGE
+#define ERROR_MESSAGE(code, str) CHAR16 msg_ ## code[sizeof(str)];
+ ERROR_MESSAGE_LIST
+ } ErrorStrings __initconst = {
+ 0
+#undef ERROR_MESSAGE
+#define ERROR_MESSAGE(code, str) , L ## str
+ ERROR_MESSAGE_LIST
+ };
+ static const uint16_t ErrCodeToStr[] __initconst = {
+#undef ERROR_MESSAGE
+#define ERROR_MESSAGE(code, str) \
+ [~EFI_ERROR_MASK & code] = offsetof(struct ErrorStrings, msg_ ## code),
+ ERROR_MESSAGE_LIST
};
EFI_STATUS ErrIdx = ErrCode & ~EFI_ERROR_MASK;

@@ -307,7 +324,8 @@ static void __init PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode)
PrintErr(L": ");

if( (ErrIdx < ARRAY_SIZE(ErrCodeToStr)) && ErrCodeToStr[ErrIdx] )
- mesg = ErrCodeToStr[ErrIdx];
+ mesg = (const CHAR16 *)((const void *)&ErrorStrings +
+ ErrCodeToStr[ErrIdx]);
else
{
PrintErr(L"ErrCode: ");
--
2.46.0

1 change: 1 addition & 0 deletions xen.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ Patch0316: 0316-drivers-char-mark-extra-reserved-device-memory-in-me.patch
Patch0317: 0317-xen-list-add-LIST_HEAD_RO_AFTER_INIT.patch
Patch0318: 0318-x86-mm-add-API-for-marking-only-part-of-a-MMIO-page-.patch
Patch0319: 0319-drivers-char-Use-sub-page-ro-API-to-make-just-xhci-d.patch
Patch0320: 0320-Avoid-crash-calling-PrintErrMesg-from-efi_multiboot2.patch

# Security fixes
Patch0500: 0500-xsa458.patch
Expand Down