Compare commits

..

10 commits

Author SHA1 Message Date
Nicolas Frayer
6b935e7021 osdep/linux/getroot: Detect DDF container similar to IMSM
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
2025-06-17 18:05:15 +02:00
Nicolas Frayer
09bf4d360e Some fixes addressing memory freeing and dereferencing
Resolves: #2368939
Resolves: #2368945
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
2025-05-28 19:40:21 +02:00
Leo Sandoval
279b2840e4 Handle special kernel parameter characters properly
Resolves: #2362821
Signed-off-by: Leo Sandoval <lsandova@redhat.com>
2025-05-27 17:28:32 -06:00
Nicolas Frayer
497a24edb2 sbat: bump grub sbat
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
2025-05-19 19:02:29 +02:00
Nicolas Frayer
debcc8e166 ieee1275/ofnet: Fix grub_malloc() removed after added safe
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
2025-03-27 10:56:26 +01:00
Leo Sandoval
cdd4d755fb Remove NTFS attribute verification patch
The removed patch was part of the CVE patches ported recently into Fedora but
unfortunately this is causing segfaults when generating the grub configuration
file. At some point the same patch will come back with the corresponding fix but
for the time being, it is removed. Note that patch numeration did not change on
purpose: patch will be introduced again so need to mess with the numeration.

Resolves: #2350327

Signed-off-by: Leo Sandoval <lsandova@redhat.com>
2025-03-10 13:07:58 -06:00
Nicolas Frayer
45ceb182d4 fs/ext2: Rework out-of-bounds read for inline and external extents
Resolves: #2346804
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
2025-03-05 19:07:10 +01:00
Leo Sandoval
4c3a62abb4 Add Several CVE fixes
Resolves: CVE-2024-45781 CVE-2024-45783 CVE-2024-45778
Resolves: CVE-2024-45775 CVE-2024-45780 CVE-2024-45774
Resolves: CVE-2025-0690 CVE-2025-1118 CVE-2024-45782
Resolves: CVE-2025-0624 CVE-2024-45779 CVE-2024-45776
Resolves: CVE-2025-0622 CVE-2025-0677

Signed-off-by: Leo Sandoval <lsandova@redhat.com>
2025-02-28 09:14:39 -06:00
Marta Lewandowska
5935ba175c 99-grub-mkconfig.install: on PPC systems, remove petiboot's version checks
On PPC systems, there is no need to check petiboot's version, so remove all
related lines and unconditionally turn on the corresponding flag.

Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
2024-12-02 19:03:26 -06:00
Marta Lewandowska
705360dd72 99-grub-mkconfig.install: Disable BLS and run grub2-mkconfig when GRUB_ENABLE_BLSCFG is disable
Resolves: #2325960

Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
2024-12-02 19:02:20 -06:00
133 changed files with 132 additions and 6502 deletions

View file

