Compare commits
No commits in common. 'c9' and 'i10-beta' have entirely different histories.
@ -0,0 +1,93 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Thu, 9 Mar 2023 11:18:19 -0500
|
||||
Subject: [PATCH] hostdisk: work around /proc not reporting size
|
||||
|
||||
fstat(2) of files in /proc will yield st_size == 0 regardless of file
|
||||
contents. Use a negative value in grub_file_t's size to denote "ignore"
|
||||
and plumb through.
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/kern/file.c | 28 ++++++++++++++++------------
|
||||
grub-core/lib/progress.c | 2 +-
|
||||
grub-core/osdep/unix/hostdisk.c | 6 ++++++
|
||||
3 files changed, 23 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
|
||||
index 868ce3b63e..4ea6d1ce95 100644
|
||||
--- a/grub-core/kern/file.c
|
||||
+++ b/grub-core/kern/file.c
|
||||
@@ -172,26 +172,30 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len)
|
||||
grub_disk_read_hook_t read_hook;
|
||||
void *read_hook_data;
|
||||
|
||||
- if (file->offset > file->size)
|
||||
- {
|
||||
- grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
- N_("attempt to read past the end of file"));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
- if (len > file->size - file->offset)
|
||||
- len = file->size - file->offset;
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
+ if (file->size >= 0)
|
||||
+ {
|
||||
+#endif
|
||||
+ if (file->offset > file->size)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("attempt to read past the end of file"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (len > file->size - file->offset)
|
||||
+ len = file->size - file->offset;
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
/* Prevent an overflow. */
|
||||
if ((grub_ssize_t) len < 0)
|
||||
len >>= 1;
|
||||
|
||||
- if (len == 0)
|
||||
- return 0;
|
||||
-
|
||||
read_hook = file->read_hook;
|
||||
read_hook_data = file->read_hook_data;
|
||||
if (!file->read_hook)
|
||||
diff --git a/grub-core/lib/progress.c b/grub-core/lib/progress.c
|
||||
index 4b7cbbca6d..f3226b6898 100644
|
||||
--- a/grub-core/lib/progress.c
|
||||
+++ b/grub-core/lib/progress.c
|
||||
@@ -71,7 +71,7 @@ grub_file_progress_hook_real (grub_disk_addr_t sector __attribute__ ((unused)),
|
||||
* 100ULL * 1000ULL,
|
||||
now - file->last_progress_time, 0);
|
||||
|
||||
- if (file->size == 0)
|
||||
+ if (file->size <= 0)
|
||||
percent = 100;
|
||||
else
|
||||
percent = grub_divmod64 (100 * file->progress_offset,
|
||||
diff --git a/grub-core/osdep/unix/hostdisk.c b/grub-core/osdep/unix/hostdisk.c
|
||||
index 3a00d7451a..e5f4b4d5f9 100644
|
||||
--- a/grub-core/osdep/unix/hostdisk.c
|
||||
+++ b/grub-core/osdep/unix/hostdisk.c
|
||||
@@ -71,6 +71,12 @@ grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsiz
|
||||
if (log_secsize)
|
||||
*log_secsize = 9;
|
||||
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
+ /* /proc doesn't behave itself and gives 0 for file sizes to stat. */
|
||||
+ if (st.st_size == 0 && !grub_strncmp ("/proc", name, 5))
|
||||
+ return -1;
|
||||
+#endif
|
||||
+
|
||||
return st.st_size;
|
||||
}
|
||||
|
@ -0,0 +1,118 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Tue, 7 Mar 2023 18:59:40 -0500
|
||||
Subject: [PATCH] blscfg: check for mounted /boot in emu
|
||||
|
||||
Irritatingly, BLS defines paths relatives to the mountpoint of the
|
||||
filesystem which contains its snippets, not / or any other fixed
|
||||
location. So grub2-emu needs to know whether /boot is a separate
|
||||
filesysem from / and conditionally prepend a path.
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 54 ++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 49 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index dbd0899acf..6e398fc175 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -40,8 +40,9 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#include "loadenv.h"
|
||||
|
||||
#define GRUB_BLS_CONFIG_PATH "/loader/entries/"
|
||||
+
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
-#define GRUB_BOOT_DEVICE ""
|
||||
+#define GRUB_BOOT_DEVICE "/boot"
|
||||
#else
|
||||
#define GRUB_BOOT_DEVICE "($root)"
|
||||
#endif
|
||||
@@ -54,8 +55,50 @@ struct keyval
|
||||
|
||||
static struct bls_entry *entries = NULL;
|
||||
|
||||
+/* Cache probing in frob_boot_device(). Used for linux entry also.
|
||||
+ * Always true in non-emu, meaning to prefix things with GRUB_BOOT_DEVICE. */
|
||||
+static int separate_boot = -1;
|
||||
+
|
||||
#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
|
||||
|
||||
+/* BLS appears to make paths relative to the filesystem that snippets are
|
||||
+ * on, not /. Attempt to cope. */
|
||||
+static char *frob_boot_device(char *tmp)
|
||||
+{
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
+ grub_file_t f;
|
||||
+ char *line = NULL;
|
||||
+
|
||||
+ if (separate_boot != -1)
|
||||
+ goto probed;
|
||||
+
|
||||
+ separate_boot = 0;
|
||||
+
|
||||
+ f = grub_file_open ("/proc/mounts", GRUB_FILE_TYPE_CONFIG);
|
||||
+ if (f == NULL)
|
||||
+ goto probed;
|
||||
+
|
||||
+ while ((line = grub_file_getline (f)))
|
||||
+ {
|
||||
+ if (grub_strstr (line, " " GRUB_BOOT_DEVICE " "))
|
||||
+ {
|
||||
+ separate_boot = 1;
|
||||
+ grub_free (line);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ grub_free(line);
|
||||
+ }
|
||||
+
|
||||
+ grub_file_close (f);
|
||||
+ probed:
|
||||
+ if (!separate_boot)
|
||||
+ return grub_stpcpy (tmp, " ");
|
||||
+#endif
|
||||
+
|
||||
+ return grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+}
|
||||
+
|
||||
static int bls_add_keyval(struct bls_entry *entry, char *key, char *val)
|
||||
{
|
||||
char *k, *v;
|
||||
@@ -842,7 +885,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]);
|
||||
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+ tmp = frob_boot_device (tmp);
|
||||
tmp = grub_stpcpy (tmp, initrd_prefix);
|
||||
tmp = grub_stpcpy (tmp, early_initrds[i]);
|
||||
grub_free(early_initrds[i]);
|
||||
@@ -851,7 +894,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]);
|
||||
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+ tmp = frob_boot_device (tmp);
|
||||
tmp = grub_stpcpy (tmp, initrds[i]);
|
||||
}
|
||||
tmp = grub_stpcpy (tmp, "\n");
|
||||
@@ -888,7 +931,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
}
|
||||
char *tmp = dt;
|
||||
tmp = grub_stpcpy (dt, "devicetree");
|
||||
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+ tmp = frob_boot_device (tmp);
|
||||
if (add_dt_prefix)
|
||||
tmp = grub_stpcpy (tmp, prefix);
|
||||
tmp = grub_stpcpy (tmp, devicetree);
|
||||
@@ -907,7 +950,8 @@ static void create_entry (struct bls_entry *entry)
|
||||
"linux %s%s%s%s\n"
|
||||
"%s%s",
|
||||
savedefault ? "savedefault\n" : "",
|
||||
- GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "",
|
||||
+ separate_boot ? GRUB_BOOT_DEVICE : "",
|
||||
+ clinux, options ? " " : "", options ? options : "",
|
||||
initrd ? initrd : "", dt ? dt : "");
|
||||
|
||||
grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index, entry);
|
@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Wed, 22 Mar 2023 14:19:43 -0400
|
||||
Subject: [PATCH] emu/linux: work around systemctl kexec returning
|
||||
|
||||
Per systemctl(1), it "is asynchronous; it will return after the reboot
|
||||
operation is enqueued, without waiting for it to complete". This
|
||||
differs from kexec(8), which calls reboot(2) and therefore does not
|
||||
return.
|
||||
|
||||
When not using fallback, this results in the confusing-but-harmless:
|
||||
|
||||
error trying to perform 'systemctl kexec': 0
|
||||
Aborted. Press any key to exit.
|
||||
|
||||
on screen for a bit, followed by successful kexec.
|
||||
|
||||
To reduce the liklihood of hitting this case, add a delay on succesful
|
||||
return. Ultimately, the systemd interface is racy: we can't avoid it
|
||||
entirely unless we never fallback on success.
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/loader/emu/linux.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c
|
||||
index 0cf378a376..7de3f7f861 100644
|
||||
--- a/grub-core/loader/emu/linux.c
|
||||
+++ b/grub-core/loader/emu/linux.c
|
||||
@@ -74,6 +74,10 @@ grub_linux_boot (void)
|
||||
(kexecute==1) ? "do-or-die" : "just-in-case");
|
||||
rc = grub_util_exec (systemctl);
|
||||
|
||||
+ /* `systemctl kexec` is "asynchronous" and will return even on success. */
|
||||
+ if (rc == 0)
|
||||
+ grub_sleep (10);
|
||||
+
|
||||
if (kexecute == 1)
|
||||
grub_fatal (N_("error trying to perform 'systemctl kexec': %d"), rc);
|
||||
|
@ -0,0 +1,156 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 22 Mar 2023 12:25:43 +0800
|
||||
Subject: [PATCH] tpm: Disable the tpm verifier if the TPM device is not
|
||||
present
|
||||
|
||||
When the tpm module is loaded, the verifier reads entire file into
|
||||
memory, measures it and uses verified content as a backing buffer for
|
||||
file accesses. However, this process may result in high memory
|
||||
utilization for file operations, sometimes causing a system to run out
|
||||
of memory which may finally lead to boot failure. To address this issue,
|
||||
among others, the commit 887f98f0d (mm: Allow dynamically requesting
|
||||
additional memory regions) have optimized memory management by
|
||||
dynamically allocating heap space to maximize memory usage and reduce
|
||||
threat of memory exhaustion. But in some cases problems may still arise,
|
||||
e.g., when large ISO images are mounted using loopback or when dealing
|
||||
with embedded systems with limited memory resources.
|
||||
|
||||
Unfortunately current implementation of the tpm module doesn't allow
|
||||
elimination of the back buffer once it is loaded. Even if the TPM device
|
||||
is not present or it has been explicitly disabled. This may unnecessary
|
||||
allocate a lot memory. To solve this issue, a patch has been developed
|
||||
to detect the TPM status at module load and skip verifier registration
|
||||
if the device is missing or deactivated. This prevents allocation of
|
||||
memory for the back buffer, avoiding wasting memory when no real measure
|
||||
boot functionality is performed. Disabling the TPM device in the system
|
||||
can reduce memory usage in the GRUB. It is useful in scenarios where
|
||||
high memory utilization is a concern and measurements of loaded
|
||||
artifacts are not necessary.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 30708dfe3bebd62a5487437554da8a24253f519f)
|
||||
---
|
||||
grub-core/commands/efi/tpm.c | 37 +++++++++++++++++++++++++++++++++++
|
||||
grub-core/commands/ieee1275/ibmvtpm.c | 20 +++++++++----------
|
||||
grub-core/commands/tpm.c | 10 ++++++++++
|
||||
include/grub/tpm.h | 1 +
|
||||
4 files changed, 58 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c
|
||||
index ae09c1bf8b..e1f343fea3 100644
|
||||
--- a/grub-core/commands/efi/tpm.c
|
||||
+++ b/grub-core/commands/efi/tpm.c
|
||||
@@ -287,3 +287,40 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
else
|
||||
return grub_tpm2_log_event (tpm_handle, buf, size, pcr, description);
|
||||
}
|
||||
+
|
||||
+int
|
||||
+grub_tpm_present (void)
|
||||
+{
|
||||
+ grub_efi_handle_t tpm_handle;
|
||||
+ grub_efi_uint8_t protocol_version;
|
||||
+
|
||||
+ if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (protocol_version == 1)
|
||||
+ {
|
||||
+ grub_efi_tpm_protocol_t *tpm;
|
||||
+
|
||||
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
|
||||
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
+ if (!tpm)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm", "Cannot open TPM protocol\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return grub_tpm1_present (tpm);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ grub_efi_tpm2_protocol_t *tpm;
|
||||
+
|
||||
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
|
||||
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
+ if (!tpm)
|
||||
+ {
|
||||
+ grub_dprintf ("tpm", "Cannot open TPM protocol\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return grub_tpm2_present (tpm);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
index 239942d27e..a6fee5c516 100644
|
||||
--- a/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
@@ -135,16 +135,6 @@ grub_err_t
|
||||
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
const char *description)
|
||||
{
|
||||
- /*
|
||||
- * Call tpm_init() 'late' rather than from GRUB_MOD_INIT() so that device nodes
|
||||
- * can be found.
|
||||
- */
|
||||
- grub_err_t err = tpm_init ();
|
||||
-
|
||||
- /* Absence of a TPM isn't a failure. */
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- return GRUB_ERR_NONE;
|
||||
-
|
||||
grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n",
|
||||
pcr, size, description);
|
||||
|
||||
@@ -153,3 +143,13 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
+
|
||||
+int
|
||||
+grub_tpm_present (void)
|
||||
+{
|
||||
+ /*
|
||||
+ * Call tpm_init() "late" rather than from GRUB_MOD_INIT() so that device nodes
|
||||
+ * can be found.
|
||||
+ */
|
||||
+ return tpm_init() == GRUB_ERR_NONE;
|
||||
+}
|
||||
diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c
|
||||
index e287d042e6..5839053d3d 100644
|
||||
--- a/grub-core/commands/tpm.c
|
||||
+++ b/grub-core/commands/tpm.c
|
||||
@@ -86,10 +86,20 @@ struct grub_file_verifier grub_tpm_verifier = {
|
||||
|
||||
GRUB_MOD_INIT (tpm)
|
||||
{
|
||||
+ /*
|
||||
+ * Even though this now calls ibmvtpm's grub_tpm_present() from GRUB_MOD_INIT(),
|
||||
+ * it does seem to call it late enough in the initialization sequence so
|
||||
+ * that whatever discovered "device nodes" before this GRUB_MOD_INIT() is
|
||||
+ * called, enables the ibmvtpm driver to see the device nodes.
|
||||
+ */
|
||||
+ if (!grub_tpm_present())
|
||||
+ return;
|
||||
grub_verifier_register (&grub_tpm_verifier);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (tpm)
|
||||
{
|
||||
+ if (!grub_tpm_present())
|
||||
+ return;
|
||||
grub_verifier_unregister (&grub_tpm_verifier);
|
||||
}
|
||||
diff --git a/include/grub/tpm.h b/include/grub/tpm.h
|
||||
index 5c285cbc52..c19fcbd0a6 100644
|
||||
--- a/include/grub/tpm.h
|
||||
+++ b/include/grub/tpm.h
|
||||
@@ -36,4 +36,5 @@
|
||||
|
||||
grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size,
|
||||
grub_uint8_t pcr, const char *description);
|
||||
+int grub_tpm_present (void);
|
||||
#endif
|
@ -0,0 +1,330 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Frayer <nfrayer@redhat.com>
|
||||
Date: Fri, 31 Mar 2023 20:47:58 +0200
|
||||
Subject: [PATCH] emu: Add switch-root to grub-emu
|
||||
|
||||
If the kernel running grub emu is the same as the one we want to
|
||||
boot, it makes sense that we just switch-root instead of kexec
|
||||
the same kernel again by doing grub2-emu --switch-root
|
||||
|
||||
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
|
||||
---
|
||||
grub-core/kern/emu/main.c | 5 +-
|
||||
grub-core/kern/emu/misc.c | 13 +++
|
||||
grub-core/loader/emu/linux.c | 209 +++++++++++++++++++++++++++++++++++++++++--
|
||||
include/grub/emu/exec.h | 2 +-
|
||||
include/grub/emu/misc.h | 2 +
|
||||
5 files changed, 223 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c
|
||||
index 68e2b283bb..ccb2863f5b 100644
|
||||
--- a/grub-core/kern/emu/main.c
|
||||
+++ b/grub-core/kern/emu/main.c
|
||||
@@ -108,6 +108,7 @@ static struct argp_option options[] = {
|
||||
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
||||
{"hold", 'H', N_("SECS"), OPTION_ARG_OPTIONAL, N_("wait until a debugger will attach"), 0},
|
||||
{"kexec", 'X', 0, 0, N_("use kexec to boot Linux kernels via systemctl (pass twice to enable dangerous fallback to non-systemctl)."), 0},
|
||||
+ {"switch-root", 'W', 0, 0, N_("use switch-root to only switch root filesystem without restarting the kernel."), 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -168,7 +169,9 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
||||
case 'X':
|
||||
grub_util_set_kexecute ();
|
||||
break;
|
||||
-
|
||||
+ case 'W':
|
||||
+ grub_util_set_switch_root ();
|
||||
+ break;
|
||||
case ARGP_KEY_ARG:
|
||||
{
|
||||
/* Too many arguments. */
|
||||
diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c
|
||||
index 02d27c3440..4b5123ef96 100644
|
||||
--- a/grub-core/kern/emu/misc.c
|
||||
+++ b/grub-core/kern/emu/misc.c
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
int verbosity;
|
||||
int kexecute;
|
||||
+int switchroot = 0;
|
||||
|
||||
void
|
||||
grub_util_warn (const char *fmt, ...)
|
||||
@@ -231,3 +232,15 @@ grub_util_get_kexecute (void)
|
||||
{
|
||||
return kexecute;
|
||||
}
|
||||
+
|
||||
+void
|
||||
+grub_util_set_switch_root (void)
|
||||
+{
|
||||
+ switchroot = 1;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_util_get_switch_root (void)
|
||||
+{
|
||||
+ return switchroot;
|
||||
+}
|
||||
diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c
|
||||
index 7de3f7f861..6feb0412c5 100644
|
||||
--- a/grub-core/loader/emu/linux.c
|
||||
+++ b/grub-core/loader/emu/linux.c
|
||||
@@ -15,7 +15,6 @@
|
||||
* 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/loader.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/command.h>
|
||||
@@ -33,6 +32,196 @@ static char *kernel_path;
|
||||
static char *initrd_path;
|
||||
static char *boot_cmdline;
|
||||
|
||||
+static grub_err_t
|
||||
+grub_switch_root (void)
|
||||
+{
|
||||
+ char *tmp = NULL;
|
||||
+ char *options_cmd = NULL;
|
||||
+ char *options = NULL;
|
||||
+ char *subvol = NULL;
|
||||
+ char *root_uuid = NULL;
|
||||
+ char *kernel_release = NULL;
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ const char *subvol_param = "subvol=";
|
||||
+ const char *kernel_release_prefix = "/boot/vmlinuz-";
|
||||
+ const char *root_prefix = "root=";
|
||||
+ const char *systemctl[] = {"systemctl", "--force", "switch-root", "/sysroot", NULL};
|
||||
+ const char *mountrootfs[] = {"mount", root_uuid, "/sysroot", options_cmd, options, NULL};
|
||||
+ const char *unamer[] = {"uname", "-r", NULL};
|
||||
+ char *uname_buf = NULL;
|
||||
+ int i = 0;
|
||||
+
|
||||
+ /* Extract the kernel release tag from kernel_path */
|
||||
+ if (!kernel_path)
|
||||
+ {
|
||||
+ rc = GRUB_ERR_BAD_ARGUMENT;
|
||||
+ grub_dprintf ("linux", "switch_root: No kernel_path found\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((kernel_release = grub_xasprintf ("%s", (kernel_path + grub_strlen (kernel_release_prefix)))) == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "switch_root: Failed to allocate memory\n");
|
||||
+ rc = GRUB_ERR_BAD_ARGUMENT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /* Check for kernel mismatch */
|
||||
+ /* Retrieve the current kernel relase tag */
|
||||
+ grub_util_exec_redirect (unamer, NULL, "/tmp/version");
|
||||
+
|
||||
+ grub_file_t f = grub_file_open ("/tmp/version", GRUB_FILE_TYPE_FS_SEARCH);
|
||||
+
|
||||
+ if (f == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "failed opening file.\n");
|
||||
+ rc = GRUB_ERR_FILE_NOT_FOUND;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((uname_buf = grub_malloc (f->size)) == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "switch_root: Failed to allocate memory\n");
|
||||
+ rc = GRUB_ERR_OUT_OF_MEMORY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_file_read (f, uname_buf, f->size) < 0)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "switch_root: failed to read from file\n");
|
||||
+ rc = GRUB_ERR_FILE_READ_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ grub_file_close (f);
|
||||
+
|
||||
+ if (grub_strstr (uname_buf, kernel_release) == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "switch_root: kernel mismatch, not performing switch-root ...\n");
|
||||
+ rc = GRUB_ERR_NO_KERNEL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* Extract the root partition from boot_cmdline */
|
||||
+ if (!boot_cmdline)
|
||||
+ {
|
||||
+ rc = GRUB_ERR_BAD_ARGUMENT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ tmp = grub_strdup (boot_cmdline);
|
||||
+
|
||||
+ if (tmp == NULL)
|
||||
+ {
|
||||
+ rc = GRUB_ERR_OUT_OF_MEMORY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((root_uuid = grub_strstr (tmp, root_prefix)) == NULL)
|
||||
+ {
|
||||
+ rc = GRUB_ERR_BAD_ARGUMENT;
|
||||
+ grub_dprintf ("linux", "switch_root: Can't find rootfs\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ root_uuid += grub_strlen (root_prefix);
|
||||
+
|
||||
+ while (root_uuid[i] != ' ' && root_uuid[i] != '\0')
|
||||
+ i++;
|
||||
+
|
||||
+ root_uuid[i] = '\0';
|
||||
+
|
||||
+ /* Allocate a new buffer holding root_uuid */
|
||||
+ root_uuid = grub_xasprintf ("%s", root_uuid);
|
||||
+
|
||||
+ if (root_uuid == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "switch_root: Failed to allocated memory\n");
|
||||
+ rc = GRUB_ERR_OUT_OF_MEMORY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* Check for subvol parameter */
|
||||
+ grub_strcpy (tmp, boot_cmdline);
|
||||
+
|
||||
+ if ((subvol = grub_strstr(tmp, subvol_param)) != NULL)
|
||||
+ {
|
||||
+ i = 0;
|
||||
+
|
||||
+ while (subvol[i] != ' ' && subvol[i] != '\0')
|
||||
+ i++;
|
||||
+
|
||||
+ subvol[i] = '\0';
|
||||
+
|
||||
+ /* Allocate a new buffer holding subvol */
|
||||
+ subvol = grub_xasprintf("%s", subvol);
|
||||
+
|
||||
+ if (subvol == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "switch_root: Failed to allocated memory\n");
|
||||
+ rc = GRUB_ERR_OUT_OF_MEMORY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ options_cmd = grub_xasprintf("%s", "-o");
|
||||
+ options = grub_xasprintf("%s", subvol);
|
||||
+ }
|
||||
+
|
||||
+ if (options == NULL)
|
||||
+ {
|
||||
+ mountrootfs[3] = NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ mountrootfs[3] = options_cmd;
|
||||
+ mountrootfs[4] = options;
|
||||
+ }
|
||||
+
|
||||
+ mountrootfs[1] = root_uuid;
|
||||
+
|
||||
+ grub_dprintf ("linux", "Executing:\n");
|
||||
+ grub_dprintf ("linux", "%s %s %s %s %s\n", mountrootfs[0], mountrootfs[1],
|
||||
+ mountrootfs[2], mountrootfs[3], mountrootfs[4]);
|
||||
+
|
||||
+ /* Mount the rootfs */
|
||||
+ rc = grub_util_exec (mountrootfs);
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "switch_root: Failed.\n");
|
||||
+ rc = GRUB_ERR_INVALID_COMMAND;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("linux", "Done.\n");
|
||||
+
|
||||
+ grub_dprintf ("linux", "%s %s %s %s\n", systemctl[0], systemctl[1],
|
||||
+ systemctl[2], systemctl[3]);
|
||||
+
|
||||
+ /* Switch root */
|
||||
+ rc = grub_util_exec (systemctl);
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "switch_root: Failed.\n");
|
||||
+ rc = GRUB_ERR_INVALID_COMMAND;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("linux", "Done.\n");
|
||||
+
|
||||
+out:
|
||||
+ grub_free (tmp);
|
||||
+ grub_free (options_cmd);
|
||||
+ grub_free (options);
|
||||
+ grub_free (subvol);
|
||||
+ grub_free (root_uuid);
|
||||
+ grub_free (uname_buf);
|
||||
+ grub_free (kernel_release);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_linux_boot (void)
|
||||
{
|
||||
@@ -51,12 +240,20 @@ grub_linux_boot (void)
|
||||
else
|
||||
initrd_param = grub_xasprintf ("%s", "");
|
||||
|
||||
- grub_dprintf ("linux", "%serforming 'kexec -la %s %s %s'\n",
|
||||
- (kexecute) ? "P" : "Not p",
|
||||
- kernel_path, initrd_param, boot_cmdline);
|
||||
+ if (grub_util_get_switch_root() == 1)
|
||||
+ {
|
||||
+ rc = grub_switch_root();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_fatal (N_("Failed to execute switch_root\n"));
|
||||
+ }
|
||||
+ else if (kexecute)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "%serforming 'kexec -la %s %s %s'\n",
|
||||
+ (kexecute) ? "P" : "Not p",
|
||||
+ kernel_path, initrd_param, boot_cmdline);
|
||||
|
||||
- if (kexecute)
|
||||
- rc = grub_util_exec (kexec);
|
||||
+ rc = grub_util_exec (kexec);
|
||||
+ }
|
||||
|
||||
grub_free (initrd_param);
|
||||
|
||||
diff --git a/include/grub/emu/exec.h b/include/grub/emu/exec.h
|
||||
index 1b61b4a2e5..e82f13215e 100644
|
||||
--- a/include/grub/emu/exec.h
|
||||
+++ b/include/grub/emu/exec.h
|
||||
@@ -36,7 +36,7 @@ grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file,
|
||||
int
|
||||
EXPORT_FUNC(grub_util_exec) (const char *const *argv);
|
||||
int
|
||||
-grub_util_exec_redirect (const char *const *argv, const char *stdin_file,
|
||||
+EXPORT_FUNC(grub_util_exec_redirect) (const char *const *argv, const char *stdin_file,
|
||||
const char *stdout_file);
|
||||
int
|
||||
grub_util_exec_redirect_null (const char *const *argv);
|
||||
diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h
|
||||
index 01056954b9..f3a712a8b2 100644
|
||||
--- a/include/grub/emu/misc.h
|
||||
+++ b/include/grub/emu/misc.h
|
||||
@@ -59,6 +59,8 @@ void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((format
|
||||
|
||||
void EXPORT_FUNC(grub_util_set_kexecute) (void);
|
||||
int EXPORT_FUNC(grub_util_get_kexecute) (void) WARN_UNUSED_RESULT;
|
||||
+void EXPORT_FUNC(grub_util_set_switch_root) (void);
|
||||
+int EXPORT_FUNC(grub_util_get_switch_root) (void);
|
||||
|
||||
grub_uint64_t EXPORT_FUNC (grub_util_get_cpu_time_ms) (void);
|
||||
|
@ -0,0 +1,52 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Glombek <cglombek@redhat.com>
|
||||
Date: Wed, 9 Aug 2023 18:11:25 +0200
|
||||
Subject: [PATCH] Add [Install] section to aux systemd units
|
||||
|
||||
Currently in Fedora, these services are statically enabled by symlinks,
|
||||
with no other way to disable them than to manually delete those symlinks.
|
||||
This is problematic in Fedora IoT, where grub-boot-success.timer is
|
||||
not supposed to be enabled.
|
||||
|
||||
This change adds `[Install]` sections to all systemd units that are
|
||||
currently enabled statically, so that they can be enabled dynamically
|
||||
via presets or manually instead.
|
||||
---
|
||||
docs/grub-boot-indeterminate.service | 3 +++
|
||||
docs/grub-boot-success.timer | 3 +++
|
||||
util/systemd/grub-systemd-integration.service.in | 3 +++
|
||||
3 files changed, 9 insertions(+)
|
||||
|
||||
diff --git a/docs/grub-boot-indeterminate.service b/docs/grub-boot-indeterminate.service
|
||||
index 6c8dcb186b63..5bcb474a3d31 100644
|
||||
--- a/docs/grub-boot-indeterminate.service
|
||||
+++ b/docs/grub-boot-indeterminate.service
|
||||
@@ -9,3 +9,6 @@ Before=system-update-pre.target
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/grub2-editenv - incr boot_indeterminate
|
||||
+
|
||||
+[Install]
|
||||
+WantedBy=system-update.target
|
||||
diff --git a/docs/grub-boot-success.timer b/docs/grub-boot-success.timer
|
||||
index 406f17200560..1d124cccc146 100644
|
||||
--- a/docs/grub-boot-success.timer
|
||||
+++ b/docs/grub-boot-success.timer
|
||||
@@ -5,3 +5,6 @@ ConditionVirtualization=!container
|
||||
|
||||
[Timer]
|
||||
OnActiveSec=2min
|
||||
+
|
||||
+[Install]
|
||||
+WantedBy=timers.target
|
||||
diff --git a/util/systemd/grub-systemd-integration.service.in b/util/systemd/grub-systemd-integration.service.in
|
||||
index c81fb594ce17..22ca1ca4885e 100644
|
||||
--- a/util/systemd/grub-systemd-integration.service.in
|
||||
+++ b/util/systemd/grub-systemd-integration.service.in
|
||||
@@ -6,3 +6,6 @@ ConditionPathExists=/run/systemd/reboot-to-boot-loader-menu
|
||||
|
||||
[Service]
|
||||
ExecStart=@libexecdir@/@grubdirname@/systemd-integration.sh
|
||||
+
|
||||
+[Install]
|
||||
+WantedBy=reboot.target
|
@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Maximilian Luz <luzmaximilian@gmail.com>
|
||||
Date: Tue, 28 Jun 2022 23:06:46 +0200
|
||||
Subject: [PATCH] arm64: Use proper memory type for kernel allocation
|
||||
|
||||
Currently, the kernel pages are allocated with type EFI_LOADER_DATA.
|
||||
While the vast majority of systems will happily execute code from those
|
||||
pages (i.e. don't care about memory protection), the Microsoft Surface
|
||||
Pro X stalls, as this memory is not designated as "executable".
|
||||
|
||||
Therefore, allocate the kernel pages as EFI_LOADER_CODE to request
|
||||
memory that is actually executable.
|
||||
|
||||
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
|
||||
---
|
||||
grub-core/loader/arm64/linux.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
|
||||
index 419f2201df8b..a3a193c255e9 100644
|
||||
--- a/grub-core/loader/arm64/linux.c
|
||||
+++ b/grub-core/loader/arm64/linux.c
|
||||
@@ -26,7 +26,9 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/cpu/linux.h>
|
||||
+#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
+#include <grub/cpu/efi/memory.h>
|
||||
#include <grub/efi/fdtload.h>
|
||||
#include <grub/efi/memory.h>
|
||||
#include <grub/efi/linux.h>
|
||||
@@ -403,7 +405,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_loader_unset();
|
||||
|
||||
kernel_alloc_pages = GRUB_EFI_BYTES_TO_PAGES (kernel_size + align - 1);
|
||||
- kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages);
|
||||
+ kernel_alloc_addr = grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS,
|
||||
+ kernel_alloc_pages,
|
||||
+ GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
||||
+ GRUB_EFI_LOADER_CODE);
|
||||
grub_dprintf ("linux", "kernel numpages: %d\n", kernel_alloc_pages);
|
||||
if (!kernel_alloc_addr)
|
||||
{
|
@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Fri, 29 Sep 2023 10:56:11 -0400
|
||||
Subject: [PATCH] Fix missing #include in ofdisk.c
|
||||
|
||||
Recently we started building with -Werror=implicit-function-declaration,
|
||||
and discovered that ofdisk.c is missing an include to declare
|
||||
grub_env_get().
|
||||
|
||||
This patch adds that #include.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index 5534684..6e33d5d 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <grub/ieee1275/ofdisk.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/time.h>
|
||||
+#include <grub/env.h>
|
||||
|
||||
static char *last_devpath;
|
||||
static grub_ieee1275_ihandle_t last_ihandle;
|
@ -0,0 +1,33 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Glombek <cglombek@redhat.com>
|
||||
Date: Tue, 14 Nov 2023 07:54:59 +0100
|
||||
Subject: [PATCH] Remove [Install] section from aux systemd units
|
||||
|
||||
See https://bugzilla.redhat.com/show_bug.cgi?id=2247635#c7
|
||||
---
|
||||
docs/grub-boot-indeterminate.service | 3 ---
|
||||
util/systemd/grub-systemd-integration.service.in | 3 ---
|
||||
2 files changed, 6 deletions(-)
|
||||
|
||||
diff --git a/docs/grub-boot-indeterminate.service b/docs/grub-boot-indeterminate.service
|
||||
index 5bcb474a3d31..6c8dcb186b63 100644
|
||||
--- a/docs/grub-boot-indeterminate.service
|
||||
+++ b/docs/grub-boot-indeterminate.service
|
||||
@@ -9,6 +9,3 @@ Before=system-update-pre.target
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/grub2-editenv - incr boot_indeterminate
|
||||
-
|
||||
-[Install]
|
||||
-WantedBy=system-update.target
|
||||
diff --git a/util/systemd/grub-systemd-integration.service.in b/util/systemd/grub-systemd-integration.service.in
|
||||
index 22ca1ca4885e..c81fb594ce17 100644
|
||||
--- a/util/systemd/grub-systemd-integration.service.in
|
||||
+++ b/util/systemd/grub-systemd-integration.service.in
|
||||
@@ -6,6 +6,3 @@ ConditionPathExists=/run/systemd/reboot-to-boot-loader-menu
|
||||
|
||||
[Service]
|
||||
ExecStart=@libexecdir@/@grubdirname@/systemd-integration.sh
|
||||
-
|
||||
-[Install]
|
||||
-WantedBy=reboot.target
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: "t.feng" <fengtao40@huawei.com>
|
||||
Date: Tue, 29 Nov 2022 17:14:15 +0800
|
||||
Subject: [PATCH] fs/xfs: Fix memory leaks in XFS module
|
||||
|
||||
Signed-off-by: t.feng <fengtao40@huawei.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/xfs.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index d6de7f1a2dd2..b67407690c1a 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -585,7 +585,10 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
if (grub_disk_read (node->data->disk,
|
||||
GRUB_XFS_FSB_TO_BLOCK (node->data, get_fsb (keys, i - 1 + recoffset)) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS),
|
||||
0, node->data->bsize, leaf))
|
||||
- return 0;
|
||||
+ {
|
||||
+ grub_free (leaf);
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
if ((!node->data->hascrc &&
|
||||
grub_strncmp ((char *) leaf->magic, "BMAP", 4)) ||
|
||||
@@ -751,6 +754,7 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
|
||||
if (err)
|
||||
{
|
||||
grub_print_error ();
|
||||
+ grub_free (fdiro);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -861,7 +865,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
blk << dirblk_log2,
|
||||
dirblk_size, dirblock, 0);
|
||||
if (numread != dirblk_size)
|
||||
- return 0;
|
||||
+ {
|
||||
+ grub_free (dirblock);
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
entries = (grub_be_to_cpu32 (tail->leaf_count)
|
||||
- grub_be_to_cpu32 (tail->leaf_stale));
|
@ -0,0 +1,106 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Darren Kenny <darren.kenny@oracle.com>
|
||||
Date: Fri, 2 Jun 2023 18:08:44 +0000
|
||||
Subject: [PATCH] fs/xfs: Fix issues found while fuzzing the XFS filesystem
|
||||
|
||||
While performing fuzz testing with XFS filesystem images with ASAN
|
||||
enabled, several issues were found where the memory accesses are made
|
||||
beyond the data that is allocated into the struct grub_xfs_data
|
||||
structure's data field.
|
||||
|
||||
The existing structure didn't store the size of the memory allocated into
|
||||
the buffer in the data field and had no way to check it. To resolve these
|
||||
issues, the data size is stored to enable checks into the data buffer.
|
||||
|
||||
With these checks in place, the fuzzing corpus no longer cause any crashes.
|
||||
|
||||
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
|
||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/xfs.c | 26 ++++++++++++++++++++++++++
|
||||
1 file changed, 26 insertions(+)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index b67407690c1a..b91cd32b49ab 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -239,6 +239,7 @@ struct grub_fshelp_node
|
||||
|
||||
struct grub_xfs_data
|
||||
{
|
||||
+ grub_size_t data_size;
|
||||
struct grub_xfs_sblock sblock;
|
||||
grub_disk_t disk;
|
||||
int pos;
|
||||
@@ -611,8 +612,20 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
}
|
||||
else if (node->inode.format == XFS_INODE_FORMAT_EXT)
|
||||
{
|
||||
+ grub_addr_t exts_end = 0;
|
||||
+ grub_addr_t data_end = 0;
|
||||
+
|
||||
nrec = grub_be_to_cpu32 (node->inode.nextents);
|
||||
exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
|
||||
+
|
||||
+ if (grub_mul (sizeof (struct grub_xfs_extent), nrec, &exts_end) ||
|
||||
+ grub_add ((grub_addr_t) node->data, exts_end, &exts_end) ||
|
||||
+ grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) ||
|
||||
+ exts_end > data_end)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS extents");
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -803,6 +816,9 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
|
||||
grub_uint8_t c;
|
||||
|
||||
+ if ((inopos + (smallino ? 4 : 8)) > (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode");
|
||||
+
|
||||
/* inopos might be unaligned. */
|
||||
if (smallino)
|
||||
ino = (((grub_uint32_t) inopos[0]) << 24)
|
||||
@@ -829,6 +845,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
de->name[de->len] = c;
|
||||
|
||||
de = grub_xfs_inline_next_de(dir->data, head, de);
|
||||
+
|
||||
+ if ((grub_uint8_t *) de >= (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
|
||||
+
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -897,6 +917,9 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
}
|
||||
|
||||
filename = (char *)(direntry + 1);
|
||||
+ if (filename + direntry->len - 1 > (char *) tail)
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
|
||||
+
|
||||
/* The byte after the filename is for the filetype, padding, or
|
||||
tag, which is not used by GRUB. So it can be overwritten. */
|
||||
filename[direntry->len] = '\0';
|
||||
@@ -941,6 +964,8 @@ grub_xfs_mount (grub_disk_t disk)
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
+ data->data_size = sizeof (struct grub_xfs_data);
|
||||
+
|
||||
grub_dprintf("xfs", "Reading sb\n");
|
||||
/* Read the superblock. */
|
||||
if (grub_disk_read (disk, 0, 0,
|
||||
@@ -962,6 +987,7 @@ grub_xfs_mount (grub_disk_t disk)
|
||||
if (! data)
|
||||
goto fail;
|
||||
|
||||
+ data->data_size = sz;
|
||||
data->diropen.data = data;
|
||||
data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino);
|
||||
data->diropen.inode_read = 1;
|
@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Lidong Chen <lidong.chen@oracle.com>
|
||||
Date: Thu, 28 Sep 2023 22:33:44 +0000
|
||||
Subject: [PATCH] fs/xfs: Incorrect short form directory data boundary check
|
||||
|
||||
After parsing of the current entry, the entry pointer is advanced
|
||||
to the next entry at the end of the "for" loop. In case where the
|
||||
last entry is at the end of the data boundary, the advanced entry
|
||||
pointer can point off the data boundary. The subsequent boundary
|
||||
check for the advanced entry pointer can cause a failure.
|
||||
|
||||
The fix is to include the boundary check into the "for" loop
|
||||
condition.
|
||||
|
||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
|
||||
Tested-by: Marta Lewandowska <mlewando@redhat.com>
|
||||
---
|
||||
grub-core/fs/xfs.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index b91cd32b49ab..ebf962793fa7 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -810,7 +810,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
if (iterate_dir_call_hook (parent, "..", &ctx))
|
||||
return 1;
|
||||
|
||||
- for (i = 0; i < head->count; i++)
|
||||
+ for (i = 0; i < head->count &&
|
||||
+ (grub_uint8_t *) de < ((grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)); i++)
|
||||
{
|
||||
grub_uint64_t ino;
|
||||
grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
|
||||
@@ -845,10 +846,6 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
de->name[de->len] = c;
|
||||
|
||||
de = grub_xfs_inline_next_de(dir->data, head, de);
|
||||
-
|
||||
- if ((grub_uint8_t *) de >= (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
|
||||
- return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
|
||||
-
|
||||
}
|
||||
break;
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Anthony Iliopoulos <ailiop@suse.com>
|
||||
Date: Thu, 26 Oct 2023 11:53:39 +0200
|
||||
Subject: [PATCH] fs/xfs: Add large extent counters incompat feature support
|
||||
|
||||
XFS introduced 64-bit extent counters for inodes via a series of
|
||||
upstream commits and the feature was marked as stable in v6.5 via
|
||||
commit 61d7e8274cd8 (xfs: drop EXPERIMENTAL tag for large extent
|
||||
counts).
|
||||
|
||||
Further, xfsprogs release v6.5.0 switched this feature on by default
|
||||
in mkfs.xfs via commit e5b18d7d1d96 (mkfs: enable large extent counts
|
||||
by default).
|
||||
|
||||
Filesystems formatted with large extent count support, nrext64=1, are
|
||||
thus currently not recognizable by GRUB, since this is an incompat
|
||||
feature. Add the required support so that those filesystems and inodes
|
||||
with large extent counters can be read by GRUB.
|
||||
|
||||
Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
|
||||
Reviewed-by: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Marta Lewandowska <mlewando@redhat.com>
|
||||
Tested-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
|
||||
---
|
||||
grub-core/fs/xfs.c | 30 +++++++++++++++++++++++++-----
|
||||
1 file changed, 25 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index 18edfcff486c..bc2224dbb463 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -79,6 +79,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
/* Inode flags2 flags */
|
||||
#define XFS_DIFLAG2_BIGTIME_BIT 3
|
||||
#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT)
|
||||
+#define XFS_DIFLAG2_NREXT64_BIT 4
|
||||
+#define XFS_DIFLAG2_NREXT64 (1 << XFS_DIFLAG2_NREXT64_BIT)
|
||||
|
||||
/* incompat feature flags */
|
||||
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
|
||||
@@ -86,6 +88,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
|
||||
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
|
||||
#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */
|
||||
+#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */
|
||||
|
||||
/*
|
||||
* Directory entries with ftype are explicitly handled by GRUB code.
|
||||
@@ -101,7 +104,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
XFS_SB_FEAT_INCOMPAT_SPINODES | \
|
||||
XFS_SB_FEAT_INCOMPAT_META_UUID | \
|
||||
XFS_SB_FEAT_INCOMPAT_BIGTIME | \
|
||||
- XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
|
||||
+ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \
|
||||
+ XFS_SB_FEAT_INCOMPAT_NREXT64)
|
||||
|
||||
struct grub_xfs_sblock
|
||||
{
|
||||
@@ -203,7 +207,8 @@ struct grub_xfs_inode
|
||||
grub_uint16_t mode;
|
||||
grub_uint8_t version;
|
||||
grub_uint8_t format;
|
||||
- grub_uint8_t unused2[26];
|
||||
+ grub_uint8_t unused2[18];
|
||||
+ grub_uint64_t nextents_big;
|
||||
grub_uint64_t atime;
|
||||
grub_uint64_t mtime;
|
||||
grub_uint64_t ctime;
|
||||
@@ -545,11 +550,26 @@ get_fsb (const void *keys, int idx)
|
||||
return grub_be_to_cpu64 (grub_get_unaligned64 (p));
|
||||
}
|
||||
|
||||
+static int
|
||||
+grub_xfs_inode_has_large_extent_counts (const struct grub_xfs_inode *inode)
|
||||
+{
|
||||
+ return inode->version >= 3 &&
|
||||
+ (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_NREXT64));
|
||||
+}
|
||||
+
|
||||
+static grub_uint64_t
|
||||
+grub_xfs_get_inode_nextents (struct grub_xfs_inode *inode)
|
||||
+{
|
||||
+ return (grub_xfs_inode_has_large_extent_counts (inode)) ?
|
||||
+ grub_be_to_cpu64 (inode->nextents_big) :
|
||||
+ grub_be_to_cpu32 (inode->nextents);
|
||||
+}
|
||||
+
|
||||
static grub_disk_addr_t
|
||||
grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
struct grub_xfs_btree_node *leaf = 0;
|
||||
- int ex, nrec;
|
||||
+ grub_uint64_t ex, nrec;
|
||||
struct grub_xfs_extent *exts;
|
||||
grub_uint64_t ret = 0;
|
||||
|
||||
@@ -574,7 +594,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
/ (2 * sizeof (grub_uint64_t));
|
||||
do
|
||||
{
|
||||
- int i;
|
||||
+ grub_uint64_t i;
|
||||
|
||||
for (i = 0; i < nrec; i++)
|
||||
{
|
||||
@@ -621,7 +641,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
grub_addr_t exts_end = 0;
|
||||
grub_addr_t data_end = 0;
|
||||
|
||||
- nrec = grub_be_to_cpu32 (node->inode.nextents);
|
||||
+ nrec = grub_xfs_get_inode_nextents (&node->inode);
|
||||
exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
|
||||
|
||||
if (grub_mul (sizeof (struct grub_xfs_extent), nrec, &exts_end) ||
|
@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: raravind <raravind@redhat.com>
|
||||
Date: Tue, 9 May 2023 11:29:35 +0200
|
||||
Subject: [PATCH] chainloader: remove device path debug message
|
||||
|
||||
Remove the debug message "/EndEntire" while using GRUB chainloader command.
|
||||
|
||||
Signed-off-by: raravind <raravind@redhat.com>
|
||||
(cherry picked from commit f75f5386b7a6a7cb2e10d30f817a3564c0a28dd7)
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index dd31ac9bb..b1c86dab2 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -210,7 +210,6 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
|
||||
/* Fill the file path for the directory. */
|
||||
d = (grub_efi_device_path_t *) ((char *) file_path
|
||||
+ ((char *) d - (char *) dp));
|
||||
- grub_efi_print_device_path (d);
|
||||
if (copy_file_path ((grub_efi_file_path_device_path_t *) d,
|
||||
dir_start, dir_end - dir_start) != GRUB_ERR_NONE)
|
||||
{
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Frayer <nfrayer@redhat.com>
|
||||
Date: Wed, 17 Jan 2024 21:15:14 +0100
|
||||
Subject: [PATCH] Ignore warnings for incompatible types
|
||||
|
||||
Add -Wno-incompatible-pointer-types to ignore warnings for incompatible
|
||||
types
|
||||
|
||||
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
|
||||
---
|
||||
configure.ac | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 79f45ef1e14c..b66e07c67851 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2009,8 +2009,8 @@ if test x"$enable_wextra" != xno ; then
|
||||
HOST_CFLAGS="$HOST_CFLAGS -Wextra"
|
||||
fi
|
||||
|
||||
-TARGET_CFLAGS="$TARGET_CFLAGS -Werror=trampolines -fno-trampolines"
|
||||
-HOST_CFLAGS="$HOST_CFLAGS -Werror=trampolines -fno-trampolines"
|
||||
+TARGET_CFLAGS="$TARGET_CFLAGS -Werror=trampolines -fno-trampolines -Wno-incompatible-pointer-types"
|
||||
+HOST_CFLAGS="$HOST_CFLAGS -Werror=trampolines -fno-trampolines -Wno-incompatible-pointer-types"
|
||||
|
||||
TARGET_CPP="$TARGET_CC -E"
|
||||
TARGET_CCAS=$TARGET_CC
|
@ -0,0 +1,168 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jon DeVree <nuxi@vault24.org>
|
||||
Date: Tue, 17 Oct 2023 23:03:47 -0400
|
||||
Subject: [PATCH] fs/xfs: Fix XFS directory extent parsing
|
||||
|
||||
The XFS directory entry parsing code has never been completely correct
|
||||
for extent based directories. The parser correctly handles the case
|
||||
where the directory is contained in a single extent, but then mistakenly
|
||||
assumes the data blocks for the multiple extent case are each identical
|
||||
to the single extent case. The difference in the format of the data
|
||||
blocks between the two cases is tiny enough that its gone unnoticed for
|
||||
a very long time.
|
||||
|
||||
A recent change introduced some additional bounds checking into the XFS
|
||||
parser. Like GRUB's existing parser, it is correct for the single extent
|
||||
case but incorrect for the multiple extent case. When parsing a directory
|
||||
with multiple extents, this new bounds checking is sometimes (but not
|
||||
always) tripped and triggers an "invalid XFS directory entry" error. This
|
||||
probably would have continued to go unnoticed but the /boot/grub/<arch>
|
||||
directory is large enough that it often has multiple extents.
|
||||
|
||||
The difference between the two cases is that when there are multiple
|
||||
extents, the data blocks do not contain a trailer nor do they contain
|
||||
any leaf information. That information is stored in a separate set of
|
||||
extents dedicated to just the leaf information. These extents come after
|
||||
the directory entry extents and are not included in the inode size. So
|
||||
the existing parser already ignores the leaf extents.
|
||||
|
||||
The only reason to read the trailer/leaf information at all is so that
|
||||
the parser can avoid misinterpreting that data as directory entries. So
|
||||
this updates the parser as follows:
|
||||
|
||||
For the single extent case the parser doesn't change much:
|
||||
1. Read the size of the leaf information from the trailer
|
||||
2. Set the end pointer for the parser to the start of the leaf
|
||||
information. (The previous bounds checking set the end pointer to the
|
||||
start of the trailer, so this is actually a small improvement.)
|
||||
3. Set the entries variable to the expected number of directory entries.
|
||||
|
||||
For the multiple extent case:
|
||||
1. Set the end pointer to the end of the block.
|
||||
2. Do not set up the entries variable. Figuring out how many entries are
|
||||
in each individual block is complex and does not seem worth it when
|
||||
it appears to be safe to just iterate over the entire block.
|
||||
|
||||
The bounds check itself was also dependent upon the faulty XFS parser
|
||||
because it accidentally used "filename + length - 1". Presumably this
|
||||
was able to pass the fuzzer because in the old parser there was always
|
||||
8 bytes of slack space between the tail pointer and the actual end of
|
||||
the block. Since this is no longer the case the bounds check needs to be
|
||||
updated to "filename + length + 1" in order to prevent a regression in
|
||||
the handling of corrupt fliesystems.
|
||||
|
||||
Notes:
|
||||
* When there is only one extent there will only ever be one block. If
|
||||
more than one block is required then XFS will always switch to holding
|
||||
leaf information in a separate extent.
|
||||
* B-tree based directories seems to be parsed properly by the same code
|
||||
that handles multiple extents. This is unlikely to ever occur within
|
||||
/boot though because its only used when there are an extremely large
|
||||
number of directory entries.
|
||||
|
||||
Fixes: ef7850c75 (fs/xfs: Fix issues found while fuzzing the XFS filesystem)
|
||||
Fixes: b2499b29c (Adds support for the XFS filesystem.)
|
||||
Fixes: https://savannah.gnu.org/bugs/?64376
|
||||
|
||||
Signed-off-by: Jon DeVree <nuxi@vault24.org>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
|
||||
Tested-by: Marta Lewandowska <mlewando@redhat.com>
|
||||
---
|
||||
grub-core/fs/xfs.c | 52 ++++++++++++++++++++++++++++++++++++++--------------
|
||||
1 file changed, 38 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index ebf962793fa7..18edfcff486c 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -223,6 +223,12 @@ struct grub_xfs_inode
|
||||
/* Size of struct grub_xfs_inode v2, up to unused4 member included. */
|
||||
#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76)
|
||||
|
||||
+struct grub_xfs_dir_leaf_entry
|
||||
+{
|
||||
+ grub_uint32_t hashval;
|
||||
+ grub_uint32_t address;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
struct grub_xfs_dirblock_tail
|
||||
{
|
||||
grub_uint32_t leaf_count;
|
||||
@@ -874,9 +880,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
{
|
||||
struct grub_xfs_dir2_entry *direntry =
|
||||
grub_xfs_first_de(dir->data, dirblock);
|
||||
- int entries;
|
||||
- struct grub_xfs_dirblock_tail *tail =
|
||||
- grub_xfs_dir_tail(dir->data, dirblock);
|
||||
+ int entries = -1;
|
||||
+ char *end = dirblock + dirblk_size;
|
||||
|
||||
numread = grub_xfs_read_file (dir, 0, 0,
|
||||
blk << dirblk_log2,
|
||||
@@ -887,14 +892,27 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
return 0;
|
||||
}
|
||||
|
||||
- entries = (grub_be_to_cpu32 (tail->leaf_count)
|
||||
- - grub_be_to_cpu32 (tail->leaf_stale));
|
||||
+ /*
|
||||
+ * Leaf and tail information are only in the data block if the number
|
||||
+ * of extents is 1.
|
||||
+ */
|
||||
+ if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
|
||||
+ {
|
||||
+ struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock);
|
||||
|
||||
- if (!entries)
|
||||
- continue;
|
||||
+ end = (char *) tail;
|
||||
+
|
||||
+ /* Subtract the space used by leaf nodes. */
|
||||
+ end -= grub_be_to_cpu32 (tail->leaf_count) * sizeof (struct grub_xfs_dir_leaf_entry);
|
||||
+
|
||||
+ entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale);
|
||||
+
|
||||
+ if (!entries)
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
/* Iterate over all entries within this block. */
|
||||
- while ((char *)direntry < (char *)tail)
|
||||
+ while ((char *) direntry < (char *) end)
|
||||
{
|
||||
grub_uint8_t *freetag;
|
||||
char *filename;
|
||||
@@ -914,7 +932,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
}
|
||||
|
||||
filename = (char *)(direntry + 1);
|
||||
- if (filename + direntry->len - 1 > (char *) tail)
|
||||
+ if (filename + direntry->len + 1 > (char *) end)
|
||||
return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
|
||||
|
||||
/* The byte after the filename is for the filetype, padding, or
|
||||
@@ -928,11 +946,17 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
return 1;
|
||||
}
|
||||
|
||||
- /* Check if last direntry in this block is
|
||||
- reached. */
|
||||
- entries--;
|
||||
- if (!entries)
|
||||
- break;
|
||||
+ /*
|
||||
+ * The expected number of directory entries is only tracked for the
|
||||
+ * single extent case.
|
||||
+ */
|
||||
+ if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
|
||||
+ {
|
||||
+ /* Check if last direntry in this block is reached. */
|
||||
+ entries--;
|
||||
+ if (!entries)
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
/* Select the next directory entry. */
|
||||
direntry = grub_xfs_next_de(dir->data, direntry);
|
@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Frayer <nfrayer@redhat.com>
|
||||
Date: Tue, 16 Jul 2024 11:11:43 +0200
|
||||
Subject: [PATCH] grub2-mkconfig: Ensure grub cfg stub is not overwritten
|
||||
|
||||
/boot/efi/EFI/$os_name/grub.cfg contains a grub cfg stub
|
||||
that should not be overwritten by grub2-mkconfig.
|
||||
Ensure that we prevent this from happening.
|
||||
|
||||
Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
|
||||
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
|
||||
---
|
||||
util/grub-mkconfig.in | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
|
||||
index 34f7c13fc521..34d0120d0ba2 100644
|
||||
--- a/util/grub-mkconfig.in
|
||||
+++ b/util/grub-mkconfig.in
|
||||
@@ -114,6 +114,20 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
+os_name=$(grep '^ID=' /etc/os-release | sed 's/ID=//')
|
||||
+if test "$os_name" = '"rhel"'; then
|
||||
+ os_name=redhat
|
||||
+elif test "$os_name" = '"centos"'; then
|
||||
+ os_name=centos
|
||||
+fi
|
||||
+if test "x${grub_cfg}" = "x/boot/efi/EFI/$os_name/grub.cfg" &&\
|
||||
+ mountpoint -q /boot/efi; then
|
||||
+ gettext_printf "Running \`grub2-mkconfig -o %s' will overwrite the GRUB wrapper.\n" "$grub_cfg" 1>&2
|
||||
+ gettext_printf "Please run \`grub2-mkconfig -o /boot/grub2/grub.cfg' instead to update grub.cfg.\n" 1>&2
|
||||
+ gettext_printf "GRUB configuration file was not updated.\n" 1>&2
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
if [ "x$EUID" = "x" ] ; then
|
||||
EUID=`id -u`
|
||||
fi
|
@ -0,0 +1,30 @@
|
||||
From ac5b2bc87a6c361fd504898a368f0867ef3e2679 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Lukoshko <alukoshko@almalinux.org>
|
||||
Date: Wed, 31 Jul 2024 16:06:10 +0000
|
||||
Subject: [PATCH] grub2-mkconfig: Simplify os_name detection
|
||||
|
||||
---
|
||||
util/grub-mkconfig.in | 7 +------
|
||||
1 file changed, 1 insertion(+), 6 deletions(-)
|
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
|
||||
index 7a0738b..ebf5150 100644
|
||||
--- a/util/grub-mkconfig.in
|
||||
+++ b/util/grub-mkconfig.in
|
||||
@@ -114,12 +114,7 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
-os_name=$(grep '^ID=' /etc/os-release | sed 's/ID=//')
|
||||
-if test "$os_name" = '"rhel"'; then
|
||||
- os_name=redhat
|
||||
-elif test "$os_name" = '"centos"'; then
|
||||
- os_name=centos
|
||||
-fi
|
||||
+os_name=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g')
|
||||
if test "x${grub_cfg}" = "x/boot/efi/EFI/$os_name/grub.cfg" &&\
|
||||
mountpoint -q /boot/efi; then
|
||||
gettext_printf "Running \`grub2-mkconfig -o %s' will overwrite the GRUB wrapper.\n" "$grub_cfg" 1>&2
|
||||
--
|
||||
2.43.5
|
||||
|
@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nicolas Frayer <nfrayer@redhat.com>
|
||||
Date: Thu, 1 Aug 2024 11:13:20 +0200
|
||||
Subject: [PATCH] grub/mkconfig: Remove check for mount point for grub cfg stub
|
||||
|
||||
Remove mountpoint when checking whether or not the grub cfg stub
|
||||
exists and add -s to the test. This should cover scenarios where
|
||||
the ESP doesn't have a seperate partition but still uses a grub
|
||||
cfg stub
|
||||
|
||||
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
|
||||
---
|
||||
util/grub-mkconfig.in | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
|
||||
index a4972039b751..3f131eea2b12 100644
|
||||
--- a/util/grub-mkconfig.in
|
||||
+++ b/util/grub-mkconfig.in
|
||||
@@ -115,8 +115,7 @@ do
|
||||
done
|
||||
|
||||
os_name=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g')
|
||||
-if test "x${grub_cfg}" = "x/boot/efi/EFI/$os_name/grub.cfg" &&\
|
||||
- mountpoint -q /boot/efi; then
|
||||
+if test -s "${grub_cfg}" && test "x${grub_cfg}" = "x/boot/efi/EFI/$os_name/grub.cfg"; then
|
||||
gettext_printf "Running \`grub2-mkconfig -o %s' will overwrite the GRUB wrapper.\n" "$grub_cfg" 1>&2
|
||||
gettext_printf "Please run \`grub2-mkconfig -o /boot/grub2/grub.cfg' instead to update grub.cfg.\n" 1>&2
|
||||
gettext_printf "GRUB configuration file was not updated.\n" 1>&2
|
@ -0,0 +1,29 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Leo Sandoval <lsandova@redhat.com>
|
||||
Date: Mon, 1 Jul 2024 12:52:13 -0600
|
||||
Subject: [PATCH] grub-mkconfig.in: turn off executable owner bit
|
||||
|
||||
Stricker permissions are required on the grub.cfg file, resulting in
|
||||
at most 0600 owner's file permissions. This resolves conflicting
|
||||
requirement permissions on grub2-pc package's grub2.cfg file.
|
||||
|
||||
Resolves: RHEL-45870
|
||||
|
||||
Signed-off-by: Leo Sandoval <lsandova@redhat.com>
|
||||
---
|
||||
util/grub-mkconfig.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
|
||||
index 3f131eea2b12..8c2bb8259de1 100644
|
||||
--- a/util/grub-mkconfig.in
|
||||
+++ b/util/grub-mkconfig.in
|
||||
@@ -328,7 +328,7 @@ and /etc/grub.d/* files or please file a bug report with
|
||||
exit 1
|
||||
else
|
||||
# none of the children aborted with error, install the new grub.cfg
|
||||
- oldumask=$(umask); umask 077
|
||||
+ oldumask=$(umask); umask 177
|
||||
cat ${grub_cfg}.new > ${grub_cfg}
|
||||
umask $oldumask
|
||||
rm -f ${grub_cfg}.new
|
@ -1,3 +1,4 @@
|
||||
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
|
||||
grub,3,Free Software Foundation,grub,@@VERSION@@,https//www.gnu.org/software/grub/
|
||||
grub.rh,2,Red Hat,grub2,@@VERSION_RELEASE@@,mailto:secalert@redhat.com
|
||||
grub.msvsphere,2,MSVSphere,grub2,@@VERSION_RELEASE@@,mailto:security@msvsphere-os.ru
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue