Ventoy Secure Boot Policy Update

- Update Ventoy grub code to match the new policy.
This commit is contained in:
longpanda
2026-06-23 21:19:46 +08:00
parent 71ac855b36
commit 1ed7bc9596
8 changed files with 562 additions and 190 deletions

View File

@@ -0,0 +1,195 @@
/* corecmd.c - critical commands which are registered in kernel */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/>.
*/
#include <grub/mm.h>
#include <grub/dl.h>
#include <grub/err.h>
#include <grub/env.h>
#include <grub/misc.h>
#include <grub/term.h>
#include <grub/file.h>
#include <grub/device.h>
#include <grub/command.h>
#include <grub/i18n.h>
/* set ENVVAR=VALUE */
static grub_err_t
grub_core_cmd_set (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
char *var;
char *val;
if (argc < 1)
{
struct grub_env_var *env;
FOR_SORTED_ENV (env)
grub_printf ("%s=%s\n", env->name, grub_env_get (env->name));
return 0;
}
var = argv[0];
val = grub_strchr (var, '=');
if (! val)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "not an assignment");
val[0] = 0;
grub_env_set (var, val + 1);
val[0] = '=';
return 0;
}
static grub_err_t
grub_core_cmd_unset (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("one argument expected"));
grub_env_unset (argv[0]);
return 0;
}
/* insmod MODULE */
static grub_err_t
grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_dl_t mod;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
/* For simple, just disable insmod when SecureBoot is enabled. */
if (g_sys_sb && g_sb_policy == VTOY_SB_POLICY_CHECK)
{
return grub_error (GRUB_ERR_BAD_SIGNATURE, "Cannot insmod when SecureBoot is enabled and Policy is check.");
}
if (argv[0][0] == '/' || argv[0][0] == '(' || argv[0][0] == '+')
mod = grub_dl_load_file (argv[0]);
else
mod = grub_dl_load (argv[0]);
if (mod)
grub_dl_ref (mod);
return 0;
}
static int
grub_mini_print_devices (const char *name, void *data __attribute__ ((unused)))
{
grub_printf ("(%s) ", name);
return 0;
}
static int
grub_mini_print_files (const char *filename,
const struct grub_dirhook_info *info,
void *data __attribute__ ((unused)))
{
grub_printf ("%s%s ", filename, info->dir ? "/" : "");
return 0;
}
/* ls [ARG] */
static grub_err_t
grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
if (argc < 1)
{
grub_device_iterate (grub_mini_print_devices, NULL);
grub_xputs ("\n");
grub_refresh ();
}
else
{
char *device_name;
grub_device_t dev = 0;
grub_fs_t fs;
char *path;
device_name = grub_file_get_device_name (argv[0]);
if (grub_errno)
goto fail;
dev = grub_device_open (device_name);
if (! dev)
goto fail;
fs = grub_fs_probe (dev);
path = grub_strchr (argv[0], ')');
if (! path)
path = argv[0];
else
path++;
if (! *path && ! device_name)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
goto fail;
}
if (! *path)
{
if (grub_errno == GRUB_ERR_UNKNOWN_FS)
grub_errno = GRUB_ERR_NONE;
grub_printf ("(%s): Filesystem is %s.\n",
device_name, fs ? fs->name : "unknown");
}
else if (fs)
{
(fs->fs_dir) (dev, path, grub_mini_print_files, NULL);
grub_xputs ("\n");
grub_refresh ();
}
fail:
if (dev)
grub_device_close (dev);
grub_free (device_name);
}
return grub_errno;
}
void
grub_register_core_commands (void)
{
grub_command_t cmd;
cmd = grub_register_command ("set", grub_core_cmd_set,
N_("[ENVVAR=VALUE]"),
N_("Set an environment variable."));
if (cmd)
cmd->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
grub_register_command ("unset", grub_core_cmd_unset,
N_("ENVVAR"),
N_("Remove an environment variable."));
grub_register_command ("ls", grub_core_cmd_ls,
N_("[ARG]"), N_("List devices or files."));
grub_register_command ("insmod", grub_core_cmd_insmod,
N_("MODULE"), N_("Insert a module."));
}

View File

@@ -22,6 +22,9 @@
#include <grub/misc.h>
#include <grub/mm.h>
grub_uint8_t g_sys_sb = 0;
grub_uint8_t g_sb_policy = VTOY_SB_POLICY_BYPASS;
/* The initial context. */
static struct grub_env_context initial_context;

View File