@ -129,7 +129,7 @@ index 00000000000..a851424beb2
+# Print the usage.
+usage () {
+ gettext_printf "Usage: %s\n" "$self"
+ gettext "Switch to BLS config files."; echo
+ gettext "Switch to BLS config files.\n"; echo
+ echo
+ print_option_help "-h, --help" "$(gettext "print this message and exit")"
+ print_option_help "-V, --version" "$(gettext "print the version information and exit")"

View file

@ -1,44 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Wed, 4 Dec 2024 07:50:28 -0600
Subject: [PATCH] fs/xfs: fix large extent counters incompat feature support
When large extent counter / NREXT64 support was added to grub, it missed
a couple of direct reads of nextents which need to be changed to the new
NREXT64-aware helper as well. Without this, we'll have mis-reads of some
directories with this feature enabled.
(The large extent counter fix likely raced on merge with
07318ee7e ("fs/xfs: Fix XFS directory extent parsing") which added the new
direct nextents reads just prior, causing this issue.)
Fixes: aa7c1322671e ("fs/xfs: Add large extent counters incompat feature support")
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Anthony Iliopoulos <ailiop@suse.com>
Reviewed-by: Jon DeVree <nuxi@vault24.org>
---
grub-core/fs/xfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 8e02ab4a3014..92046f9bdf49 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -926,7 +926,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
* 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))
+ if (grub_xfs_get_inode_nextents(&dir->inode) == 1)
{
struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock);
@@ -980,7 +980,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
* 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))
+ if (grub_xfs_get_inode_nextents(&dir->inode) == 1)
{
/* Check if last direntry in this block is reached. */
entries--;

View file

@ -1,34 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: Thu, 16 Jan 2025 10:22:48 -0600
Subject: [PATCH] term/nns8250-spcr: return if redirection is disabled
The Microsoft spec for SPCR says "The base address of the Serial Port register
set described using the ACPI Generic Address Structure, or 0 if console
redirection is disabled." so return if disable (base address = 0). If this check
is not done, we may get invalid ports for those particular machines that
redirection is disabled and at some point hanging the booting execution when
reading the grub.cfg configuration file.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
---
grub-core/term/ns8250-spcr.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/grub-core/term/ns8250-spcr.c b/grub-core/term/ns8250-spcr.c
index d52b52c26..86f1aa078 100644
--- a/grub-core/term/ns8250-spcr.c
+++ b/grub-core/term/ns8250-spcr.c
@@ -75,6 +75,11 @@ grub_ns8250_spcr_init (void)
config.speed = 115200;
break;
};
+
+ /* if base address is 0, it means redirection is disable, so return it */
+ if (spcr->base_addr.addr == 0)
+ return NULL;
+
switch (spcr->base_addr.space_id)
{
case GRUB_ACPI_GENADDR_MEM_SPACE:

View file

@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
Date: Wed, 16 Oct 2024 11:54:38 -0600
Subject: [PATCH] commands/legacycfg: Avoid closing file twice
An internal (at Red Hat) static soure code scan detected an
use-after-free scenario:
Error: USE_AFTER_FREE (CWE-416):
grub-2.06/grub-core/commands/legacycfg.c:194: freed_arg: "grub_file_close" frees "file".
grub-2.06/grub-core/commands/legacycfg.c:201: deref_arg: Calling "grub_file_close" dereferences freed pointer "file".
# 199| if (!args)
# 200| {
# 201|-> grub_file_close (file);
# 202| grub_free (suffix);
# 203| grub_free (entrysrc);
So, remove the extra file close call.
Signed-off-by: Leo Sandoval <lsandova@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/legacycfg.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
index 2c5d1a0ef..86bcda695 100644
--- a/grub-core/commands/legacycfg.c
+++ b/grub-core/commands/legacycfg.c
@@ -198,7 +198,6 @@ legacy_file (const char *filename)
const char **args = grub_malloc (sizeof (args[0]));
if (!args)
{
- grub_file_close (file);
grub_free (suffix);
grub_free (entrysrc);
return grub_errno;

View file

@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
Date: Wed, 22 Jan 2025 13:37:42 -0600
Subject: [PATCH] disk/ahci.c: remove conditional operator for endtime
The conditional makes no sense when the two possible expressions have the same
value, so remove it (perhaps the compiler does it for us but better to remove
it).
Signed-off-by: Leo Sandoval <lsandova@redhat.com>
---
grub-core/disk/ahci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/disk/ahci.c b/grub-core/disk/ahci.c
index e7b5dc5f2..b247161b9 100644
--- a/grub-core/disk/ahci.c
+++ b/grub-core/disk/ahci.c
@@ -1038,7 +1038,7 @@ grub_ahci_readwrite_real (struct grub_ahci_device *dev,
grub_dprintf ("ahci", "AHCI tfd = %x\n",
dev->hba->ports[dev->port].task_file_data);
- endtime = grub_get_time_ms () + (spinup ? 20000 : 20000);
+ endtime = grub_get_time_ms () + 20000;
while ((dev->hba->ports[dev->port].command_issue & 1))
if (grub_get_time_ms () > endtime ||
(dev->hba->ports[dev->port].intstatus & GRUB_AHCI_HBA_PORT_IS_FATAL_MASK))

View file

@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Wed, 17 Jul 2024 14:46:46 +0800
Subject: [PATCH] commands/bli: Fix crash in get_part_uuid()
The get_part_uuid() function made an assumption that the target GRUB
device is a partition device and accessed device->disk->partition
without checking for NULL. There are four situations where this
assumption is problematic:
1. The device is a net device instead of a disk.
2. The device is an abstraction device, like LVM, RAID, or CRYPTO, which
is mostly logical "disk" ((lvmid/<UUID>) and so on).
3. Firmware RAID may present the ESP to GRUB as an EFI disk (hd0) device
if it is contained within a Linux software RAID.
4. When booting from a CD-ROM, the ESP is a VFAT image indexed by the El
Torito boot catalog. The boot device is set to (cd0), corresponding
to the CD-ROM image mounted as an ISO 9660 filesystem.
As a result, get_part_uuid() could lead to a NULL pointer dereference
and trigger a synchronous exception during boot if the ESP falls into
one of these categories. This patch fixes the problem by adding the
necessary checks to handle cases where the ESP is not a partition device.
Additionally, to avoid disrupting the boot process, this patch relaxes
the severity of the errors in this context to non-critical. Errors will
be logged, but they will not prevent the boot process from continuing.
Fixes: e0fa7dc84 (bli: Add a module for the Boot Loader Interface)
Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-By: Oliver Steffen <osteffen@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/bli.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
index e0d8a54f7bea..298c5f70a876 100644
--- a/grub-core/commands/bli.c
+++ b/grub-core/commands/bli.c
@@ -48,6 +48,22 @@ get_part_uuid (const char *device_name, char **part_uuid)
if (device == NULL)
return grub_error (grub_errno, N_("cannot open device: %s"), device_name);
+ if (device->disk == NULL)
+ {
+ grub_dprintf ("bli", "%s is not a disk device, partuuid skipped\n", device_name);
+ *part_uuid = NULL;
+ grub_device_close (device);
+ return GRUB_ERR_NONE;
+ }
+
+ if (device->disk->partition == NULL)
+ {
+ grub_dprintf ("bli", "%s has no partition, partuuid skipped\n", device_name);
+ *part_uuid = NULL;
+ grub_device_close (device);
+ return GRUB_ERR_NONE;
+ }
+
disk = grub_disk_open (device->disk->name);
if (disk == NULL)
{
@@ -99,7 +115,7 @@ set_loader_device_part_uuid (void)
status = get_part_uuid (device_name, &part_uuid);
- if (status == GRUB_ERR_NONE)
+ if (status == GRUB_ERR_NONE && part_uuid)
status = grub_efi_set_variable_to_string ("LoaderDevicePartUUID", &bli_vendor_guid, part_uuid,
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
@@ -117,4 +133,6 @@ GRUB_MOD_INIT (bli)
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
set_loader_device_part_uuid ();
+ /* No error here is critical, other than being logged */
+ grub_print_error ();
}

View file

@ -22,10 +22,10 @@ Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c
index b832593213e6..4bf386b590b5 100644
index 527d4f0c538a..7872a8d03a0b 100644
--- a/grub-core/osdep/linux/getroot.c
+++ b/grub-core/osdep/linux/getroot.c
@@ -127,7 +127,7 @@ struct btrfs_ioctl_search_args {
@@ -119,7 +119,7 @@ struct btrfs_ioctl_search_args {
struct btrfs_ioctl_fs_info_args)
static int
@ -34,7 +34,7 @@ index b832593213e6..4bf386b590b5 100644
#define ESCAPED_PATH_MAX (4 * PATH_MAX)
@@ -759,10 +759,10 @@ out:
@@ -638,10 +638,10 @@ out:
}
static int
@ -47,7 +47,7 @@ index b832593213e6..4bf386b590b5 100644
int container_seen = 0;
const char *dev = os_dev;
@@ -823,10 +823,17 @@ grub_util_is_imsm (const char *os_dev)
@@ -702,10 +702,17 @@ grub_util_is_imsm (const char *os_dev)
if (strncmp (buf, "MD_METADATA=imsm",
sizeof ("MD_METADATA=imsm") - 1) == 0)
{
@ -66,7 +66,7 @@ index b832593213e6..4bf386b590b5 100644
}
free (buf);
@@ -837,7 +844,7 @@ grub_util_is_imsm (const char *os_dev)
@@ -716,7 +723,7 @@ grub_util_is_imsm (const char *os_dev)
if (dev != os_dev)
free ((void *) dev);
@ -75,7 +75,7 @@ index b832593213e6..4bf386b590b5 100644
}
char *
@@ -1202,7 +1209,7 @@ grub_util_get_dev_abstraction_os (const char *os_dev)
@@ -1081,7 +1088,7 @@ grub_util_get_dev_abstraction_os (const char *os_dev)
/* Check for RAID. */
if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev)

View file

@ -1,117 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <avnish@linux.ibm.com>
Date: Thu, 13 Mar 2025 19:45:50 +0530
Subject: [PATCH] powerpc: increase MIN RMA size for CAS negotiation
Change RMA size from 512 MB to 768 MB which will result
in more memory at boot time for PowerPC. When vTPM, Secure Boot or
FADump are enabled on PowerPC, the 512 MB RMA memory is not sufficient for
booting. With this 512 MB RMA, GRUB2 runs out of memory and fails to
boot the machine. Sometimes even usage of CDROM requires more memory
for installation and along with the options mentioned above exhausts
the boot memory which results in boot failures. Increasing the RMA size
will resolves multiple out of memory issues observed in PowerPC.
Failure details (GRUB2 debugs):
kern/ieee1275/init.c:550: mm requested region of size 8513000, flags 1
kern/ieee1275/init.c:563: Cannot satisfy allocation and retain minimum runtime space
kern/ieee1275/init.c:550: mm requested region of size 8513000, flags 0
kern/ieee1275/init.c:563: Cannot satisfy allocation and retain minimum runtime space
kern/file.c:215: Closing `/ppc/ppc64/initrd.img' ...
kern/disk.c:297: Closing `ieee1275//vdevice/v-scsi@30000067/disk@8300000000000000'...
kern/disk.c:311: Closing `ieee1275//vdevice/v-scsi@30000067/disk@8300000000000000' succeeded.
kern/file.c:225: Closing `/ppc/ppc64/initrd.img' failed with 3.
kern/file.c:148: Opening `/ppc/ppc64/initrd.img' succeeded.
error: ../../grub-core/kern/mm.c:552:out of memory.
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
---
grub-core/kern/ieee1275/init.c | 51 +++++++++++++++++++++++++++++++++++++-----
1 file changed, 46 insertions(+), 5 deletions(-)
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index 4ec6598cfbb8..bb791f80f41c 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -737,7 +737,7 @@ struct cas_vector
/*
* Call ibm,client-architecture-support to try to get more RMA.
- * We ask for 512MB which should be enough to verify a distro kernel.
+ * We ask for 768MB which should be enough to verify a distro kernel.
* We ignore most errors: if we don't succeed we'll proceed with whatever
* memory we have.
*/
@@ -809,7 +809,7 @@ grub_ieee1275_ibm_cas (void)
.vec1 = 0x80, /* ignore */
.vec2_size = 1 + sizeof (struct option_vector2) - 2,
.vec2 = {
- 0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48
+ 0, 0, -1, -1, -1, -1, -1, 768, -1, 0, 48
},
.vec3_size = 2 - 1,
.vec3 = 0x00e0, /* ask for FP + VMX + DFP but don't halt if unsatisfied */
@@ -846,6 +846,10 @@ grub_claim_heap (void)
{
grub_err_t err;
grub_uint32_t total = HEAP_MAX_SIZE;
+#if defined(__powerpc__)
+ grub_uint32_t ibm_ca_support_reboot = 0;
+ grub_ssize_t actual;
+#endif
err = grub_ieee1275_total_mem (&rmo_top);
@@ -858,11 +862,48 @@ grub_claim_heap (void)
grub_mm_add_region_fn = grub_ieee1275_mm_add_region;
#if defined(__powerpc__)
+ /* Check if it's a CAS reboot with below property. If so, we will skip CAS call */
+ if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
+ "ibm,client-architecture-support-reboot",
+ &ibm_ca_support_reboot,
+ sizeof (ibm_ca_support_reboot),
+ &actual) >= 0)
+ grub_dprintf ("ieee1275", "ibm,client-architecture-support-reboot: %" PRIuGRUB_UINT32_T "\n",
+ ibm_ca_support_reboot);
+
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY))
{
- /* if we have an error, don't call CAS, just hope for the best */
- if (err == GRUB_ERR_NONE && rmo_top < (512 * 1024 * 1024))
- grub_ieee1275_ibm_cas ();
+ /*
+ * If we have an error, don't call CAS. Just hope for the best.
+ * Along with the above, if the rmo_top is 512 MB or above. We
+ * will skip the CAS call. However, if we call CAS, the rmo_top
+ * will be set to 768 MB via CAS Vector2. But we need to call
+ * CAS with "rmo_top < 512 MB" to avoid the issue on the older
+ * Linux kernel, which still uses rmo_top as 512 MB. If we call
+ * CAS with a condition "rmo_top < 768 MB", it will result in an
+ * issue due to the IBM CAS reboot feature and we won't be able
+ * to boot the newer kernel. Whenever a reboot is detected as
+ * the CAS reboot by GRUB. It will boot the machine with the
+ * last booted kernel by reading the variable "boot-last-label"
+ * which has the info related to the last boot and it's specific
+ * to IBM PowerPC. Due to this, the machine will boot with the
+ * last booted kernel which has rmo_top as 512 MB. Also, if the
+ * reboot is detected as a CAS reboot, the GRUB will skip the CAS
+ * call. As the CAS has already been called earlier, so it is
+ * not required to call CAS even if the other conditions are met.
+ * This condition will also prevent a scenario where the machine
+ * get stuck in the CAS reboot loop while booting. A machine with
+ * an older kernel, having option_vector2 MIN_RMA as 512 MB in
+ * Linux prom_init.c and GRUB uses "rmo_top < 768 MB" condition
+ * for calling CAS. Due to their respective conditions, linux
+ * CAS and GRUB CAS will keep doing the CAS calls and change
+ * the MIN_RMA from 768(changed by GRUB) to 512(changed by Linux)
+ * to 768(changed by GRUB) to 512(changed by Linux) and so on,
+ * and the machine will stuck in this CAS reboot loop forever.
+ * IBM PAPR : https://openpower.foundation/specifications/linuxonpower/
+ */
+ if (!ibm_ca_support_reboot && err == GRUB_ERR_NONE && rmo_top < (512 * 1024 * 1024))
+ grub_ieee1275_ibm_cas ();
}
#endif

View file

@ -1,66 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: James Le Cuirot <jlecuirot@microsoft.com>
Date: Thu, 24 Oct 2024 14:42:46 +0100
Subject: [PATCH] script/execute: Don't let trailing blank lines determine the
return code
grub_script_execute_sourcecode() parses and executes code one line at a
time, updating the return code each time because only the last line
determines the final status. However, trailing new lines were also
executed, masking any failure on the previous line. Fix this by only
trying to execute the command when there is actually one present.
This has presumably never been noticed because this code is not used by
regular functions, only in special cases like eval and menu entries. The
latter generally don't return at all, having booted an OS. When failing
to boot, upstream GRUB triggers the fallback mechanism regardless of the
return code.
We noticed the problem while using Red Hat's patches, which change this
behaviour to take account of the return code. In that case, a failure
takes you back to the menu rather than triggering a fallback.
Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
---
grub-core/script/execute.c | 5 ++++-
tests/grub_script_eval.in | 10 +++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index 014132703..3d26a3fe4 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -952,7 +952,10 @@ grub_script_execute_sourcecode (const char *source)
break;
}
- ret = grub_script_execute (parsed_script);
+ /* Don't let trailing blank lines determine the return code. */
+ if (parsed_script->cmd)
+ ret = grub_script_execute (parsed_script);
+
grub_script_free (parsed_script);
grub_free (line);
}
diff --git a/tests/grub_script_eval.in b/tests/grub_script_eval.in
index c97b78d77..9c6211042 100644
--- a/tests/grub_script_eval.in
+++ b/tests/grub_script_eval.in
@@ -3,4 +3,12 @@
eval echo "Hello world"
valname=tst
eval $valname=hi
-echo $tst
\ No newline at end of file
+echo $tst
+
+if eval "
+false
+"; then
+ echo should have failed
+else
+ echo failed as expected
+fi
--
2.48.1

View file

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: James Le Cuirot <jlecuirot@microsoft.com>
Date: Thu, 24 Oct 2024 15:00:26 +0100
Subject: [PATCH] normal/menu: Check return code of the script when executing a
menu entry
Don't rely on grub_errno here because grub_script_execute_new_scope()
calls grub_print_error(), which always resets grub_errno back to
GRUB_ERR_NONE. It may also get reset by grub_wait_after_message().
This problem was observed when a "bad signature" error resulted in the
menu being redisplayed rather than the fallback mechanism being
triggered, although another change was also needed to fix it. This only
happens with Red Hat's patches because upstream GRUB triggers the
fallback mechanism regardless of the return code.
Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
---
grub-core/normal/menu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 97687013c..a2703dabb 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -377,14 +377,14 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
if (ptr && ptr[0] && ptr[1])
grub_env_set ("default", ptr + 1);
- grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args);
+ err = grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args);
if (errs_before != grub_err_printed_errors)
grub_wait_after_message ();
errs_before = grub_err_printed_errors;
- if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
+ if (err == GRUB_ERR_NONE && grub_loader_is_loaded ())
/* Implicit execution of boot, only if something is loaded. */
err = grub_command_execute ("boot", 0, 0);
--
2.48.1

View file

@ -1,167 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Date: Wed, 23 Oct 2024 17:54:32 +0530
Subject: [PATCH] grub-mkimage: Create new ELF note for SBAT
In order to store the SBAT data we create a new ELF note. The string
".sbat", zero-padded to 4 byte alignment, shall be entered in the name
field. The string "SBAT"'s ASCII values, 0x53424154, should be entered
in the type field.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
include/grub/util/mkimage.h | 4 ++--
util/grub-mkimagexx.c | 48 +++++++++++++++++++++++++++++++++++++++++++--
util/mkimage.c | 5 +++--
3 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
index 6f1da89b9b65..881e3031f41f 100644
--- a/include/grub/util/mkimage.h
+++ b/include/grub/util/mkimage.h
@@ -51,12 +51,12 @@ grub_mkimage_load_image64 (const char *kernel_path,
const struct grub_install_image_target_desc *image_target);
void
grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target,
- int note, size_t appsig_size, char **core_img, size_t *core_size,
+ int note, size_t appsig_size, char *sbat, char **core_img, size_t *core_size,
Elf32_Addr target_addr,
struct grub_mkimage_layout *layout);
void
grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target,
- int note, size_t appsig_size, char **core_img, size_t *core_size,
+ int note, size_t appsig_size, char *sbat, char **core_img, size_t *core_size,
Elf64_Addr target_addr,
struct grub_mkimage_layout *layout);
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index 9488f052510a..b9930544889d 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -116,6 +116,14 @@ struct section_metadata
const char *strtab;
};
+#define GRUB_SBAT_NOTE_NAME ".sbat"
+#define GRUB_SBAT_NOTE_TYPE 0x53424154 /* "SBAT" */
+
+struct grub_sbat_note {
+ Elf32_Nhdr header;
+ char name[ALIGN_UP(sizeof(GRUB_SBAT_NOTE_NAME), 4)];
+};
+
static int
is_relocatable (const struct grub_install_image_target_desc *image_target)
{
@@ -217,7 +225,7 @@ grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr)
void
SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target,
- int note, size_t appsig_size, char **core_img, size_t *core_size,
+ int note, size_t appsig_size, char *sbat, char **core_img, size_t *core_size,
Elf_Addr target_addr,
struct grub_mkimage_layout *layout)
{
@@ -226,10 +234,17 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
Elf_Ehdr *ehdr;
Elf_Phdr *phdr;
Elf_Shdr *shdr;
- int header_size, footer_size = 0;
+ int header_size, footer_size = 0, footer_offset = 0;
int phnum = 1;
int shnum = 4;
int string_size = sizeof (".text") + sizeof ("mods") + 1;
+ char *footer;
+
+ if (sbat)
+ {
+ phnum++;
+ footer_size += ALIGN_UP (sizeof (struct grub_sbat_note) + layout->sbat_size, 4);
+ }
if (appsig_size)
{
@@ -263,6 +278,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
ehdr = (void *) elf_img;
phdr = (void *) (elf_img + sizeof (*ehdr));
shdr = (void *) (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr));
+ footer = elf_img + program_size + header_size;
memcpy (ehdr->e_ident, ELFMAG, SELFMAG);
ehdr->e_ident[EI_CLASS] = ELFCLASSXX;
if (!image_target->bigendian)
@@ -435,6 +451,8 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
phdr->p_filesz = grub_host_to_target32 (XEN_NOTE_SIZE);
phdr->p_memsz = 0;
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
+ footer = ptr;
+ footer_offset = XEN_NOTE_SIZE;
}
if (image_target->id == IMAGE_XEN_PVH)
@@ -468,6 +486,8 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
phdr->p_filesz = grub_host_to_target32 (XEN_PVH_NOTE_SIZE);
phdr->p_memsz = 0;
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
+ footer = ptr;
+ footer_offset = XEN_PVH_NOTE_SIZE;
}
if (note)
@@ -498,6 +518,30 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
phdr->p_filesz = grub_host_to_target32 (note_size);
phdr->p_memsz = 0;
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
+ footer = (elf_img + program_size + header_size + note_size);
+ footer_offset += note_size;
+ }
+
+ if (sbat)
+ {
+ int note_size = ALIGN_UP (sizeof (struct grub_sbat_note) + layout->sbat_size, 4);
+ struct grub_sbat_note *note_ptr = (struct grub_sbat_note *) footer;
+
+ note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_SBAT_NOTE_NAME));
+ note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(layout->sbat_size, 4));
+ note_ptr->header.n_type = grub_host_to_target32 (GRUB_SBAT_NOTE_TYPE);
+ memcpy (note_ptr->name, GRUB_SBAT_NOTE_NAME, sizeof (GRUB_SBAT_NOTE_NAME));
+ memcpy ((char *)(note_ptr + 1), sbat, layout->sbat_size);
+
+ phdr++;
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
+ phdr->p_flags = grub_host_to_target32 (PF_R);
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
+ phdr->p_vaddr = 0;
+ phdr->p_paddr = 0;
+ phdr->p_filesz = grub_host_to_target32 (note_size);
+ phdr->p_memsz = 0;
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size + footer_offset);
}
if (appsig_size) {
diff --git a/util/mkimage.c b/util/mkimage.c
index f31fdefa814a..7fa6a7b21954 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -1848,6 +1848,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
case IMAGE_I386_IEEE1275:
{
grub_uint64_t target_addr;
+ char *sbat = NULL;
if (image_target->id == IMAGE_LOONGSON_ELF)
{
if (comp == GRUB_COMPRESSION_NONE)
@@ -1859,10 +1860,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
else
target_addr = image_target->link_addr;
if (image_target->voidp_sizeof == 4)
- grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img,
+ grub_mkimage_generate_elf32 (image_target, note, appsig_size, sbat, &core_img,
&core_size, target_addr, &layout);
else
- grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img,
+ grub_mkimage_generate_elf64 (image_target, note, appsig_size, sbat, &core_img,
&core_size, target_addr, &layout);
}
break;

View file

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Date: Wed, 23 Oct 2024 17:54:33 +0530
Subject: [PATCH] grub-mkimage: Add SBAT metadata into ELF note for PowerPC
targets
The SBAT metadata is read from CSV file and transformed into an ELF note
with the -s option.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
util/mkimage.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/util/mkimage.c b/util/mkimage.c
index 7fa6a7b21954..f92949d1df25 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -957,8 +957,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
total_module_size += dtb_size + sizeof (struct grub_module_header);
}
- if (sbat_path != NULL && image_target->id != IMAGE_EFI)
- grub_util_error (_(".sbat section can be embedded into EFI images only"));
+ if (sbat_path != NULL && (image_target->id != IMAGE_EFI && image_target->id != IMAGE_PPC))
+ grub_util_error (_("SBAT data can be added only to EFI or powerpc-ieee1275 images"));
if (disable_shim_lock)
total_module_size += sizeof (struct grub_module_header);
@@ -1849,6 +1849,13 @@ grub_install_generate_image (const char *dir, const char *prefix,
{
grub_uint64_t target_addr;
char *sbat = NULL;
+ if (sbat_path != NULL)
+ {
+ sbat_size = grub_util_get_image_size (sbat_path);
+ sbat = xmalloc (sbat_size);
+ grub_util_load_image (sbat_path, sbat);
+ layout.sbat_size = sbat_size;
+ }
if (image_target->id == IMAGE_LOONGSON_ELF)
{
if (comp == GRUB_COMPRESSION_NONE)

View file

@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Fri, 28 Feb 2025 17:00:53 +0300
Subject: [PATCH] kern/rescue_reader: Block the rescue mode until the CLI
authentication
This further mitigates potential misuse of the CLI after the
root device has been successfully unlocked via TPM.
Fixes: CVE-2025-4382
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/rescue_reader.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c
index 4259857ba9..a71ada8fb7 100644
--- a/grub-core/kern/rescue_reader.c
+++ b/grub-core/kern/rescue_reader.c
@@ -79,7 +79,7 @@ void __attribute__ ((noreturn))
grub_rescue_run (void)
{
/* Stall if the CLI has been disabled */
- if (grub_is_cli_disabled ())
+ if (grub_is_cli_disabled () || grub_is_cli_need_auth ())
{
grub_printf ("Rescue mode has been disabled...\n");

View file

@ -1,133 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Sat, 1 Mar 2025 14:16:48 +0300
Subject: [PATCH] commands/search: Introduce the --cryptodisk-only argument
This allows users to restrict the "search" command's scope to
encrypted disks only.
Typically, this command is used to "rebase" $root and $prefix
before loading additional configuration files via "source" or
"configfile". Unfortunately, this leads to security problems,
like CVE-2023-4001, when an unexpected, attacker-controlled
device is chosen by the "search" command.
The --cryptodisk-only argument allows users to ensure that the
file system picked is encrypted.
This feature supports the CLI authentication, blocking bypass
attempts.
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/search.c | 20 ++++++++++++++++++++
grub-core/commands/search_wrap.c | 7 ++++++-
grub-core/normal/main.c | 3 ++-
include/grub/search.h | 9 +++++----
4 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index d538b36219..84362b54b3 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -182,6 +182,26 @@ iterate_device (const char *name, void *data)
grub_device_close (dev);
}
+ /* Limit to encrypted disks when requested. */
+ if (ctx->flags & SEARCH_FLAGS_CRYPTODISK_ONLY)
+ {
+ grub_device_t dev;
+
+ dev = grub_device_open (name);
+ if (dev == NULL)
+ {
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ if (dev->disk == NULL || dev->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
+ {
+ grub_device_close (dev);
+ grub_errno = GRUB_ERR_NONE;
+ return 0;
+ }
+ grub_device_close (dev);
+ }
+
/* Skip it if it's not the root device when requested. */
if (ctx->flags & SEARCH_FLAGS_ROOTDEV_ONLY)
{
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
index 4fe6440c65..ec2fb638f1 100644
--- a/grub-core/commands/search_wrap.c
+++ b/grub-core/commands/search_wrap.c
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
ARG_TYPE_STRING},
{"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0},
{"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0},
+ {"cryptodisk-only", 0, 0, N_("Only probe encrypted disks."), 0, 0},
{"root-dev-only", 'r', 0, N_("Only probe root device."), 0, 0},
{"hint", 'h', GRUB_ARG_OPTION_REPEATABLE,
N_("First try the device HINT. If HINT ends in comma, "
@@ -76,6 +77,7 @@ enum options
SEARCH_SET,
SEARCH_NO_FLOPPY,
SEARCH_EFIDISK_ONLY,
+ SEARCH_CRYPTODISK_ONLY,
SEARCH_ROOTDEV_ONLY,
SEARCH_HINT,
SEARCH_HINT_IEEE1275,
@@ -191,6 +193,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
if (state[SEARCH_EFIDISK_ONLY].set)
flags |= SEARCH_FLAGS_EFIDISK_ONLY;
+ if (state[SEARCH_CRYPTODISK_ONLY].set)
+ flags |= SEARCH_FLAGS_CRYPTODISK_ONLY;
+
if (state[SEARCH_ROOTDEV_ONLY].set)
flags |= SEARCH_FLAGS_ROOTDEV_ONLY;
@@ -215,7 +220,7 @@ GRUB_MOD_INIT(search)
cmd =
grub_register_extcmd ("search", grub_cmd_search,
GRUB_COMMAND_FLAG_EXTRACTOR | GRUB_COMMAND_ACCEPT_DASH,
- N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
+ N_("[-f|-l|-u|-s|-n] [--cryptodisk-only] [--hint HINT [--hint HINT] ...]"
" NAME"),
N_("Search devices by file, filesystem label"
" or filesystem UUID."
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index dd20e51290..6f7290a897 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -615,7 +615,8 @@ static const char *features[] = {
"feature_chainloader_bpb", "feature_ntldr", "feature_platform_search_hint",
"feature_default_font_path", "feature_all_video_module",
"feature_menuentry_id", "feature_menuentry_options", "feature_200_final",
- "feature_nativedisk_cmd", "feature_timeout_style"
+ "feature_nativedisk_cmd", "feature_timeout_style",
+ "feature_search_cryptodisk_only"
};
GRUB_MOD_INIT(normal)
diff --git a/include/grub/search.h b/include/grub/search.h
index 9343c66b13..b6b5c8be1f 100644
--- a/include/grub/search.h
+++ b/include/grub/search.h
@@ -21,10 +21,11 @@
enum search_flags
{
- SEARCH_FLAGS_NONE = 0,
- SEARCH_FLAGS_NO_FLOPPY = 1,
- SEARCH_FLAGS_EFIDISK_ONLY = 2,
- SEARCH_FLAGS_ROOTDEV_ONLY = 4
+ SEARCH_FLAGS_NONE = 0,
+ SEARCH_FLAGS_NO_FLOPPY = 1,
+ SEARCH_FLAGS_EFIDISK_ONLY = 2,
+ SEARCH_FLAGS_ROOTDEV_ONLY = 4,
+ SEARCH_FLAGS_CRYPTODISK_ONLY = 8
};
void grub_search_fs_file (const char *key, const char *var,

View file

@ -1,133 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Sun, 2 Mar 2025 18:08:22 +0300
Subject: [PATCH] disk/diskfilter: Introduce the "cryptocheck" command
This command examines a given diskfilter device, e.g., an LVM disk,
and checks if underlying disks, physical volumes, are cryptodisks,
e.g., LUKS disks, this layout is called "LVM-on-LUKS".
The return value is 0 when all underlying disks (of a given device)
are cryptodisks (1 if at least one disk is unencrypted or in an
unknown state).
Users are encouraged to include the relevant check before loading
anything from an LVM disk that is supposed to be encrypted.
This further supports the CLI authentication, blocking bypass
attempts when booting from an encrypted LVM disk.
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/diskfilter.c | 75 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
index fef0b815ab..216be6a782 100644
--- a/grub-core/disk/diskfilter.c
+++ b/grub-core/disk/diskfilter.c
@@ -20,6 +20,7 @@
#include <grub/dl.h>
#include <grub/disk.h>
#include <grub/mm.h>
+#include <grub/command.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/diskfilter.h>
@@ -1365,6 +1366,73 @@ grub_diskfilter_get_pv_from_disk (grub_disk_t disk,
}
#endif
+static int
+grub_diskfilter_check_pvs_encrypted (grub_disk_t disk, int *pvs_cnt)
+{
+ struct grub_diskfilter_lv *lv = disk->data;
+ struct grub_diskfilter_pv *pv;
+
+ *pvs_cnt = 0;
+
+ if (lv->vg->pvs)
+ for (pv = lv->vg->pvs; pv; pv = pv->next)
+ {
+ (*pvs_cnt)++;
+
+ if (pv->disk == NULL)
+ {
+ /* Can be a partially activated VG, bail out. */
+ return GRUB_ERR_TEST_FAILURE;
+ }
+
+ if (pv->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
+ {
+ /* All backing devices must be cryptodisks, stop. */
+ return GRUB_ERR_TEST_FAILURE;
+ }
+ }
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_cryptocheck (grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_disk_t disk;
+ int check_pvs_res;
+ int namelen;
+ int pvs_cnt;
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("disk name expected"));
+
+ namelen = grub_strlen (args[0]);
+ if (namelen > 2 && (args[0][0] == '(') && (args[0][namelen - 1] == ')'))
+ args[0][namelen - 1] = 0;
+ else
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("invalid disk: %s"),
+ args[0]);
+
+ if (!is_valid_diskfilter_name (&args[0][1]))
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("unrecognized disk: %s"),
+ &args[0][1]);
+
+ disk = grub_disk_open (&args[0][1]);
+ if (disk == NULL)
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("no such disk: %s"),
+ &args[0][1]);
+
+ check_pvs_res = grub_diskfilter_check_pvs_encrypted (disk, &pvs_cnt);
+ grub_disk_close (disk);
+
+ grub_printf("%s is %sencrypted (%d pv%s examined)\n", &args[0][1],
+ (check_pvs_res == GRUB_ERR_NONE) ? "" : "un",
+ pvs_cnt,
+ (pvs_cnt > 1) ? "s" : "");
+
+ return check_pvs_res;
+}
+
static struct grub_disk_dev grub_diskfilter_dev =
{
.name = "diskfilter",
@@ -1381,14 +1449,21 @@ static struct grub_disk_dev grub_diskfilter_dev =
.next = 0
};
+static grub_command_t cmd;
+
GRUB_MOD_INIT(diskfilter)
{
grub_disk_dev_register (&grub_diskfilter_dev);
+ cmd = grub_register_command ("cryptocheck", grub_cmd_cryptocheck,
+ N_("DEVICE"),
+ N_("Check if a logical volume resides on encrypted disks."));
}
GRUB_MOD_FINI(diskfilter)
{
grub_disk_dev_unregister (&grub_diskfilter_dev);
+ if (cmd != NULL)
+ grub_unregister_command (cmd);
free_array ();
}

View file

@ -1,67 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Sun, 2 Mar 2025 23:32:43 +0300
Subject: [PATCH] commands/search: Add the diskfilter support
When the --cryptodisk-only argument is given, also check the target
device using the "cryptocheck" command, if available.
This extends the checks to common layouts like LVM-on-LUKS, so the
--cryptodisk-only argument transparently handles such setups.
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/search.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 84362b54b3..1cf714ad7d 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -150,6 +150,36 @@ check_for_duplicate (const char *name, void *data)
return ret;
}
+static bool
+is_unencrypted_disk (grub_disk_t disk)
+{
+ grub_command_t cmd;
+ char *disk_str;
+ int disk_str_len;
+ int res;
+
+ if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
+ return false; /* This is (crypto) disk. */
+
+ if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
+ {
+ cmd = grub_command_find ("cryptocheck");
+ if (cmd == NULL) /* No diskfilter module loaded for some reason. */
+ return true;
+
+ disk_str_len = grub_strlen (disk->name) + 2 + 1;
+ disk_str = grub_malloc (disk_str_len);
+ if (disk_str == NULL) /* Something is wrong, better report as unencrypted. */
+ return true;
+
+ grub_snprintf (disk_str, disk_str_len, "(%s)", disk->name);
+ res = cmd->func (cmd, 1, &disk_str);
+ grub_free (disk_str);
+ return (res != GRUB_ERR_NONE) ? true : false; /* GRUB_ERR_NONE for encrypted. */
+ }
+ return true;
+}
+
/* Helper for FUNC_NAME. */
static int
iterate_device (const char *name, void *data)
@@ -193,7 +223,7 @@ iterate_device (const char *name, void *data)
grub_errno = GRUB_ERR_NONE;
return 0;
}
- if (dev->disk == NULL || dev->disk->dev->id != GRUB_DISK_DEVICE_CRYPTODISK_ID)
+ if (dev->disk == NULL || is_unencrypted_disk (dev->disk) == true)
{
grub_device_close (dev);
grub_errno = GRUB_ERR_NONE;

View file

@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 10 Mar 2025 15:33:46 +0300
Subject: [PATCH] docs: Document available crypto disks checks
Document the --cryptodisk-only argument. Also, document the
"cryptocheck" command invoked when that argument is processed.
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
docs/grub.texi | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 2d6d73a78d..93e23be99d 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -4365,6 +4365,7 @@ you forget a command, you can run the command @command{help}
* configfile:: Load a configuration file
* cpuid:: Check for CPU features
* crc:: Compute or check CRC32 checksums
+* cryptocheck:: Check if a device is encrypted
* cryptomount:: Mount a crypto device
* cutmem:: Remove memory regions
* date:: Display or set current date and time
@@ -4674,6 +4675,16 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum}
(@pxref{hashsum}) for full description.
@end deffn
+@node cryptocheck
+@subsection cryptocheck
+
+@deffn Command cryptocheck device
+Check if a given diskfilter device is backed by encrypted devices
+(@pxref{cryptomount} for additional information).
+
+The command examines all backing devices, physical volumes, of a specified
+logical volume, like LVM2, and fails when at least one of them is unencrypted.
+@end deffn
@node cryptomount
@subsection cryptomount
@@ -5522,7 +5533,8 @@ unbootable. @xref{Using GPG-style digital signatures}, for more information.
@deffn Command search @
[@option{--file}|@option{--label}|@option{--fs-uuid}] @
- [@option{--set} [var]] [@option{--no-floppy}|@option{--efidisk-only}] name
+ [@option{--set} [var]] [@option{--no-floppy}|@option{--efidisk-only}|@option{--cryptodisk-only}] @
+ name
Search devices by file (@option{-f}, @option{--file}), filesystem label
(@option{-l}, @option{--label}), or filesystem UUID (@option{-u},
@option{--fs-uuid}).
@@ -5537,6 +5549,14 @@ devices, which can be slow.
The (@option{--efidisk-only}) option prevents searching any other devices then
EFI disks. This is typically used when chainloading to local EFI partition.
+The (@option{--cryptodisk-only}) option prevents searching any devices other
+than encrypted disks. This is typically used when booting from an encrypted
+file system to ensure that no code gets executed from an unencrypted device
+having the same filesystem UUID or label.
+
+This option implicitly invokes the command @command{cryptocheck}, if it is
+available (@pxref{cryptocheck} for additional information).
+
The @samp{search.file}, @samp{search.fs_label}, and @samp{search.fs_uuid}
commands are aliases for @samp{search --file}, @samp{search --label}, and
@samp{search --fs-uuid} respectively.

View file

@ -1,147 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Tue, 6 May 2025 12:25:20 -0600
Subject: [PATCH] disk/cryptodisk: Add the "erase secrets" function
This commit adds the grub_cryptodisk_erasesecrets() function to wipe
master keys from all cryptodisks. This function is EFI-only.
Since there is no easy way to "force unmount" a given encrypted disk,
this function renders all mounted cryptodisks unusable. An attempt to
read them will return garbage.
This is why this function must be used in "no way back" conditions.
Currently, it is used when unloading the cryptodisk module and when
performing the "exit" command (it is often used to switch to the next
EFI application). This function is not called when performing the
"chainloader" command, because the callee may return to GRUB. For this
reason, users are encouraged to use "exit" instead of "chainloader" to
execute third-party boot applications.
This function does not guarantee that all secrets are wiped from RAM.
Console output, chunks from disk read requests and other may remain.
This function does not clear the IV prefix and rekey key for geli disks.
Also, this commit adds the relevant documentation improvements.
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
docs/grub.texi | 6 ++++++
grub-core/commands/minicmd.c | 11 +++++++++++
grub-core/disk/cryptodisk.c | 28 ++++++++++++++++++++++++++++
include/grub/cryptodisk.h | 1 +
4 files changed, 46 insertions(+)
diff --git a/docs/grub.texi b/docs/grub.texi
index 93e23be99d..0af47b5ade 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -4721,6 +4721,11 @@ namespace in addition to the cryptodisk namespace.
Support for plain encryption mode (plain dm-crypt) is provided via separate
@command{@pxref{plainmount}} command.
+
+On the EFI platform, GRUB tries to erase master keys from memory when the cryptodisk
+module is unloaded or the command @command{exit} is executed. All secrets remain in
+memory when the command @command{chainloader} is issued, because execution can
+return to GRUB on the EFI platform.
@end deffn
@node cutmem
@@ -6982,6 +6987,7 @@ USB support provides benefits similar to ATA (for USB disks) or AT (for USB
keyboards). In addition it allows USBserial.
Chainloading refers to the ability to load another bootloader through the same protocol
+and on some platforms, like EFI, allow that bootloader to return to the GRUB.
Hints allow faster disk discovery by already knowing in advance which is the disk in
question. On some platforms hints are correct unless you move the disk between boots.
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
index 9efb7718c3..eb786766a8 100644
--- a/grub-core/commands/minicmd.c
+++ b/grub-core/commands/minicmd.c
@@ -29,6 +29,10 @@
#include <grub/command.h>
#include <grub/i18n.h>
+#ifdef GRUB_MACHINE_EFI
+#include <grub/cryptodisk.h>
+#endif
+
GRUB_MOD_LICENSE ("GPLv3+");
/* cat FILE */
@@ -199,6 +203,13 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
retval = n;
}
+#ifdef GRUB_MACHINE_EFI
+ /*
+ * The "exit" command is often used to launch the next boot application.
+ * So, erase the secrets.
+ */
+ grub_cryptodisk_erasesecrets ();
+#endif
grub_exit (retval);
/* Not reached. */
}
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index 8727760100..9597d2d3bd 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -1677,6 +1677,31 @@ grub_cryptodisk_challenge_password (void)
return GRUB_ERR_NONE;
}
+
+void
+grub_cryptodisk_erasesecrets (void)
+{
+ grub_cryptodisk_t i;
+ grub_uint8_t *buf;
+
+ buf = grub_zalloc (GRUB_CRYPTODISK_MAX_KEYLEN);
+ if (buf == NULL)
+ grub_fatal ("grub_cryptodisk_erasesecrets: cannot allocate memory");
+
+ for (i = cryptodisk_list; i != NULL; i = i->next)
+ if (grub_cryptodisk_setkey (i, buf, i->keysize))
+ grub_fatal ("grub_cryptodisk_erasesecrets: cannot erase secrets for %s", i->source);
+ else
+ grub_printf ("Erased crypto secrets for %s\n", i->source);
+ /*
+ * Unfortunately, there is no way to "force unmount" a given disk, it may
+ * have mounted "child" disks as well, e.g., an LVM volume. So, this
+ * function MUST be called when there is no way back, e.g., when exiting.
+ * Otherwise, subsequent read calls for a cryptodisk will return garbage.
+ */
+
+ grub_free (buf);
+}
#endif /* GRUB_MACHINE_EFI */
struct grub_procfs_entry luks_script =
@@ -1700,6 +1725,9 @@ GRUB_MOD_INIT (cryptodisk)
GRUB_MOD_FINI (cryptodisk)
{
+#ifdef GRUB_MACHINE_EFI
+ grub_cryptodisk_erasesecrets ();
+#endif
grub_disk_dev_unregister (&grub_cryptodisk_dev);
cryptodisk_cleanup ();
grub_unregister_extcmd (cmd);
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
index d2572f8b05..ef307dfd5d 100644
--- a/include/grub/cryptodisk.h
+++ b/include/grub/cryptodisk.h
@@ -189,5 +189,6 @@ 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);
+void grub_cryptodisk_erasesecrets (void);
#endif
#endif

View file

@ -1,29 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Tue, 4 Mar 2025 15:27:59 +0300
Subject: [PATCH] disk/cryptodisk: Wipe the passphrase from memory
Switching to another EFI boot application while there are secrets in
RAM is dangerous, because not all firmware is wiping memory on free.
To reduce the attack surface, wipe the passphrase acquired when
unlocking an encrypted volume.
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/cryptodisk.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index 9597d2d3bd..26457095d3 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -1164,6 +1164,7 @@ grub_cryptodisk_scan_device_real (const char *name,
if (askpass)
{
+ grub_memset (cargs->key_data, 0, cargs->key_len);
cargs->key_len = 0;
grub_free (cargs->key_data);
}

View file

@ -1,114 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Fri, 14 Mar 2025 19:03:39 +0800
Subject: [PATCH] cryptocheck: Add --quiet option
The option can be used to suppress output if we only want to test the
return value of the command.
Also, mention this option in the documentation.
Signed-off-by: Michael Chang <mchang@suse.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
docs/grub.texi | 4 +++-
grub-core/commands/search.c | 7 ++++++-
grub-core/disk/diskfilter.c | 25 +++++++++++++++++++------
3 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 0af47b5ade..ae01e8c994 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -4678,12 +4678,14 @@ Alias for @code{hashsum --hash crc32 arg @dots{}}. See command @command{hashsum}
@node cryptocheck
@subsection cryptocheck
-@deffn Command cryptocheck device
+@deffn Command cryptocheck [ @option{--quiet} ] device
Check if a given diskfilter device is backed by encrypted devices
(@pxref{cryptomount} for additional information).
The command examines all backing devices, physical volumes, of a specified
logical volume, like LVM2, and fails when at least one of them is unencrypted.
+
+The option @option{--quiet} can be given to suppress the output.
@end deffn
@node cryptomount
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 1cf714ad7d..c432c0ac6f 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -163,6 +163,9 @@ is_unencrypted_disk (grub_disk_t disk)
if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
{
+ char opt[] = "--quiet";
+ char *args[2];
+
cmd = grub_command_find ("cryptocheck");
if (cmd == NULL) /* No diskfilter module loaded for some reason. */
return true;
@@ -173,7 +176,9 @@ is_unencrypted_disk (grub_disk_t disk)
return true;
grub_snprintf (disk_str, disk_str_len, "(%s)", disk->name);
- res = cmd->func (cmd, 1, &disk_str);
+ args[0] = opt;
+ args[1] = disk_str;
+ res = cmd->func (cmd, 2, args);
grub_free (disk_str);
return (res != GRUB_ERR_NONE) ? true : false; /* GRUB_ERR_NONE for encrypted. */
}
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
index 216be6a782..04b64aebc6 100644
--- a/grub-core/disk/diskfilter.c
+++ b/grub-core/disk/diskfilter.c
@@ -1402,6 +1402,19 @@ grub_cmd_cryptocheck (grub_command_t cmd __attribute__ ((unused)),
int check_pvs_res;
int namelen;
int pvs_cnt;
+ int opt_quiet = 0;
+
+ if (argc == 2)
+ {
+ if (grub_strcmp (args[0], "--quiet") == 0)
+ {
+ opt_quiet = 1;
+ argc--;
+ args++;
+ }
+ else
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unrecognized option: %s"), args[0]);
+ }
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("disk name expected"));
@@ -1424,11 +1437,11 @@ grub_cmd_cryptocheck (grub_command_t cmd __attribute__ ((unused)),
check_pvs_res = grub_diskfilter_check_pvs_encrypted (disk, &pvs_cnt);
grub_disk_close (disk);
-
- grub_printf("%s is %sencrypted (%d pv%s examined)\n", &args[0][1],
- (check_pvs_res == GRUB_ERR_NONE) ? "" : "un",
- pvs_cnt,
- (pvs_cnt > 1) ? "s" : "");
+ if (!opt_quiet)
+ grub_printf ("%s is %sencrypted (%d pv%s examined)\n", &args[0][1],
+ (check_pvs_res == GRUB_ERR_NONE) ? "" : "un",
+ pvs_cnt,
+ (pvs_cnt > 1) ? "s" : "");
return check_pvs_res;
}
@@ -1456,7 +1469,7 @@ GRUB_MOD_INIT(diskfilter)
{
grub_disk_dev_register (&grub_diskfilter_dev);
cmd = grub_register_command ("cryptocheck", grub_cmd_cryptocheck,
- N_("DEVICE"),
+ N_("[--quiet] DEVICE"),
N_("Check if a logical volume resides on encrypted disks."));
}

View file

@ -1,291 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
Date: Tue, 29 Jul 2025 09:43:37 -0600
Subject: [PATCH] Set correctly the memory attributes for the kernel PE
sections
Currently the whole kernel memory region is set to RO, so at some
point when execution is passed to the kernel, the latter faults on a
memory write access, e.g. zeroing .bss section. The proposed change
sets the memory attribute appropriately for each kernel PE section.
Signed-off-by: Leo Sandoval <lsandova@redhat.com>
---
grub-core/loader/efi/linux.c | 170 +++++++++++++++++++++++++++-----------
grub-core/loader/i386/efi/linux.c | 5 +-
include/grub/efi/linux.h | 6 ++
3 files changed, 134 insertions(+), 47 deletions(-)
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index ef55556f2d..111edf0e1d 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -36,6 +36,7 @@
#include <grub/efi/sb.h>
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
+#include <grub/safemath.h>
#include <grub/verify.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -202,22 +203,133 @@ grub_efi_check_nx_required (int *nx_required)
typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
grub_err_t
-grub_efi_linux_boot (grub_addr_t k_address, grub_size_t k_size,
+grub_efi_mem_set_att(grub_addr_t k_address, grub_size_t k_size,
+ grub_size_t k_start, int nx_supported)
+{
+ grub_addr_t k_start_address = k_address + k_start;
+
+ grub_uint64_t default_set_attrs = GRUB_MEM_ATTR_R | GRUB_MEM_ATTR_W | GRUB_MEM_ATTR_X;
+ grub_uint64_t default_clear_attrs = 0;
+ grub_uint64_t stack_set_attrs = default_set_attrs;
+ grub_uint64_t stack_clear_attrs = default_clear_attrs;
+ grub_uint64_t kernel_set_attrs = default_set_attrs;
+ grub_uint64_t kernel_clear_attrs = default_clear_attrs;
+ grub_uint64_t attrs;
+
+ struct grub_msdos_image_header *header;
+ struct grub_pe_image_header *pe_image_header;
+ struct grub_pe32_coff_header *coff_header;
+ struct grub_pe32_section_table *section, *sections;
+ grub_uint16_t i;
+ grub_size_t sz;
+
+ header = (struct grub_msdos_image_header *)k_address;
+
+ if (grub_add ((grub_addr_t) header, header->pe_image_header_offset, &sz))
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Error on PE image header address calculation"));
+
+ pe_image_header = (struct grub_pe_image_header *) (sz);
+
+ if (pe_image_header > (k_address + k_size))
+ return grub_error (GRUB_ERR_BAD_OS, N_("PE image header address is invalid"));
+
+ if (grub_memcmp (pe_image_header->signature, GRUB_PE32_SIGNATURE,
+ GRUB_PE32_SIGNATURE_SIZE) != 0)
+ return grub_error (GRUB_ERR_BAD_OS, N_("kernel PE magic is invalid"));
+
+ coff_header = &(pe_image_header->coff_header);
+ grub_dprintf ("nx", "coff_header 0x%"PRIxGRUB_ADDR" machine %08x\n", (grub_addr_t)coff_header, coff_header->machine);
+
+ if (grub_add ((grub_addr_t) coff_header, sizeof (*coff_header), &sz) ||
+ grub_add (sz, coff_header->optional_header_size, &sz))
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Error on PE sections calculation"));
+
+ sections = (struct grub_pe32_section_table *) (sz);
+
+ if (sections > (k_address + k_size))
+ return grub_error (GRUB_ERR_BAD_OS, N_("Section address is invalid"));
+
+ /* Parse the PE, remove W for code section, remove X for data sections, RO for the rest */
+ for (i = 0, section = sections; i < coff_header->num_sections; i++, section++)
+ {
+ kernel_set_attrs = default_set_attrs;
+ kernel_clear_attrs = default_clear_attrs;
+
+ if (nx_supported)
+ {
+ if (section->characteristics & GRUB_PE32_SCN_MEM_EXECUTE)
+ {
+ /* RX section */
+ kernel_set_attrs &= ~GRUB_MEM_ATTR_W;
+ kernel_clear_attrs |= GRUB_MEM_ATTR_W;
+ }
+ else if (section->characteristics & GRUB_PE32_SCN_MEM_WRITE)
+ {
+ /* RW section */
+ kernel_set_attrs &= ~GRUB_MEM_ATTR_X;
+ kernel_clear_attrs |= GRUB_MEM_ATTR_X;
+ }
+ else
+ {
+ /* RO section */
+ kernel_set_attrs &= ~GRUB_MEM_ATTR_W & ~GRUB_MEM_ATTR_X;
+ kernel_clear_attrs |= GRUB_MEM_ATTR_X | GRUB_MEM_ATTR_W ;
+ }
+ }
+
+ /* Make sure we are inside range */
+ if (grub_add ((grub_addr_t) k_address, section->raw_data_offset, &sz))
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("Error on PE Executable section calculation"));
+
+ grub_update_mem_attrs (sz, section->raw_data_size, kernel_set_attrs, kernel_clear_attrs);
+
+ grub_get_mem_attrs (sz, 4096, &attrs);
+ grub_dprintf ("nx", "permissions for section %s 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
+ section->name,
+ (grub_addr_t)sz,
+ (attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
+ (attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
+ (attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
+ }
+
+ if (grub_stack_addr != (grub_addr_t)-1ll)
+ {
+ if (nx_supported)
+ {
+ stack_set_attrs &= ~GRUB_MEM_ATTR_X;
+ stack_clear_attrs |= GRUB_MEM_ATTR_X;
+ }
+
+ grub_dprintf ("nx", "Setting attributes for stack at 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" to rw%c\n",
+ grub_stack_addr, grub_stack_addr + grub_stack_size - 1,
+ (stack_set_attrs & GRUB_MEM_ATTR_X) ? 'x' : '-');
+
+ grub_update_mem_attrs (grub_stack_addr, grub_stack_size,
+ stack_set_attrs, stack_clear_attrs);
+
+ grub_get_mem_attrs (grub_stack_addr, 4096, &attrs);
+ grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
+ grub_stack_addr,
+ (attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
+ (attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
+ (attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+
+grub_err_t
+grub_efi_linux_boot (grub_addr_t k_address, grub_size_t k_size, grub_size_t k_start,
grub_off_t h_offset, void *k_params,
int nx_supported)
{
+ grub_addr_t k_start_address = k_address + k_start;
grub_efi_loaded_image_t *loaded_image = NULL;
handover_func hf;
int offset = 0;
- grub_uint64_t stack_set_attrs = GRUB_MEM_ATTR_R |
- GRUB_MEM_ATTR_W |
- GRUB_MEM_ATTR_X;
- grub_uint64_t stack_clear_attrs = 0;
- grub_uint64_t kernel_set_attrs = stack_set_attrs;
- grub_uint64_t kernel_clear_attrs = stack_clear_attrs;
- grub_uint64_t attrs;
int nx_required = 0;
-
+
#ifdef __x86_64__
offset = 512;
#endif
@@ -241,47 +353,13 @@ grub_efi_linux_boot (grub_addr_t k_address, grub_size_t k_size,
if (nx_required && !nx_supported)
return grub_error (GRUB_ERR_BAD_OS, N_("kernel does not support NX loading required by policy"));
- if (nx_supported)
- {
- kernel_set_attrs &= ~GRUB_MEM_ATTR_W;
- kernel_clear_attrs |= GRUB_MEM_ATTR_W;
- stack_set_attrs &= ~GRUB_MEM_ATTR_X;
- stack_clear_attrs |= GRUB_MEM_ATTR_X;
- }
-
- grub_dprintf ("nx", "Setting attributes for 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" to r%cx\n",
- k_address, k_address + k_size - 1,
- (kernel_set_attrs & GRUB_MEM_ATTR_W) ? 'w' : '-');
- grub_update_mem_attrs (k_address, k_size,
- kernel_set_attrs, kernel_clear_attrs);
-
- grub_get_mem_attrs (k_address, 4096, &attrs);
- grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
- (grub_addr_t)k_address,
- (attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
- (attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
- (attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
- if (grub_stack_addr != (grub_addr_t)-1ll)
- {
- grub_dprintf ("nx", "Setting attributes for stack at 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" to rw%c\n",
- grub_stack_addr, grub_stack_addr + grub_stack_size - 1,
- (stack_set_attrs & GRUB_MEM_ATTR_X) ? 'x' : '-');
- grub_update_mem_attrs (grub_stack_addr, grub_stack_size,
- stack_set_attrs, stack_clear_attrs);
-
- grub_get_mem_attrs (grub_stack_addr, 4096, &attrs);
- grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
- grub_stack_addr,
- (attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
- (attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
- (attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
- }
+ grub_efi_mem_set_att (k_address, k_size, k_start, nx_supported);
#if defined(__i386__) || defined(__x86_64__)
asm volatile ("cli");
#endif
- hf = (handover_func)((char *)k_address + h_offset + offset);
+ hf = (handover_func)((char *)k_start_address + h_offset + offset);
hf (grub_efi_image_handle, grub_efi_system_table, k_params);
return GRUB_ERR_BUG;
@@ -451,7 +529,7 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args,
grub_dprintf ("linux", "linux command line: '%s'\n", args);
- retval = grub_efi_linux_boot (addr, size, handover_offset,
+ retval = grub_efi_linux_boot (addr, size, 0, handover_offset,
(void *)addr, nx_supported);
/* Never reached... */
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
index abbf6b24f5..6c310d9879 100644
--- a/grub-core/loader/i386/efi/linux.c
+++ b/grub-core/loader/i386/efi/linux.c
@@ -41,6 +41,7 @@ static grub_command_t cmd_linuxefi, cmd_initrdefi;
struct grub_linuxefi_context {
void *kernel_mem;
grub_uint64_t kernel_size;
+ grub_uint64_t kernel_start;
grub_uint32_t handover_offset;
struct linux_kernel_params *params;
char *cmdline;
@@ -169,6 +170,7 @@ grub_linuxefi_boot (void *data)
return grub_efi_linux_boot ((grub_addr_t)context->kernel_mem,
context->kernel_size,
+ context->kernel_start,
context->handover_offset,
context->params,
context->nx_supported);
@@ -527,7 +529,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
LOW_U32(kernel_mem));
lh->code32_start = LOW_U32(kernel_mem);
- grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start);
+ grub_memcpy (kernel_mem, (char *)kernel, filelen);
lh->type_of_loader = 0x6;
grub_dprintf ("linux", "setting lh->type_of_loader = 0x%02x\n",
@@ -544,6 +546,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
context->kernel_mem = kernel_mem;
context->kernel_size = kernel_size;
+ context->kernel_start = start;
context->handover_offset = handover_offset;
context->params = params;
context->cmdline = cmdline;
diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h
index 5b4e626c37..cd17be506a 100644
--- a/include/grub/efi/linux.h
+++ b/include/grub/efi/linux.h
@@ -27,6 +27,7 @@
grub_err_t
EXPORT_FUNC(grub_efi_linux_boot) (grub_addr_t kernel_address,
grub_size_t kernel_size,
+ grub_size_t kernel_start,
grub_off_t handover_offset,
void *kernel_param, int nx_enabled);
@@ -38,4 +39,9 @@ EXPORT_FUNC(grub_efi_check_nx_image_support) (grub_addr_t kernel_addr,
grub_err_t
EXPORT_FUNC(grub_efi_check_nx_required) (int *nx_required);
+grub_err_t
+EXPORT_FUNC(grub_efi_mem_set_att) (grub_addr_t k_address,
+ grub_size_t k_size,
+ grub_size_t k_start, int nx_supported);
+
#endif /* ! GRUB_EFI_LINUX_HEADER */

View file

@ -1,102 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
Date: Fri, 11 Apr 2025 15:31:53 -0600
Subject: [PATCH] Include function name on debug and error print functions
Together with the line number, the debug log gives more context when
debugging.
Signed-off-by: Leo Sandoval <lsandova@redhat.com>
---
grub-core/kern/err.c | 4 ++--
grub-core/kern/misc.c | 4 ++--
include/grub/err.h | 6 +++---
include/grub/misc.h | 5 +++--
4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
index aebfe0cf83..ba04b57fb7 100644
--- a/grub-core/kern/err.c
+++ b/grub-core/kern/err.c
@@ -38,14 +38,14 @@ static int grub_error_stack_assert;
#endif
grub_err_t
-grub_error (grub_err_t n, const char *file, const int line, const char *fmt, ...)
+grub_error (grub_err_t n, const char *file, const char *function, const int line, const char *fmt, ...)
{
va_list ap;
int m;
grub_errno = n;
- m = grub_snprintf (grub_errmsg, sizeof (grub_errmsg), "%s:%d:", file, line);
+ m = grub_snprintf (grub_errmsg, sizeof (grub_errmsg), "%s:%s:%d:", file, function, line);
if (m < 0)
m = 0;
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index 69bd655f3d..541c7bb80c 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -248,7 +248,7 @@ grub_debug_enabled (const char * condition)
}
void
-grub_real_dprintf (const char *file, const int line, const char *condition,
+grub_real_dprintf (const char *file, const char *function, const int line, const char *condition,
const char *fmt, ...)
{
va_list args;
@@ -272,7 +272,7 @@ grub_real_dprintf (const char *file, const int line, const char *condition,
else
last_had_cr = 0;
#endif
- grub_printf ("%s:%d:%s: ", file, line, condition);
+ grub_printf ("%s:%s:%d:%s: ", file, function, line, condition);
va_start (args, fmt);
grub_vprintf (fmt, args);
va_end (args);
diff --git a/include/grub/err.h b/include/grub/err.h
index 7530f58b29..6379a6baf8 100644
--- a/include/grub/err.h
+++ b/include/grub/err.h
@@ -88,10 +88,10 @@ struct grub_error_saved
extern grub_err_t EXPORT_VAR(grub_errno);
extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG];
-grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int line, const char *fmt, ...)
- __attribute__ ((format (GNU_PRINTF, 4, 5)));
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const char *function, const int line, const char *fmt, ...)
+ __attribute__ ((format (GNU_PRINTF, 5, 6)));
-#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
+#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
diff --git a/include/grub/misc.h b/include/grub/misc.h
index 0429339ef3..2b9096a0b3 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -43,7 +43,7 @@
#define CONCAT(a, b) CONCAT_(a, b)
#endif
-#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__)
+#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __FUNCTION__, __LINE__, condition, __VA_ARGS__)
void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
@@ -420,9 +420,10 @@ int EXPORT_FUNC(grub_puts_) (const char *s);
int EXPORT_FUNC(grub_debug_is_enabled) (void);
int EXPORT_FUNC(grub_debug_enabled) (const char *condition);
void EXPORT_FUNC(grub_real_dprintf) (const char *file,
+ const char *function,
const int line,
const char *condition,
- const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5)));
+ const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 5, 6)));
int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2)));
int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2)));
void EXPORT_FUNC(grub_qdprintf) (const char *condition,

Some files were not shown because too many files have changed in this diff Show more