From: Maxim Suhanov <dfirb...@gmail.com>

This allows users to restrict the "search" command's scope to
encrypted disks only.

Typically, this command is used to "rebase" $root and $prefix
before loading additional configuration files via "source" or
"configfile". Unfortunately, this leads to security problems,
like CVE-2023-4001, when an unexpected, attacker-controlled
device is chosen by the "search" command.

The --cryptodisk-only argument allows users to ensure that the
file system picked is encrypted.

This feature supports the CLI authentication, blocking bypass
attempts.

Signed-off-by: Maxim Suhanov <dfirb...@gmail.com>
Reviewed-by: Daniel Kiper <daniel.ki...@oracle.com>
---
 grub-core/commands/search.c      | 20 ++++++++++++++++++++
 grub-core/commands/search_wrap.c |  7 ++++++-
 grub-core/normal/main.c          |  3 ++-
 include/grub/search.h            |  7 ++++---
 4 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 263f1501c..f6bfef958 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -86,6 +86,26 @@ iterate_device (const char *name, void *data)
       grub_device_close (dev);
     }
 
+  /* Limit to encrypted disks when requested. */
+  if (ctx->flags & SEARCH_FLAGS_CRYPTODISK_ONLY)
+    {
+      grub_device_t dev;
+
+      dev = grub_device_open (name);
+      if (dev == NULL)
+       {
+         grub_errno = GRUB_ERR_NONE;
+         return 0;
+       }
+      if (dev->disk == NULL || dev->disk->dev->id != 
GRUB_DISK_DEVICE_CRYPTODISK_ID)
+       {
+         grub_device_close (dev);
+         grub_errno = GRUB_ERR_NONE;
+         return 0;
+       }
+      grub_device_close (dev);
+    }
+
 #ifdef DO_SEARCH_FS_UUID
 #define compare_fn grub_strcasecmp
 #else
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
index 318581f3b..5f536006c 100644
--- a/grub-core/commands/search_wrap.c
+++ b/grub-core/commands/search_wrap.c
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
      ARG_TYPE_STRING},
     {"no-floppy",      'n', 0, N_("Do not probe any floppy drive."), 0, 0},
     {"efidisk-only",   0, 0, N_("Only probe EFI disks."), 0, 0},
+    {"cryptodisk-only",        0, 0, N_("Only probe encrypted disks."), 0, 0},
     {"hint",           'h', GRUB_ARG_OPTION_REPEATABLE,
      N_("First try the device HINT. If HINT ends in comma, "
        "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
@@ -75,6 +76,7 @@ enum options
     SEARCH_SET,
     SEARCH_NO_FLOPPY,
     SEARCH_EFIDISK_ONLY,
+    SEARCH_CRYPTODISK_ONLY,
     SEARCH_HINT,
     SEARCH_HINT_IEEE1275,
     SEARCH_HINT_BIOS,
@@ -189,6 +191,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char 
**args)
   if (state[SEARCH_EFIDISK_ONLY].set)
     flags |= SEARCH_FLAGS_EFIDISK_ONLY;
 
+  if (state[SEARCH_CRYPTODISK_ONLY].set)
+    flags |= SEARCH_FLAGS_CRYPTODISK_ONLY;
+
   if (state[SEARCH_LABEL].set)
     grub_search_label (id, var, flags, hints, nhints);
   else if (state[SEARCH_FS_UUID].set)
@@ -210,7 +215,7 @@ GRUB_MOD_INIT(search)
   cmd =
     grub_register_extcmd ("search", grub_cmd_search,
                          GRUB_COMMAND_FLAG_EXTRACTOR | 
GRUB_COMMAND_ACCEPT_DASH,
-                         N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
+                         N_("[-f|-l|-u|-s|-n] [--cryptodisk-only] [--hint HINT 
[--hint HINT] ...]"
                             " NAME"),
                          N_("Search devices by file, filesystem label"
                             " or filesystem UUID."
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index 04d058f55..96abfda2f 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -511,7 +511,8 @@ static const char *features[] = {
   "feature_chainloader_bpb", "feature_ntldr", "feature_platform_search_hint",
   "feature_default_font_path", "feature_all_video_module",
   "feature_menuentry_id", "feature_menuentry_options", "feature_200_final",
-  "feature_nativedisk_cmd", "feature_timeout_style"
+  "feature_nativedisk_cmd", "feature_timeout_style",
+  "feature_search_cryptodisk_only"
 };
 
 GRUB_MOD_INIT(normal)
diff --git a/include/grub/search.h b/include/grub/search.h
index ffd2411ca..3eabaf0cc 100644
--- a/include/grub/search.h
+++ b/include/grub/search.h
@@ -21,9 +21,10 @@
 
 enum search_flags
   {
-    SEARCH_FLAGS_NONE          = 0,
-    SEARCH_FLAGS_NO_FLOPPY     = 1,
-    SEARCH_FLAGS_EFIDISK_ONLY  = 2
+    SEARCH_FLAGS_NONE            = 0,
+    SEARCH_FLAGS_NO_FLOPPY       = 1,
+    SEARCH_FLAGS_EFIDISK_ONLY    = 2,
+    SEARCH_FLAGS_CRYPTODISK_ONLY = 4
   };
 
 void grub_search_fs_file (const char *key, const char *var,
-- 
2.11.0


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to