Accepting request 1221631 from Base:System
OBS-URL: https://build.opensuse.org/request/show/1221631 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/grub2?expand=0&rev=339
This commit is contained in:
374
0001-cli_lock-Add-build-option-to-block-command-line-inte.patch
Normal file
374
0001-cli_lock-Add-build-option-to-block-command-line-inte.patch
Normal file
@@ -0,0 +1,374 @@
|
||||
From c7dd3dd296592fef6166170121b54aafe634369f Mon Sep 17 00:00:00 2001
|
||||
From: Alec Brown <alec.r.brown@oracle.com>
|
||||
Date: Wed, 24 Jan 2024 06:26:37 +0000
|
||||
Subject: [PATCH 1/2] cli_lock: Add build option to block command line
|
||||
interface
|
||||
|
||||
Add functionality to disable command line interface access and editing of GRUB
|
||||
menu entries if GRUB image is built with --disable-cli.
|
||||
|
||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
||||
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 6 ++++--
|
||||
grub-core/kern/main.c | 28 ++++++++++++++++++++++++++++
|
||||
grub-core/kern/rescue_reader.c | 13 +++++++++++++
|
||||
grub-core/normal/auth.c | 3 +++
|
||||
grub-core/normal/menu_text.c | 31 +++++++++++++++++--------------
|
||||
include/grub/kernel.h | 3 ++-
|
||||
include/grub/misc.h | 2 ++
|
||||
include/grub/util/install.h | 8 ++++++--
|
||||
util/grub-install-common.c | 11 ++++++++---
|
||||
util/grub-mkimage.c | 9 ++++++++-
|
||||
util/mkimage.c | 16 +++++++++++++++-
|
||||
11 files changed, 106 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 00c5fdc44..e89007920 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -6523,8 +6523,10 @@ the GRUB command line, edit menu entries, and execute any menu entry. If
|
||||
@samp{superusers} is set, then use of the command line and editing of menu
|
||||
entries are automatically restricted to superusers. Setting @samp{superusers}
|
||||
to empty string effectively disables both access to CLI and editing of menu
|
||||
-entries. Note: The environment variable needs to be exported to also affect
|
||||
-the section defined by the @samp{submenu} command (@pxref{submenu}).
|
||||
+entries. Building a grub image with @samp{--disable-cli} option will also
|
||||
+disable access to CLI and editing of menu entries, as well as disabling rescue
|
||||
+mode. Note: The environment variable needs to be exported to also affect the
|
||||
+section defined by the @samp{submenu} command (@pxref{submenu}).
|
||||
|
||||
Other users may be allowed to execute specific menu entries by giving a list of
|
||||
usernames (as above) using the @option{--users} option to the
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 02df49206..07b6940d2 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -30,11 +30,14 @@
|
||||
#include <grub/reader.h>
|
||||
#include <grub/parser.h>
|
||||
#include <grub/verify.h>
|
||||
+#include <grub/types.h>
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
#include <grub/machine/memory.h>
|
||||
#endif
|
||||
|
||||
+static bool cli_disabled = false;
|
||||
+
|
||||
grub_addr_t
|
||||
grub_modules_get_end (void)
|
||||
{
|
||||
@@ -237,6 +240,28 @@ grub_load_normal_mode (void)
|
||||
grub_command_execute ("normal", 0, 0);
|
||||
}
|
||||
|
||||
+bool
|
||||
+grub_is_cli_disabled (void)
|
||||
+{
|
||||
+ return cli_disabled;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+check_is_cli_disabled (void)
|
||||
+{
|
||||
+ struct grub_module_header *header;
|
||||
+ header = 0;
|
||||
+
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ if (header->type == OBJ_TYPE_DISABLE_CLI)
|
||||
+ {
|
||||
+ cli_disabled = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
reclaim_module_space (void)
|
||||
{
|
||||
@@ -294,6 +319,9 @@ grub_main (void)
|
||||
|
||||
grub_boot_time ("After loading embedded modules.");
|
||||
|
||||
+ /* Check if the CLI should be disabled */
|
||||
+ check_is_cli_disabled ();
|
||||
+
|
||||
/* It is better to set the root device as soon as possible,
|
||||
for convenience. */
|
||||
grub_set_prefix_and_root ();
|
||||
diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c
|
||||
index dcd7d4439..4259857ba 100644
|
||||
--- a/grub-core/kern/rescue_reader.c
|
||||
+++ b/grub-core/kern/rescue_reader.c
|
||||
@@ -78,6 +78,19 @@ grub_rescue_read_line (char **line, int cont,
|
||||
void __attribute__ ((noreturn))
|
||||
grub_rescue_run (void)
|
||||
{
|
||||
+ /* Stall if the CLI has been disabled */
|
||||
+ if (grub_is_cli_disabled ())
|
||||
+ {
|
||||
+ grub_printf ("Rescue mode has been disabled...\n");
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ /* Do not optimize out the loop. */
|
||||
+ asm volatile ("");
|
||||
+ }
|
||||
+ while (1);
|
||||
+ }
|
||||
+
|
||||
grub_printf ("Entering rescue mode...\n");
|
||||
|
||||
while (1)
|
||||
diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c
|
||||
index 517fc623f..d94020186 100644
|
||||
--- a/grub-core/normal/auth.c
|
||||
+++ b/grub-core/normal/auth.c
|
||||
@@ -209,6 +209,9 @@ grub_auth_check_authentication (const char *userlist)
|
||||
char entered[GRUB_AUTH_MAX_PASSLEN];
|
||||
struct grub_auth_user *user;
|
||||
|
||||
+ if (grub_is_cli_disabled ())
|
||||
+ return GRUB_ACCESS_DENIED;
|
||||
+
|
||||
grub_memset (login, 0, sizeof (login));
|
||||
|
||||
if (is_authenticated (userlist))
|
||||
diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
|
||||
index ae92050d7..56c6f7797 100644
|
||||
--- a/grub-core/normal/menu_text.c
|
||||
+++ b/grub-core/normal/menu_text.c
|
||||
@@ -194,21 +194,24 @@ command-line or ESC to discard edits and return to the GRUB menu."),
|
||||
grub_free (msg_translated);
|
||||
#endif
|
||||
|
||||
- if (nested)
|
||||
+ if (!grub_is_cli_disabled ())
|
||||
{
|
||||
- ret += grub_print_message_indented_real
|
||||
- (_("Press enter to boot the selected OS, "
|
||||
- "`e' to edit the commands before booting "
|
||||
- "or `c' for a command-line. ESC to return previous menu."),
|
||||
- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- ret += grub_print_message_indented_real
|
||||
- (_("Press enter to boot the selected OS, "
|
||||
- "`e' to edit the commands before booting "
|
||||
- "or `c' for a command-line."),
|
||||
- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
+ if (nested)
|
||||
+ {
|
||||
+ ret += grub_print_message_indented_real
|
||||
+ (_("Press enter to boot the selected OS, "
|
||||
+ "`e' to edit the commands before booting "
|
||||
+ "or `c' for a command-line. ESC to return previous menu."),
|
||||
+ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ret += grub_print_message_indented_real
|
||||
+ (_("Press enter to boot the selected OS, "
|
||||
+ "`e' to edit the commands before booting "
|
||||
+ "or `c' for a command-line."),
|
||||
+ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
|
||||
index d3aafc884..9f3e2031f 100644
|
||||
--- a/include/grub/kernel.h
|
||||
+++ b/include/grub/kernel.h
|
||||
@@ -31,7 +31,8 @@ enum
|
||||
OBJ_TYPE_GPG_PUBKEY,
|
||||
OBJ_TYPE_X509_PUBKEY,
|
||||
OBJ_TYPE_DTB,
|
||||
- OBJ_TYPE_DISABLE_SHIM_LOCK
|
||||
+ OBJ_TYPE_DISABLE_SHIM_LOCK,
|
||||
+ OBJ_TYPE_DISABLE_CLI
|
||||
};
|
||||
|
||||
/* The module header. */
|
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||
index 1b35a167f..1578f36c3 100644
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -391,6 +391,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
|
||||
grub_uint64_t d,
|
||||
grub_uint64_t *r);
|
||||
|
||||
+extern bool EXPORT_FUNC(grub_is_cli_disabled) (void);
|
||||
+
|
||||
/* Must match softdiv group in gentpl.py. */
|
||||
#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
|
||||
(defined(__riscv) && (__riscv_xlen == 32)))
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 38c6da73b..a4aac7b85 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -72,6 +72,8 @@
|
||||
{ "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
|
||||
"SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
|
||||
1}, \
|
||||
+ { "disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, \
|
||||
+ N_("disabled command line interface access"), 0 }, \
|
||||
{ "verbose", 'v', 0, 0, \
|
||||
N_("print verbose messages."), 1 }
|
||||
|
||||
@@ -136,7 +138,8 @@ enum grub_install_options {
|
||||
GRUB_INSTALL_OPTIONS_DTB,
|
||||
GRUB_INSTALL_OPTIONS_SBAT,
|
||||
GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK,
|
||||
- GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE
|
||||
+ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,
|
||||
+ GRUB_INSTALL_OPTIONS_DISABLE_CLI
|
||||
};
|
||||
|
||||
extern char *grub_install_source_directory;
|
||||
@@ -199,7 +202,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
int note, size_t appsig_size,
|
||||
grub_compression_t comp, const char *dtb_file,
|
||||
- const char *sbat_path, const int disable_shim_lock);
|
||||
+ const char *sbat_path, const int disable_shim_lock,
|
||||
+ const int disable_cli);
|
||||
|
||||
const struct grub_install_image_target_desc *
|
||||
grub_install_get_image_target (const char *arg);
|
||||
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
|
||||
index 75fa03995..344dca664 100644
|
||||
--- a/util/grub-install-common.c
|
||||
+++ b/util/grub-install-common.c
|
||||
@@ -469,6 +469,7 @@ static char **x509keys;
|
||||
static size_t nx509keys;
|
||||
static grub_compression_t compression;
|
||||
static size_t appsig_size;
|
||||
+static int disable_cli;
|
||||
|
||||
int
|
||||
grub_install_parse (int key, char *arg)
|
||||
@@ -514,6 +515,9 @@ grub_install_parse (int key, char *arg)
|
||||
* (nx509keys + 1));
|
||||
x509keys[nx509keys++] = xstrdup (arg);
|
||||
return 1;
|
||||
+ case GRUB_INSTALL_OPTIONS_DISABLE_CLI:
|
||||
+ disable_cli = 1;
|
||||
+ return 1;
|
||||
|
||||
case GRUB_INSTALL_OPTIONS_VERBOSITY:
|
||||
verbosity++;
|
||||
@@ -707,12 +711,13 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
|
||||
grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'"
|
||||
" --format '%s' --compression '%s'"
|
||||
- " --appended-signature-size %zu%s%s%s\n",
|
||||
+ " --appended-signature-size %zu%s%s%s%s\n",
|
||||
dir, prefix, outname,
|
||||
mkimage_target, compnames[compression],
|
||||
appsig_size,
|
||||
note ? " --note" : "",
|
||||
- disable_shim_lock ? " --disable-shim-lock" : "", s);
|
||||
+ disable_shim_lock ? " --disable-shim-lock" : "",
|
||||
+ disable_cli ? " --disable-cli" : "", s);
|
||||
free (s);
|
||||
|
||||
tgt = grub_install_get_image_target (mkimage_target);
|
||||
@@ -724,7 +729,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
pubkeys, npubkeys, x509keys, nx509keys,
|
||||
config_path, tgt,
|
||||
note, appsig_size, compression, dtb, sbat,
|
||||
- disable_shim_lock);
|
||||
+ disable_shim_lock, disable_cli);
|
||||
while (dc--)
|
||||
grub_install_pop_module ();
|
||||
}
|
||||
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
|
||||
index 7d61ef3ea..351a5e430 100644
|
||||
--- a/util/grub-mkimage.c
|
||||
+++ b/util/grub-mkimage.c
|
||||
@@ -84,6 +84,7 @@ static struct argp_option options[] = {
|
||||
{"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
|
||||
{"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
|
||||
{"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0},
|
||||
+ {"disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, N_("disable command line interface access"), 0},
|
||||
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
||||
{"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
@@ -133,6 +134,7 @@ struct arguments
|
||||
int note;
|
||||
int disable_shim_lock;
|
||||
size_t appsig_size;
|
||||
+ int disable_cli;
|
||||
const struct grub_install_image_target_desc *image_target;
|
||||
grub_compression_t comp;
|
||||
};
|
||||
@@ -259,6 +261,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
||||
arguments->disable_shim_lock = 1;
|
||||
break;
|
||||
|
||||
+ case GRUB_INSTALL_OPTIONS_DISABLE_CLI:
|
||||
+ arguments->disable_cli = 1;
|
||||
+ break;
|
||||
+
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
@@ -347,7 +353,8 @@ main (int argc, char *argv[])
|
||||
arguments.image_target, arguments.note,
|
||||
arguments.appsig_size,
|
||||
arguments.comp, arguments.dtb,
|
||||
- arguments.sbat, arguments.disable_shim_lock);
|
||||
+ arguments.sbat, arguments.disable_shim_lock,
|
||||
+ arguments.disable_cli);
|
||||
|
||||
if (grub_util_file_sync (fp) < 0)
|
||||
grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout",
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 0737935fd..d6cc13475 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -889,7 +889,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
int note, size_t appsig_size, grub_compression_t comp,
|
||||
const char *dtb_path, const char *sbat_path,
|
||||
- int disable_shim_lock)
|
||||
+ int disable_shim_lock,
|
||||
+ int disable_cli)
|
||||
{
|
||||
char *kernel_img, *core_img;
|
||||
size_t total_module_size, core_size;
|
||||
@@ -964,6 +965,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
if (disable_shim_lock)
|
||||
total_module_size += sizeof (struct grub_module_header);
|
||||
|
||||
+ if (disable_cli)
|
||||
+ total_module_size += sizeof (struct grub_module_header);
|
||||
+
|
||||
if (config_path)
|
||||
{
|
||||
config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
|
||||
@@ -1130,6 +1134,16 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
offset += sizeof (*header);
|
||||
}
|
||||
|
||||
+ if (disable_cli)
|
||||
+ {
|
||||
+ struct grub_module_header *header;
|
||||
+
|
||||
+ header = (struct grub_module_header *) (kernel_img + offset);
|
||||
+ header->type = grub_host_to_target32 (OBJ_TYPE_DISABLE_CLI);
|
||||
+ header->size = grub_host_to_target32 (sizeof (*header));
|
||||
+ offset += sizeof (*header);
|
||||
+ }
|
||||
+
|
||||
if (config_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
--
|
||||
2.46.0
|
||||
|
66
0001-kern-main-Fix-cmdpath-in-root-directory.patch
Normal file
66
0001-kern-main-Fix-cmdpath-in-root-directory.patch
Normal file
@@ -0,0 +1,66 @@
|
||||
From 56b221476d31310de485af26550c8651618832bb Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 29 Oct 2024 11:54:28 +0800
|
||||
Subject: [PATCH] kern/main: Fix cmdpath in root directory
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The "cmdpath" environment variable is set at startup to the location
|
||||
from which the grub image is loaded. It includes a device part and,
|
||||
optionally, an absolute directory name if the grub image is booted as a
|
||||
file in a local file-system directory, or in a remote server directory,
|
||||
like TFTP.
|
||||
|
||||
This entire process relies on firmware to provide the correct device
|
||||
path of the booted image.
|
||||
|
||||
We encountered an issue when the image is booted from the root
|
||||
directory, where the absolute directory name "/" is discarded. This
|
||||
makes it unclear whether the root path was missing in the firmware
|
||||
provided device path or if it is simply the root directory. This
|
||||
ambiguity can cause confusion in custom scripts, potentially causing
|
||||
them to interpret firmware data incorrectly and trigger unintended
|
||||
fallback measures.
|
||||
|
||||
This patch fixes the problem by properly assigning the "fwpath" returned
|
||||
by "grub_machine_get_bootlocation()" to "cmdpath". The fix is based on
|
||||
the fact that fwpath is NULL if the firmware didn’t provide a path part
|
||||
or an NUL character, "", if it represents the root directory. With this,
|
||||
it becomes possible to clearly distinguish:
|
||||
|
||||
- cmdpath=(hd0,1) - Either the image is booted from the first (raw)
|
||||
partition, or the firmware failed to provide the path part.
|
||||
- cmdpath=(hd0,1)/ - The image is booted from the root directory in the
|
||||
first partition.
|
||||
|
||||
As a side note, the fix is similar to [1], but without the renaming
|
||||
part.
|
||||
|
||||
[1] https://mail.gnu.org/archive/html/grub-devel/2024-10/msg00155.html
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/kern/main.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index ef3b3756d..f9ab12c74 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -136,7 +136,11 @@ grub_set_prefix_and_root (void)
|
||||
{
|
||||
char *cmdpath;
|
||||
|
||||
- cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : "");
|
||||
+ if (fwpath && *fwpath == '\0')
|
||||
+ cmdpath = grub_xasprintf ("(%s)/", fwdevice);
|
||||
+ else
|
||||
+ cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : "");
|
||||
+
|
||||
if (cmdpath)
|
||||
{
|
||||
grub_env_set ("cmdpath", cmdpath);
|
||||
--
|
||||
2.47.0
|
||||
|
290
0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch
Normal file
290
0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch
Normal file
@@ -0,0 +1,290 @@
|
||||
From af8b106667aa2ca7a7613e10d8746959e182f8f1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 29 Aug 2024 13:27:30 +0800
|
||||
Subject: [PATCH 2/2] Requiring authentication after tpm unlock for CLI access
|
||||
|
||||
GRUB may use TPM to verify the integrity of boot components, and the
|
||||
result can determine whether a previously sealed key can be released. If
|
||||
everything checks out, showing nothing has been tampered with, the key
|
||||
is released, and grub unlocks the encrypted root partition for the next
|
||||
stage of booting.
|
||||
|
||||
However, the liberal command line interface (CLI) can be misused by
|
||||
anyone in this case to access files in the encrypted partition one way
|
||||
or another. Despite efforts to keep the CLI secure by preventing utility
|
||||
command output from leaking file content, many techniques in the wild
|
||||
could still be used to exploit the CLI, enabling attacks or learning
|
||||
methods to attack. It's nearly impossible to account for all scenarios
|
||||
where a hack could be applied.
|
||||
|
||||
Therefore, to mitigate potential misuse of the CLI after the root device
|
||||
has been successfully unlocked via TPM, the user should be required to
|
||||
authenticate using the LUKS password. This added layer of security
|
||||
ensures that only authorized users can access the CLI, reducing the risk
|
||||
of exploitation or unauthorized access to the encrypted partition.
|
||||
|
||||
Fixes: CVE-2024-49504
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 80 +++++++++++++++++++++++++++++++++++
|
||||
grub-core/kern/main.c | 12 ++++++
|
||||
grub-core/normal/auth.c | 30 +++++++++++++
|
||||
grub-core/normal/main.c | 4 ++
|
||||
grub-core/normal/menu_entry.c | 4 ++
|
||||
include/grub/auth.h | 1 +
|
||||
include/grub/cryptodisk.h | 3 ++
|
||||
include/grub/misc.h | 2 +
|
||||
8 files changed, 136 insertions(+)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index babc94868..77bc782fd 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1188,6 +1188,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
goto error;
|
||||
#ifndef GRUB_UTIL
|
||||
is_tpmkey = 1;
|
||||
+ grub_cli_set_auth_needed ();
|
||||
#endif
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -1706,6 +1707,85 @@ luks_script_get (grub_size_t *sz)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+grub_err_t
|
||||
+grub_cryptodisk_challenge_password (void)
|
||||
+{
|
||||
+ grub_cryptodisk_t cr_dev;
|
||||
+
|
||||
+ for (cr_dev = cryptodisk_list; cr_dev != NULL; cr_dev = cr_dev->next)
|
||||
+ {
|
||||
+ grub_cryptodisk_dev_t cr;
|
||||
+ grub_disk_t source = NULL;
|
||||
+ grub_err_t ret = GRUB_ERR_NONE;
|
||||
+ grub_cryptodisk_t dev = NULL;
|
||||
+ char *part = NULL;
|
||||
+ struct grub_cryptomount_args cargs = {0};
|
||||
+
|
||||
+ cargs.check_boot = 0;
|
||||
+ cargs.search_uuid = cr_dev->uuid;
|
||||
+
|
||||
+ source = grub_disk_open (cr_dev->source);
|
||||
+
|
||||
+ if (source == NULL)
|
||||
+ goto error_out;
|
||||
+
|
||||
+ FOR_CRYPTODISK_DEVS (cr)
|
||||
+ {
|
||||
+ dev = cr->scan (source, &cargs);
|
||||
+ if (grub_errno)
|
||||
+ goto error_out;
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (dev == NULL)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_MODULE,
|
||||
+ "no cryptodisk module can handle this device");
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), cr_dev->uuid);
|
||||
+ grub_free (part);
|
||||
+
|
||||
+ cargs.key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
+ if (cargs.key_data == NULL)
|
||||
+ goto error_out;
|
||||
+
|
||||
+ if (!grub_password_get ((char *) cargs.key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+ cargs.key_len = grub_strlen ((char *) cargs.key_data);
|
||||
+ ret = cr->recover_key (source, dev, &cargs);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error_out;
|
||||
+
|
||||
+ error_out:
|
||||
+ if (source)
|
||||
+ grub_disk_close (source);
|
||||
+ if (dev)
|
||||
+ cryptodisk_close (dev);
|
||||
+ if (cargs.key_data)
|
||||
+ {
|
||||
+ grub_memset (cargs.key_data, 0, cargs.key_len);
|
||||
+ grub_free (cargs.key_data);
|
||||
+ }
|
||||
+
|
||||
+ if (grub_errno != GRUB_ERR_NONE)
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+#endif /* GRUB_MACHINE_EFI */
|
||||
+
|
||||
struct grub_procfs_entry luks_script =
|
||||
{
|
||||
.name = "luks_script",
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 07b6940d2..ef3b3756d 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#endif
|
||||
|
||||
static bool cli_disabled = false;
|
||||
+static bool cli_need_auth = false;
|
||||
|
||||
grub_addr_t
|
||||
grub_modules_get_end (void)
|
||||
@@ -246,6 +247,17 @@ grub_is_cli_disabled (void)
|
||||
return cli_disabled;
|
||||
}
|
||||
|
||||
+bool
|
||||
+grub_is_cli_need_auth (void)
|
||||
+{
|
||||
+ return cli_need_auth;
|
||||
+}
|
||||
+
|
||||
+void grub_cli_set_auth_needed (void)
|
||||
+{
|
||||
+ cli_need_auth = true;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
check_is_cli_disabled (void)
|
||||
{
|
||||
diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c
|
||||
index d94020186..2931ba604 100644
|
||||
--- a/grub-core/normal/auth.c
|
||||
+++ b/grub-core/normal/auth.c
|
||||
@@ -25,6 +25,10 @@
|
||||
#include <grub/time.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+#include <grub/cryptodisk.h>
|
||||
+#endif
|
||||
+
|
||||
struct grub_auth_user
|
||||
{
|
||||
struct grub_auth_user *next;
|
||||
@@ -200,6 +204,32 @@ grub_username_get (char buf[], unsigned buf_size)
|
||||
return (key != GRUB_TERM_ESC);
|
||||
}
|
||||
|
||||
+grub_err_t
|
||||
+grub_auth_check_cli_access (void)
|
||||
+{
|
||||
+ if (grub_is_cli_need_auth () == true)
|
||||
+ {
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ static bool authenticated = false;
|
||||
+
|
||||
+ if (authenticated == false)
|
||||
+ {
|
||||
+ grub_err_t ret;
|
||||
+
|
||||
+ ret = grub_cryptodisk_challenge_password ();
|
||||
+ if (ret == GRUB_ERR_NONE)
|
||||
+ authenticated = true;
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return GRUB_ERR_NONE;
|
||||
+#else
|
||||
+ return GRUB_ACCESS_DENIED;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_auth_check_authentication (const char *userlist)
|
||||
{
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index 8e58ced67..b08fd6977 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -560,9 +560,13 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
}
|
||||
while (err && force_auth);
|
||||
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ err = grub_auth_check_cli_access ();
|
||||
+
|
||||
if (err)
|
||||
{
|
||||
grub_print_error ();
|
||||
+ grub_wait_after_message ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
|
||||
index e5ba91ea4..06682a396 100644
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -1256,9 +1256,13 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
|
||||
err = grub_auth_check_authentication (NULL);
|
||||
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ err = grub_auth_check_cli_access ();
|
||||
+
|
||||
if (err)
|
||||
{
|
||||
grub_print_error ();
|
||||
+ grub_wait_after_message ();
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return;
|
||||
}
|
||||
diff --git a/include/grub/auth.h b/include/grub/auth.h
|
||||
index 747334451..21d5190f0 100644
|
||||
--- a/include/grub/auth.h
|
||||
+++ b/include/grub/auth.h
|
||||
@@ -33,5 +33,6 @@ grub_err_t grub_auth_unregister_authentication (const char *user);
|
||||
grub_err_t grub_auth_authenticate (const char *user);
|
||||
grub_err_t grub_auth_deauthenticate (const char *user);
|
||||
grub_err_t grub_auth_check_authentication (const char *userlist);
|
||||
+grub_err_t grub_auth_check_cli_access (void);
|
||||
|
||||
#endif /* ! GRUB_AUTH_HEADER */
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index 0b41e249e..b3291519b 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -203,4 +203,7 @@ grub_util_get_geli_uuid (const char *dev);
|
||||
grub_cryptodisk_t grub_cryptodisk_get_by_uuid (const char *uuid);
|
||||
grub_cryptodisk_t grub_cryptodisk_get_by_source_disk (grub_disk_t disk);
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+grub_err_t grub_cryptodisk_challenge_password (void);
|
||||
+#endif
|
||||
#endif
|
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||
index 1578f36c3..6e94d18f5 100644
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -392,6 +392,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
|
||||
grub_uint64_t *r);
|
||||
|
||||
extern bool EXPORT_FUNC(grub_is_cli_disabled) (void);
|
||||
+extern bool EXPORT_FUNC(grub_is_cli_need_auth) (void);
|
||||
+extern void EXPORT_FUNC(grub_cli_set_auth_needed) (void);
|
||||
|
||||
/* Must match softdiv group in gentpl.py. */
|
||||
#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
|
||||
--
|
||||
2.47.0
|
||||
|
@@ -1,197 +0,0 @@
|
||||
From 912384e63c1e3b6aa9d90effb71cd535a17da1e2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 18 Nov 2023 19:02:31 +0800
|
||||
Subject: [PATCH 2/4] Restrict file access on cryptodisk print
|
||||
|
||||
When the encrypted partition is automatically unlocked by TPM, granting
|
||||
access to the system upon validation of its known good state, there's a
|
||||
potential vulnerability. Grub gains access to file systems that were
|
||||
previously inaccessible to the public, enabling certain commands from
|
||||
the grub console to print content. This arises due to grub lacking
|
||||
restrictions similar to those imposed by password authentication, which
|
||||
typically occurs before privileged access is granted.
|
||||
|
||||
Although the automatic unlocking process ensures system integrity and a
|
||||
secure environment for grub to operate in, it doesn't directly address
|
||||
the issue of authentication for viewing encrypted partition content.
|
||||
|
||||
This commit addresses this security loophole by implementing a file
|
||||
filter upon adding a TPM key. The newly added file filter will
|
||||
specifically verify if the disk is encrypted, denying access and
|
||||
returning an "Access Denied: prohibited to view encrypted data" error
|
||||
message to alert the user.
|
||||
|
||||
Since the policy to filter out unwanted commands from leaking encrypted
|
||||
content is irreversible, it is advisable to make the loaded module
|
||||
persistent to prevent its removal.
|
||||
|
||||
This enhancement aims to bolster security measures and prevent
|
||||
unauthorized access to encrypted data.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 35 ++++++++++++++++++++++++++++++++++-
|
||||
grub-core/disk/diskfilter.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
include/grub/disk.h | 10 ++++++++++
|
||||
include/grub/file.h | 1 +
|
||||
4 files changed, 80 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index 9397bede9..d3acc4b59 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -6,11 +6,39 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/list.h>
|
||||
#include <grub/crypttab.h>
|
||||
+#include <grub/file.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
grub_crypto_key_list_t *cryptokey_lst;
|
||||
|
||||
+static grub_file_t
|
||||
+grub_nocat_open (grub_file_t io, enum grub_file_type type)
|
||||
+{
|
||||
+ grub_disk_t disk;
|
||||
+
|
||||
+ /* Network device */
|
||||
+ if (!io->device->disk)
|
||||
+ return io;
|
||||
+
|
||||
+ disk = io->device->disk;
|
||||
+
|
||||
+ if (grub_disk_is_crypto (disk))
|
||||
+ {
|
||||
+ switch (type & GRUB_FILE_TYPE_MASK)
|
||||
+ {
|
||||
+ case GRUB_FILE_TYPE_CAT:
|
||||
+ case GRUB_FILE_TYPE_HEXCAT:
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to view encrypted data"));
|
||||
+ return NULL;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return io;
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey)
|
||||
{
|
||||
@@ -48,7 +76,11 @@ grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key
|
||||
}
|
||||
|
||||
if (is_tpmkey >= 0)
|
||||
- cur->is_tpmkey = is_tpmkey;
|
||||
+ {
|
||||
+ cur->is_tpmkey = is_tpmkey;
|
||||
+ if (is_tpmkey)
|
||||
+ grub_file_filter_register (GRUB_FILE_FILTER_NOCAT, grub_nocat_open);
|
||||
+ }
|
||||
|
||||
if (!cur->name)
|
||||
{
|
||||
@@ -121,6 +153,7 @@ GRUB_MOD_INIT(crypttab)
|
||||
{
|
||||
cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
+ grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(crypttab)
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index 5c5fabe1a..b0c1c880d 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -558,6 +558,39 @@ find_lv (const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static int
|
||||
+grub_diskfilter_has_cryptodisk (const struct grub_diskfilter_lv *lv)
|
||||
+{
|
||||
+ struct grub_diskfilter_pv *pv;
|
||||
+
|
||||
+ if (!lv)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (lv->vg->pvs)
|
||||
+ for (pv = lv->vg->pvs; pv; pv = pv->next)
|
||||
+ {
|
||||
+ if (!pv->disk)
|
||||
+ {
|
||||
+ grub_dprintf ("diskfilter", _("Couldn't find physical volume `%s'."
|
||||
+ " Some modules may be missing from core image."),
|
||||
+ pv->name);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ switch (pv->disk->dev->id)
|
||||
+ {
|
||||
+ case GRUB_DISK_DEVICE_CRYPTODISK_ID:
|
||||
+ return 1;
|
||||
+ case GRUB_DISK_DEVICE_DISKFILTER_ID:
|
||||
+ return grub_diskfilter_has_cryptodisk (pv->disk->data);
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
@@ -589,6 +622,8 @@ grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
|
||||
disk->total_sectors = lv->size;
|
||||
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||
+ disk->is_crypto_diskfilter = grub_diskfilter_has_cryptodisk (lv);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/include/grub/disk.h b/include/grub/disk.h
|
||||
index 3b3db6222..63982f16c 100644
|
||||
--- a/include/grub/disk.h
|
||||
+++ b/include/grub/disk.h
|
||||
@@ -147,6 +147,8 @@ struct grub_disk
|
||||
|
||||
/* Device-specific data. */
|
||||
void *data;
|
||||
+
|
||||
+ int is_crypto_diskfilter;
|
||||
};
|
||||
typedef struct grub_disk *grub_disk_t;
|
||||
|
||||
@@ -314,4 +316,12 @@ void grub_mdraid1x_fini (void);
|
||||
void grub_diskfilter_fini (void);
|
||||
#endif
|
||||
|
||||
+static inline int
|
||||
+grub_disk_is_crypto (grub_disk_t disk)
|
||||
+{
|
||||
+ return ((disk->is_crypto_diskfilter ||
|
||||
+ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ?
|
||||
+ 1 : 0);
|
||||
+}
|
||||
+
|
||||
#endif /* ! GRUB_DISK_HEADER */
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index fde58f0fa..fcfd32ce2 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
/* Filters with lower ID are executed first. */
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
+ GRUB_FILE_FILTER_NOCAT,
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
GRUB_FILE_FILTER_XZIO,
|
||||
--
|
||||
2.42.1
|
||||
|
@@ -1,117 +0,0 @@
|
||||
From 6c8d390809956d355fed8bc830f64e86838e3e82 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 18 Nov 2023 21:42:00 +0800
|
||||
Subject: [PATCH 3/4] Restrict 'ls' and auto file completion on cryptodisk
|
||||
print
|
||||
|
||||
The 'ls' command allows file listing, while file completion assists in
|
||||
providing matched file names by partially inputting via the TAB key.
|
||||
Both functionalities should be restricted when the disk is automatically
|
||||
unlocked for the same reasons as highlighted in the previous patch
|
||||
addressing the limitation on file access to the cryptodisk.
|
||||
|
||||
Given that no file is explicitly opened for listing, employing file
|
||||
filters becomes impractical. Consequently, this patch focuses on
|
||||
modifying relevant routines separately to incorporate necessary checks.
|
||||
The objective is to introduce measures that prevent 'ls' and auto file
|
||||
completion from accessing encrypted data when the disk is automatically
|
||||
unlocked.
|
||||
|
||||
By implementing these modifications, any attempt to utilize 'ls' or file
|
||||
completion on the cryptodisk will result in an "Access Denied:
|
||||
prohibited to browse encrypted data" error message, thus effectively
|
||||
alerting the user about the restricted access.
|
||||
|
||||
While protecting content within disk files from viewing is essential,
|
||||
it's equally crucial to restrict access to in-memory content. This
|
||||
includes prohibiting access to the decrypted in-memory copies of disk
|
||||
files.
|
||||
|
||||
This enhancement aims to fortify security protocols by extending
|
||||
restrictions to additional functionalities beyond direct file access.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/ls.c | 8 ++++++++
|
||||
grub-core/commands/minicmd.c | 6 ++++++
|
||||
grub-core/kern/corecmd.c | 8 ++++++++
|
||||
grub-core/normal/completion.c | 8 ++++++++
|
||||
4 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
|
||||
index 8e98c73cc..aeb336a73 100644
|
||||
--- a/grub-core/commands/ls.c
|
||||
+++ b/grub-core/commands/ls.c
|
||||
@@ -183,6 +183,14 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
||||
if (! dev)
|
||||
goto fail;
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
path = grub_strchr (dirname, ')');
|
||||
if (! path)
|
||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
||||
index fa498931e..8f2ac0539 100644
|
||||
--- a/grub-core/commands/minicmd.c
|
||||
+++ b/grub-core/commands/minicmd.c
|
||||
@@ -101,6 +101,12 @@ grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified");
|
||||
|
||||
+ /* NOCAT filter is applied to prevent cat alike command from revealing file
|
||||
+ * content, the dump command should also be prohibited to revealing memory
|
||||
+ * content as well */
|
||||
+ if (grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by security policy"));
|
||||
+
|
||||
#if GRUB_CPU_SIZEOF_VOID_P == GRUB_CPU_SIZEOF_LONG
|
||||
#define grub_strtoaddr grub_strtoul
|
||||
#else
|
||||
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
|
||||
index 62d434ba9..b639bc3ae 100644
|
||||
--- a/grub-core/kern/corecmd.c
|
||||
+++ b/grub-core/kern/corecmd.c
|
||||
@@ -135,6 +135,14 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (! dev)
|
||||
goto fail;
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
path = grub_strchr (argv[0], ')');
|
||||
if (! path)
|
||||
diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c
|
||||
index 18cadfa85..d003ec37d 100644
|
||||
--- a/grub-core/normal/completion.c
|
||||
+++ b/grub-core/normal/completion.c
|
||||
@@ -259,6 +259,14 @@ complete_file (void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
{
|
||||
--
|
||||
2.42.1
|
||||
|
@@ -20,11 +20,17 @@ Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
include/grub/file.h | 1 +
|
||||
2 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index d3acc4b59..e09296c57 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -121,6 +121,41 @@ grub_cryptokey_tpmkey_discard (void)
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/list.h>
|
||||
#include <grub/crypttab.h>
|
||||
+#include <grub/file.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -89,6 +90,41 @@
|
||||
grub_cryptokey_discard();
|
||||
}
|
||||
|
||||
@@ -66,26 +72,97 @@ index d3acc4b59..e09296c57 100644
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
@@ -153,6 +188,7 @@ GRUB_MOD_INIT(crypttab)
|
||||
@@ -121,6 +157,8 @@
|
||||
{
|
||||
cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
+ grub_file_filter_register (GRUB_FILE_FILTER_DISTRUST, grub_distrust_open);
|
||||
grub_dl_set_persistent (mod);
|
||||
+ grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index fcfd32ce2..daf23a9c9 100644
|
||||
GRUB_MOD_FINI(crypttab)
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
@@ -185,6 +185,7 @@
|
||||
/* Filters with lower ID are executed first. */
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
+ GRUB_FILE_FILTER_DISTRUST,
|
||||
GRUB_FILE_FILTER_NOCAT,
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
--
|
||||
2.42.1
|
||||
|
||||
GRUB_FILE_FILTER_XZIO,
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -558,6 +558,39 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static int
|
||||
+grub_diskfilter_has_cryptodisk (const struct grub_diskfilter_lv *lv)
|
||||
+{
|
||||
+ struct grub_diskfilter_pv *pv;
|
||||
+
|
||||
+ if (!lv)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (lv->vg->pvs)
|
||||
+ for (pv = lv->vg->pvs; pv; pv = pv->next)
|
||||
+ {
|
||||
+ if (!pv->disk)
|
||||
+ {
|
||||
+ grub_dprintf ("diskfilter", _("Couldn't find physical volume `%s'."
|
||||
+ " Some modules may be missing from core image."),
|
||||
+ pv->name);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ switch (pv->disk->dev->id)
|
||||
+ {
|
||||
+ case GRUB_DISK_DEVICE_CRYPTODISK_ID:
|
||||
+ return 1;
|
||||
+ case GRUB_DISK_DEVICE_DISKFILTER_ID:
|
||||
+ return grub_diskfilter_has_cryptodisk (pv->disk->data);
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
@@ -589,6 +622,8 @@
|
||||
|
||||
disk->total_sectors = lv->size;
|
||||
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||
+ disk->is_crypto_diskfilter = grub_diskfilter_has_cryptodisk (lv);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/include/grub/disk.h
|
||||
+++ b/include/grub/disk.h
|
||||
@@ -147,6 +147,8 @@
|
||||
|
||||
/* Device-specific data. */
|
||||
void *data;
|
||||
+
|
||||
+ int is_crypto_diskfilter;
|
||||
};
|
||||
typedef struct grub_disk *grub_disk_t;
|
||||
|
||||
@@ -317,4 +319,12 @@
|
||||
void grub_diskfilter_fini (void);
|
||||
#endif
|
||||
|
||||
+static inline int
|
||||
+grub_disk_is_crypto (grub_disk_t disk)
|
||||
+{
|
||||
+ return ((disk->is_crypto_diskfilter ||
|
||||
+ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ?
|
||||
+ 1 : 0);
|
||||
+}
|
||||
+
|
||||
#endif /* ! GRUB_DISK_HEADER */
|
||||
|
@@ -1,3 +1,28 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Nov 1 08:46:36 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix grub.cfg is loaded from an unexpected fallback directory instead of the
|
||||
root directory during PXE boot when grub is loaded from the tftp root
|
||||
directory (bsc#1232391)
|
||||
* 0001-kern-main-Fix-cmdpath-in-root-directory.patch
|
||||
* grub2.spec: Refine PPC grub.elf early config to derive root from cmdpath
|
||||
directly, avoiding the unneeded search
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Oct 30 08:24:15 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix CVE-2024-49504 (bsc#1229163) (bsc#1229164)
|
||||
- Restrict CLI access if the encrypted root device is automatically unlocked by
|
||||
the TPM. LUKS password authentication is required for access to be granted
|
||||
* 0001-cli_lock-Add-build-option-to-block-command-line-inte.patch
|
||||
* 0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch
|
||||
- Obsolete, as CLI access is now locked and granted access no longer requires
|
||||
the previous restrictions
|
||||
* 0002-Restrict-file-access-on-cryptodisk-print.patch
|
||||
* 0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
|
||||
- Rediff
|
||||
* 0004-Key-revocation-on-out-of-bound-file-access.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Oct 30 00:44:41 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
|
18
grub2.spec
18
grub2.spec
@@ -377,8 +377,6 @@ Patch189: arm64-Use-proper-memory-type-for-kernel-allocation.patch
|
||||
Patch190: 0001-luks2-Use-grub-tpm2-token-for-TPM2-protected-volume-.patch
|
||||
Patch191: Fix-the-size-calculation-for-the-synthesized-initrd.patch
|
||||
Patch192: 0001-Improve-TPM-key-protection-on-boot-interruptions.patch
|
||||
Patch193: 0002-Restrict-file-access-on-cryptodisk-print.patch
|
||||
Patch194: 0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
|
||||
Patch195: 0004-Key-revocation-on-out-of-bound-file-access.patch
|
||||
# Workaround for 2.12 tarball
|
||||
Patch196: fix_no_extra_deps_in_release_tarball.patch
|
||||
@@ -419,6 +417,9 @@ Patch230: 0007-mkimage-create-new-ELF-Note-for-SBAT.patch
|
||||
Patch231: 0008-mkimage-adding-sbat-data-into-sbat-ELF-Note-on-power.patch
|
||||
Patch232: 0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
|
||||
Patch233: 0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch
|
||||
Patch234: 0001-cli_lock-Add-build-option-to-block-command-line-inte.patch
|
||||
Patch235: 0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch
|
||||
Patch236: 0001-kern-main-Fix-cmdpath-in-root-directory.patch
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
# Always requires a default cpu-platform package
|
||||
@@ -948,8 +949,6 @@ echo "bpath=$bpath"
|
||||
if regexp '^(tftp|http)$' "$bdev"; then
|
||||
if [ -z "$bpath" ]; then
|
||||
echo "network booting via $bdev but firmware didn't provide loaded path from sever root"
|
||||
bpath="/boot/grub2/powerpc-ieee1275"
|
||||
echo "using bpath=$bpath as fallback path"
|
||||
fi
|
||||
elif [ -z "$ENV_FS_UUID" ]; then
|
||||
echo "Reading vars from ($bdev)"
|
||||
@@ -994,6 +993,17 @@ set prefix=""
|
||||
set root=""
|
||||
set cfg="grub.cfg"
|
||||
|
||||
if regexp '^(tftp|http)$' "$bdev"; then
|
||||
cfg_dir=""
|
||||
root="$bdev$bpart"
|
||||
if [ -z "$bpath" ]; then
|
||||
bpath="/boot/grub2/powerpc-ieee1275"
|
||||
echo "using bpath=$bpath as fallback path"
|
||||
fi
|
||||
prefix="($root)$bpath"
|
||||
cfg="grub.cfg"
|
||||
fi
|
||||
|
||||
for uuid in $ENV_CRYPTO_UUID; do
|
||||
cryptomount -u $uuid
|
||||
done
|
||||
|
Reference in New Issue
Block a user