[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[SECURITY PATCH 26/28] efi: Fix use-after-free in halt/reboot path
From: |
Daniel Kiper |
Subject: |
[SECURITY PATCH 26/28] efi: Fix use-after-free in halt/reboot path |
Date: |
Wed, 29 Jul 2020 19:00:39 +0200 |
From: Alexey Makhalov <amakhalov@vmware.com>
commit 92bfc33db984 ("efi: Free malloc regions on exit")
introduced memory freeing in grub_efi_fini(), which is
used not only by exit path but by halt/reboot one as well.
As result of memory freeing, code and data regions used by
modules, such as halt, reboot, acpi (used by halt) also got
freed. After return to module code, CPU executes, filled
by UEFI firmware (tested with edk2), 0xAFAFAFAF pattern as
a code. Which leads to #UD exception later.
grub> halt
!!!! X64 Exception Type - 06(#UD - Invalid Opcode) CPU Apic ID - 00000000 !!!!
RIP - 0000000003F4EC28, CS - 0000000000000038, RFLAGS - 0000000000200246
RAX - 0000000000000000, RCX - 00000000061DA188, RDX - 0A74C0854DC35D41
RBX - 0000000003E10E08, RSP - 0000000007F0F860, RBP - 0000000000000000
RSI - 00000000064DB768, RDI - 000000000832C5C3
R8 - 0000000000000002, R9 - 0000000000000000, R10 - 00000000061E2E52
R11 - 0000000000000020, R12 - 0000000003EE5C1F, R13 - 00000000061E0FF4
R14 - 0000000003E10D80, R15 - 00000000061E2F60
DS - 0000000000000030, ES - 0000000000000030, FS - 0000000000000030
GS - 0000000000000030, SS - 0000000000000030
CR0 - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
CR4 - 0000000000000668, CR8 - 0000000000000000
DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 00000000079EEA98 0000000000000047, LDTR - 0000000000000000
IDTR - 0000000007598018 0000000000000FFF, TR - 0000000000000000
FXSAVE_STATE - 0000000007F0F4C0
Proposal here is to continue to free allocated memory for
exit boot services path but keep it for halt/reboot path
as it won't be much security concern here.
Introduced GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY
loader flag to be used by efi halt/reboot path.
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/arm/efi/init.c | 3 +++
grub-core/kern/arm64/efi/init.c | 3 +++
grub-core/kern/efi/efi.c | 3 ++-
grub-core/kern/efi/init.c | 1 -
grub-core/kern/i386/efi/init.c | 9 +++++++--
grub-core/kern/ia64/efi/init.c | 9 +++++++--
grub-core/kern/riscv/efi/init.c | 3 +++
grub-core/lib/efi/halt.c | 3 ++-
include/grub/loader.h | 1 +
9 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c
index 06df60e2f..40c3b467f 100644
--- a/grub-core/kern/arm/efi/init.c
+++ b/grub-core/kern/arm/efi/init.c
@@ -71,4 +71,7 @@ grub_machine_fini (int flags)
efi_call_1 (b->close_event, tmr_evt);
grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}
diff --git a/grub-core/kern/arm64/efi/init.c b/grub-core/kern/arm64/efi/init.c
index 6224999ec..5010caefd 100644
--- a/grub-core/kern/arm64/efi/init.c
+++ b/grub-core/kern/arm64/efi/init.c
@@ -57,4 +57,7 @@ grub_machine_fini (int flags)
return;
grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index 535e29424..e0165e74c 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -157,7 +157,8 @@ grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
void
grub_reboot (void)
{
- grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
+ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
+ GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
efi_call_4 (grub_efi_system_table->runtime_services->reset_system,
GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL);
for (;;) ;
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index 3dfdf2d22..2c31847bf 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -80,5 +80,4 @@ grub_efi_fini (void)
{
grub_efidisk_fini ();
grub_console_fini ();
- grub_efi_memory_fini ();
}
diff --git a/grub-core/kern/i386/efi/init.c b/grub-core/kern/i386/efi/init.c
index da499aba0..deb2eacd8 100644
--- a/grub-core/kern/i386/efi/init.c
+++ b/grub-core/kern/i386/efi/init.c
@@ -39,6 +39,11 @@ grub_machine_init (void)
void
grub_machine_fini (int flags)
{
- if (flags & GRUB_LOADER_FLAG_NORETURN)
- grub_efi_fini ();
+ if (!(flags & GRUB_LOADER_FLAG_NORETURN))
+ return;
+
+ grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}
diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c
index b5ecbd091..f1965571b 100644
--- a/grub-core/kern/ia64/efi/init.c
+++ b/grub-core/kern/ia64/efi/init.c
@@ -70,6 +70,11 @@ grub_machine_init (void)
void
grub_machine_fini (int flags)
{
- if (flags & GRUB_LOADER_FLAG_NORETURN)
- grub_efi_fini ();
+ if (!(flags & GRUB_LOADER_FLAG_NORETURN))
+ return;
+
+ grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}
diff --git a/grub-core/kern/riscv/efi/init.c b/grub-core/kern/riscv/efi/init.c
index 7eb1969d0..38795fe67 100644
--- a/grub-core/kern/riscv/efi/init.c
+++ b/grub-core/kern/riscv/efi/init.c
@@ -73,4 +73,7 @@ grub_machine_fini (int flags)
return;
grub_efi_fini ();
+
+ if (!(flags & GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY))
+ grub_efi_memory_fini ();
}
diff --git a/grub-core/lib/efi/halt.c b/grub-core/lib/efi/halt.c
index 5859f0498..29d413641 100644
--- a/grub-core/lib/efi/halt.c
+++ b/grub-core/lib/efi/halt.c
@@ -28,7 +28,8 @@
void
grub_halt (void)
{
- grub_machine_fini (GRUB_LOADER_FLAG_NORETURN);
+ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN |
+ GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY);
#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && \
!defined(__riscv)
grub_acpi_halt ();
diff --git a/include/grub/loader.h b/include/grub/loader.h
index 7f82a499f..b20864282 100644
--- a/include/grub/loader.h
+++ b/include/grub/loader.h
@@ -33,6 +33,7 @@ enum
{
GRUB_LOADER_FLAG_NORETURN = 1,
GRUB_LOADER_FLAG_PXE_NOT_UNLOAD = 2,
+ GRUB_LOADER_FLAG_EFI_KEEP_ALLOCATED_MEMORY = 4,
};
void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void),
--
2.11.0
- [SECURITY PATCH 12/28] term: Fix overflow on user inputs, (continued)
- [SECURITY PATCH 12/28] term: Fix overflow on user inputs, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 13/28] udf: Fix memory leak, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 14/28] multiboot2: Fix memory leak if grub_create_loader_cmdline() fails, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 15/28] tftp: Do not use priority queue, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 18/28] script: Remove unused fields from grub_script_function struct, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 19/28] script: Avoid a use-after-free when redefining a function during execution, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 22/28] lvm: Fix two more potential data-dependent alloc overflows, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 23/28] emu: Make grub_free(NULL) safe, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 24/28] efi: Fix some malformed device path arithmetic errors, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 25/28] efi/chainloader: Propagate errors from copy_file_path(), Daniel Kiper, 2020/07/29
- [SECURITY PATCH 26/28] efi: Fix use-after-free in halt/reboot path,
Daniel Kiper <=
- [SECURITY PATCH 27/28] loader/linux: Avoid overflow on initrd size calculation, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 28/28] linux: Fix integer overflows in initrd size handling, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 09/28] xnu: Fix double free in grub_xnu_devprop_add_property(), Daniel Kiper, 2020/07/29
- [SECURITY PATCH 16/28] relocator: Protect grub_relocator_alloc_chunk_addr() input args against integer underflow/overflow, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 17/28] relocator: Protect grub_relocator_alloc_chunk_align() max_addr against integer underflow, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 20/28] relocator: Fix grub_relocator_alloc_chunk_align() top memory allocation, Daniel Kiper, 2020/07/29
- [SECURITY PATCH 21/28] hfsplus: Fix two more overflows, Daniel Kiper, 2020/07/29
- Re: [SECURITY PATCH 00/28] Multiple GRUB2 vulnerabilities - BootHole, Christian Hesse, 2020/07/29