Other verifiers that implement secure boot may want to be able to reuse the same list and behaviour.
Signed-off-by: Daniel Axtens <d...@axtens.net> --- grub-core/commands/efi/shim_lock.c | 45 +++++++++++------------------ grub-core/commands/verifiers.c | 46 ++++++++++++++++++++++++++++++ include/grub/verify.h | 13 +++++++++ 3 files changed, 75 insertions(+), 29 deletions(-) diff --git a/grub-core/commands/efi/shim_lock.c b/grub-core/commands/efi/shim_lock.c index 764098cfc83e..bad594b4620d 100644 --- a/grub-core/commands/efi/shim_lock.c +++ b/grub-core/commands/efi/shim_lock.c @@ -42,16 +42,12 @@ typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t; static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID; static grub_efi_shim_lock_protocol_t *sl; -/* List of modules which cannot be loaded if UEFI secure boot mode is enabled. */ -static const char * const disabled_mods[] = {"iorw", "memrw", "wrmsr", NULL}; - static grub_err_t shim_lock_init (grub_file_t io, enum grub_file_type type, void **context __attribute__ ((unused)), enum grub_verify_flags *flags) { - const char *b, *e; - int i; + const char *dangerous_mod; *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; @@ -61,22 +57,13 @@ shim_lock_init (grub_file_t io, enum grub_file_type type, switch (type & GRUB_FILE_TYPE_MASK) { case GRUB_FILE_TYPE_GRUB_MODULE: - /* Establish GRUB module name. */ - b = grub_strrchr (io->name, '/'); - e = grub_strrchr (io->name, '.'); - - b = b ? (b + 1) : io->name; - e = e ? e : io->name + grub_strlen (io->name); - e = (e > b) ? e : io->name + grub_strlen (io->name); - - for (i = 0; disabled_mods[i]; i++) - if (!grub_strncmp (b, disabled_mods[i], grub_strlen (b) - grub_strlen (e))) - { - grub_error (GRUB_ERR_ACCESS_DENIED, - N_("module cannot be loaded in UEFI secure boot mode: %s"), - io->name); - return GRUB_ERR_ACCESS_DENIED; - } + if (grub_is_dangerous_module (io)) + { + grub_error (GRUB_ERR_ACCESS_DENIED, + N_("module cannot be loaded in UEFI secure boot mode: %s"), + io->name); + return GRUB_ERR_ACCESS_DENIED; + } /* Fall through. */ @@ -91,14 +78,14 @@ shim_lock_init (grub_file_t io, enum grub_file_type type, case GRUB_FILE_TYPE_BSD_KERNEL: case GRUB_FILE_TYPE_XNU_KERNEL: case GRUB_FILE_TYPE_PLAN9_KERNEL: - for (i = 0; disabled_mods[i]; i++) - if (grub_dl_get (disabled_mods[i])) - { - grub_error (GRUB_ERR_ACCESS_DENIED, - N_("cannot boot due to dangerous module in memory: %s"), - disabled_mods[i]); - return GRUB_ERR_ACCESS_DENIED; - } + dangerous_mod = grub_dangerous_module_loaded (); + if (dangerous_mod) + { + grub_error (GRUB_ERR_ACCESS_DENIED, + N_("cannot boot due to dangerous module in memory: %s"), + dangerous_mod); + return GRUB_ERR_ACCESS_DENIED; + } *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK; diff --git a/grub-core/commands/verifiers.c b/grub-core/commands/verifiers.c index aae4d84bb118..1d67a2541dae 100644 --- a/grub-core/commands/verifiers.c +++ b/grub-core/commands/verifiers.c @@ -221,6 +221,52 @@ grub_verify_string (char *str, enum grub_verify_string_type type) return GRUB_ERR_NONE; } +/* List of modules which may allow for verifcation to be bypassed. */ +static const char *const disabled_mods[] = { "iorw", "memrw", "wrmsr", NULL }; + +/* + * Does the module in file `io' allow for the a verifier to be bypassed? + * + * Returns 1 if so, otherwise 0. + */ +char +grub_is_dangerous_module (grub_file_t io) +{ + char *b, *e; + int i; + + /* Establish GRUB module name. */ + b = grub_strrchr (io->name, '/'); + e = grub_strrchr (io->name, '.'); + + b = b ? (b + 1) : io->name; + e = e ? e : io->name + grub_strlen (io->name); + e = (e > b) ? e : io->name + grub_strlen (io->name); + + for (i = 0; disabled_mods[i]; i++) + if (!grub_strncmp (b, disabled_mods[i], + grub_strlen (b) - grub_strlen (e))) + return 1; + return 0; +} + +/* + * Is there already an unsafe module in memory? + * Returns the name if one is loaded, otherwise NULL. + */ +const char * +grub_dangerous_module_loaded (void) +{ + int i; + + for (i = 0; disabled_mods[i]; i++) + if (grub_dl_get (disabled_mods[i])) + { + return disabled_mods[i]; + } + return NULL; +} + GRUB_MOD_INIT(verifiers) { grub_file_filter_register (GRUB_FILE_FILTER_VERIFY, grub_verifiers_open); diff --git a/include/grub/verify.h b/include/grub/verify.h index ea049143368e..8c2de132051d 100644 --- a/include/grub/verify.h +++ b/include/grub/verify.h @@ -81,4 +81,17 @@ grub_verifier_unregister (struct grub_file_verifier *ver) grub_err_t grub_verify_string (char *str, enum grub_verify_string_type type); +/* + * Does the module in file `io' allow for the a verifier to be bypassed? + * + * Returns 1 if so, otherwise 0. + */ +char grub_is_dangerous_module (grub_file_t io); + +/* + * Is there already an unsafe module in memory? + * Returns the name if one is loaded, otherwise NULL. + */ +const char *grub_dangerous_module_loaded (void); + #endif /* ! GRUB_VERIFY_HEADER */ -- 2.25.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel