mirror of
https://github.com/ventoy/Ventoy.git
synced 2025-04-29 22:57:54 -04:00
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> Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
80 lines
2.7 KiB
C
80 lines
2.7 KiB
C
/* loader.h - OS loaders */
|
|
/*
|
|
* GRUB -- GRand Unified Bootloader
|
|
* Copyright (C) 2002,2003,2004,2006,2007,2009 Free Software Foundation, Inc.
|
|
*
|
|
* GRUB is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GRUB is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef GRUB_LOADER_HEADER
|
|
#define GRUB_LOADER_HEADER 1
|
|
|
|
#include <grub/file.h>
|
|
#include <grub/symbol.h>
|
|
#include <grub/err.h>
|
|
#include <grub/types.h>
|
|
|
|
/* Check if a loader is loaded. */
|
|
int EXPORT_FUNC (grub_loader_is_loaded) (void);
|
|
|
|
/* Set loader functions. */
|
|
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),
|
|
grub_err_t (*unload) (void),
|
|
int flags);
|
|
|
|
/* Unset current loader, if any. */
|
|
void EXPORT_FUNC (grub_loader_unset) (void);
|
|
|
|
/* Call the boot hook in current loader. This may or may not return,
|
|
depending on the setting by grub_loader_set. */
|
|
grub_err_t grub_loader_boot (void);
|
|
|
|
/* The space between numbers is intentional for the simplicity of adding new
|
|
values even if external modules use them. */
|
|
typedef enum {
|
|
/* A preboot hook which can use everything and turns nothing off. */
|
|
GRUB_LOADER_PREBOOT_HOOK_PRIO_NORMAL = 400,
|
|
/* A preboot hook which can't use disks and may stop disks. */
|
|
GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK = 300,
|
|
/* A preboot hook which can't use disks or console and may stop console. */
|
|
GRUB_LOADER_PREBOOT_HOOK_PRIO_CONSOLE = 200,
|
|
/* A preboot hook which can't use disks or console, can't modify memory map
|
|
and may stop memory services or finalize memory map. */
|
|
GRUB_LOADER_PREBOOT_HOOK_PRIO_MEMORY = 100,
|
|
} grub_loader_preboot_hook_prio_t;
|
|
|
|
/* Register a preboot hook. */
|
|
struct grub_preboot;
|
|
|
|
struct grub_preboot *EXPORT_FUNC(grub_loader_register_preboot_hook) (grub_err_t (*preboot_func) (int noret),
|
|
grub_err_t (*preboot_rest_func) (void),
|
|
grub_loader_preboot_hook_prio_t prio);
|
|
|
|
/* Unregister given preboot hook. */
|
|
void EXPORT_FUNC (grub_loader_unregister_preboot_hook) (struct grub_preboot *hnd);
|
|
|
|
#ifndef GRUB_MACHINE_EMU
|
|
void grub_boot_init (void);
|
|
void grub_boot_fini (void);
|
|
#endif
|
|
|
|
#endif /* ! GRUB_LOADER_HEADER */
|