@@ -35,6 +35,8 @@
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
#include <grub/linux.h>
#include <grub/time.h>
#include <grub/env.h>
#include <grub/machine/kernel.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -750,6 +752,16 @@ grub_linux_boot (void)
grub_size_t mmap_size;
grub_size_t cl_offset;
/* To be simple, just deny to boot linux kernel when SecureBoot is enabled and Policy is check */
if (g_sys_sb && g_sb_policy == VTOY_SB_POLICY_CHECK)
{
grub_printf("\n\n ######### Can not do linux boot in SecureBoot Policy Check #######\n\n");
grub_refresh();
grub_sleep(5);
grub_errno = GRUB_ERR_BAD_SIGNATURE;
return 0;
}
ventoy_preboot();
#ifdef GRUB_MACHINE_IEEE1275

View File

@@ -49,6 +49,8 @@ int g_ventoy_debug = 0;
static int g_efi_os = 0xFF;
grub_uint32_t g_ventoy_plat_data;
static VTOY_SHIM *g_vtoy_shim = NULL;
void ventoy_debug(const char *fmt, ...)
{
va_list args;
@@ -298,9 +300,119 @@ void ventoy_memfile_env_set(const char *prefix, const void *buf, unsigned long l
return;
}
#ifdef GRUB_MACHINE_EFI
static void ventoy_get_uefi_version(char *str, grub_size_t len)
{
grub_efi_uint8_t uefi_minor_1, uefi_minor_2;
uefi_minor_1 = (grub_efi_system_table->hdr.revision & 0xffff) / 10;
uefi_minor_2 = (grub_efi_system_table->hdr.revision & 0xffff) % 10;
grub_snprintf(str, len, "%d.%d", (grub_efi_system_table->hdr.revision >> 16), uefi_minor_1);
if (uefi_minor_2)
grub_snprintf(str, len, "%s.%d", str, uefi_minor_2);
}
int ventoy_set_sb_policy(void)
{
const char *env = NULL;
static int set_once = 0;
/* no need when SecureBoot is disabled */
if (g_sys_sb == 0)
{
return 0;
}
/* can only set once */
if (set_once > 0)
{
return 0;
}
set_once = 1;
/* VTOY_SECURE_BOOT_POLICY only take affect once during init */
env = grub_env_get("VTOY_SECURE_BOOT_POLICY");
if (env)
{
g_sb_policy = (grub_uint8_t)(env[0] - '0');
}
if (g_sb_policy == VTOY_SB_POLICY_BYPASS)
{
if (g_vtoy_shim && g_vtoy_shim->ByPassSB)
{
g_vtoy_shim->ByPassSB();
}
}
else if (g_sb_policy == VTOY_SB_POLICY_CHECK)
{
if (g_vtoy_shim && g_vtoy_shim->CheckSB)
{
g_vtoy_shim->CheckSB();
}
}
return 0;
}
static void ventoy_get_uefi_sb(void)
{
grub_uint8_t *var = NULL;
grub_size_t size = 0;
grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
var = grub_efi_get_variable("SecureBoot", &global, &size);
if (var && size == 1 && *var == 1)
{
g_sys_sb = 1;
}
grub_check_free(var);
}
static int ventoy_secure_boot_init(void)
{
grub_efi_guid_t ProtGuid = VTOY_SHIM_POLICY_GUID;
ventoy_get_uefi_sb();
if (g_sys_sb == 0)
{
return 0;
}
/*
* When SecureBoot enabled, Ventoy grub must be launched by Ventoy Shim.
* Currently only x86_64 support this feature.
*/
if (g_ventoy_plat_data == VTOY_PLAT_X86_64_UEFI)
{
g_vtoy_shim = grub_efi_locate_protocol(&ProtGuid, NULL);
if (g_vtoy_shim == NULL || g_vtoy_shim->ByPassSB == NULL || g_vtoy_shim->CheckSB == NULL)
{
grub_cls();
grub_printf(VTOY_WARNING"\n");
grub_printf(VTOY_WARNING"\n");
grub_printf(VTOY_WARNING"\n\n\n");
grub_printf("Ventoy grub is not launched by Ventoy shim.\n\n");
grub_refresh();
ventoy_prompt_end();
}
}
return 0;
}
#endif
static int ventoy_arch_mode_init(void)
{
#ifdef GRUB_MACHINE_EFI
if (grub_strcmp(GRUB_TARGET_CPU, "i386") == 0)
{
g_ventoy_plat_data = VTOY_PLAT_I386_UEFI;
@@ -329,19 +441,6 @@ static int ventoy_arch_mode_init(void)
return 0;
}
#ifdef GRUB_MACHINE_EFI
static void ventoy_get_uefi_version(char *str, grub_size_t len)
{
grub_efi_uint8_t uefi_minor_1, uefi_minor_2;
uefi_minor_1 = (grub_efi_system_table->hdr.revision & 0xffff) / 10;
uefi_minor_2 = (grub_efi_system_table->hdr.revision & 0xffff) % 10;
grub_snprintf(str, len, "%d.%d", (grub_efi_system_table->hdr.revision >> 16), uefi_minor_1);
if (uefi_minor_2)
grub_snprintf(str, len, "%s.%d", str, uefi_minor_2);
}
#endif
static int ventoy_calc_totalmem(grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, void *data)
{
grub_uint64_t *total_mem = (grub_uint64_t *)data;
@@ -497,6 +596,11 @@ GRUB_MOD_INIT(ventoy)
ventoy_hwinfo_init();
ventoy_env_init();
ventoy_arch_mode_init();
#ifdef GRUB_MACHINE_EFI
ventoy_secure_boot_init();
#endif
ventoy_register_all_cmd();
}

View File

@@ -4723,7 +4723,7 @@ static grub_err_t ventoy_cmd_img_unhook_root(grub_extcmd_context_t ctxt, int arg
static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args)
{
int ret = 1;
grub_uint8_t *var;
grub_uint8_t *var = NULL;
grub_size_t size;
grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
@@ -4734,6 +4734,7 @@ static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, in
var = grub_efi_get_variable("SecureBoot", &global, &size);
if (var && *var == 1)
{
grub_free(var);
return 0;
}
@@ -5118,7 +5119,7 @@ int ventoy_load_part_table(const char *diskname)
return 0;
}
static void ventoy_prompt_end(void)
void ventoy_prompt_end(void)
{
int op = 0;
char c;
@@ -6412,6 +6413,40 @@ static grub_err_t ventoy_cmd_load_menu_lang(grub_extcmd_context_t ctxt, int argc
VENTOY_CMD_RETURN(0);
}
static grub_err_t ventoy_cmd_sb_info(grub_extcmd_context_t ctxt, int argc, char **args)
{
const char *policy = NULL;
(void)ctxt;
(void)argc;
(void)args;
#ifdef GRUB_MACHINE_EFI
if (g_sb_policy == VTOY_SB_POLICY_BYPASS)
{
policy = "ByPass";
}
else if (g_sb_policy == VTOY_SB_POLICY_CHECK)
{
policy = "Check";
}
else
{
policy = "XXX";
}
grub_printf("UEFI Firmware Secure Boot: %s\n", g_sys_sb ? "Enable" : "Disable");
grub_printf("Ventoy Secure Boot Policy: %s\n", policy);
#else
grub_printf("Non EFI mode!\n");
#endif
grub_refresh();
VENTOY_CMD_RETURN(0);
}
static int ventoy_chksum_pathcmp(int chktype, char *rlpath, char *rdpath)
{
char *pos1 = NULL;
@@ -7060,6 +7095,8 @@ static cmd_para ventoy_cmds[] =
{ "vt_pop_menu_lang", ventoy_cmd_pop_menulang, 0, NULL, "", "", NULL },
{ "vt_linux_initrd", ventoy_cmd_linux_initrd, 0, NULL, "", "", NULL },
{ "vt_sbinfo", ventoy_cmd_sb_info, 0, NULL, "", "", NULL },
};
int ventoy_register_all_cmd(void)

View File

@@ -195,6 +195,16 @@ typedef struct cpio_newc_header
#define check_free(p, func) if (p) { func(p); p = NULL; }
#define grub_check_free(p) if (p) { grub_free(p); p = NULL; }
#define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }};
typedef void (*VTOY_BYPASS_SB)(void);
typedef void (*VTOY_CHECK_SB)(void);
typedef struct _VTOY_SHIM{
VTOY_BYPASS_SB ByPassSB;
VTOY_CHECK_SB CheckSB;
} VTOY_SHIM;
typedef int (*grub_char_check_func)(int c);
#define ventoy_is_decimal(str) ventoy_string_check(str, grub_isdigit)
@@ -1326,6 +1336,8 @@ int ventoy_ctrl_var_init(void);
int ventoy_global_var_init(void);
grub_err_t ventoy_cmd_push_menulang(grub_extcmd_context_t ctxt, int argc, char **args);
grub_err_t ventoy_cmd_pop_menulang(grub_extcmd_context_t ctxt, int argc, char **args);
void ventoy_prompt_end(void);
int ventoy_set_sb_policy(void);
#endif /* __VENTOY_DEF_H__ */

View File

@@ -2556,6 +2556,10 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a
grub_env_unset("VTOY_MENU_TIP_ENABLE");
}
#ifdef GRUB_MACHINE_EFI
ventoy_set_sb_policy();
#endif
VENTOY_CMD_RETURN(GRUB_ERR_NONE);
}

View File

@@ -24,6 +24,11 @@
#include <grub/types.h>
#include <grub/menu.h>
#define VTOY_SB_POLICY_BYPASS 0
#define VTOY_SB_POLICY_CHECK 1
extern grub_uint8_t EXPORT_VAR(g_sys_sb);
extern grub_uint8_t EXPORT_VAR(g_sb_policy);
struct grub_env_var;
typedef const char *(*grub_env_read_hook_t) (struct grub_env_var *var,