Compare commits
No commits in common. "c8" and "imports/c8-beta/grub2-2.02-138.el8" have entirely different histories.
c8
...
imports/c8
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,9 +1,3 @@
|
|||||||
SOURCES/grub-2.02.tar.xz
|
SOURCES/grub-2.02.tar.xz
|
||||||
SOURCES/redhatsecureboot301.cer
|
|
||||||
SOURCES/redhatsecureboot502.cer
|
|
||||||
SOURCES/redhatsecureboot601.cer
|
|
||||||
SOURCES/redhatsecureboot701.cer
|
|
||||||
SOURCES/redhatsecurebootca3.cer
|
|
||||||
SOURCES/redhatsecurebootca5.cer
|
|
||||||
SOURCES/theme.tar.bz2
|
SOURCES/theme.tar.bz2
|
||||||
SOURCES/unifont-5.1.20080820.pcf.gz
|
SOURCES/unifont-5.1.20080820.pcf.gz
|
||||||
|
@ -1,9 +1,3 @@
|
|||||||
3d7eb6eaab28b88cb969ba9ab24af959f4d1b178 SOURCES/grub-2.02.tar.xz
|
3d7eb6eaab28b88cb969ba9ab24af959f4d1b178 SOURCES/grub-2.02.tar.xz
|
||||||
4a07b56e28741884b86da6ac91f8f9929541a1e4 SOURCES/redhatsecureboot301.cer
|
|
||||||
3f94c47f1d08bacc7cb29bdd912e286b8d2f6fcf SOURCES/redhatsecureboot502.cer
|
|
||||||
039357ef97aab3e484d1119edd4528156f5859e6 SOURCES/redhatsecureboot601.cer
|
|
||||||
e89890ca0ded2f9058651cc5fa838b78db2e6cc2 SOURCES/redhatsecureboot701.cer
|
|
||||||
cf9230e69000076727e5b784ec871d22716dc5da SOURCES/redhatsecurebootca3.cer
|
|
||||||
e6f506462069aa17d2e8610503635c20f3a995c3 SOURCES/redhatsecurebootca5.cer
|
|
||||||
cf0b7763c528902da7e8b05cfa248f20c8825ce5 SOURCES/theme.tar.bz2
|
cf0b7763c528902da7e8b05cfa248f20c8825ce5 SOURCES/theme.tar.bz2
|
||||||
87f8600ba24e521b5d20bdf6c4b71af8ae861e3a SOURCES/unifont-5.1.20080820.pcf.gz
|
87f8600ba24e521b5d20bdf6c4b71af8ae861e3a SOURCES/unifont-5.1.20080820.pcf.gz
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Peter Jones <pjones@redhat.com>
|
|
||||||
Date: Fri, 29 Jul 2022 15:56:00 -0400
|
|
||||||
Subject: [PATCH] Make debug=file show which file filters get run.
|
|
||||||
|
|
||||||
If one of the file filters breaks things, it's hard to figure out where
|
|
||||||
it has happened.
|
|
||||||
|
|
||||||
This makes grub log which filter is being run, which makes it easier to
|
|
||||||
figure out where you are in the sequence of events.
|
|
||||||
|
|
||||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
||||||
(cherry picked from commit d3d6518a13b5440a3be6c66b0ae47447182f2891)
|
|
||||||
(cherry picked from commit d197e70761b1383827e9008e21ee41c6c7015776)
|
|
||||||
---
|
|
||||||
grub-core/kern/file.c | 11 +++++++++++
|
|
||||||
1 file changed, 11 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
|
|
||||||
index f062fc21e7..5e1f29d0dd 100644
|
|
||||||
--- a/grub-core/kern/file.c
|
|
||||||
+++ b/grub-core/kern/file.c
|
|
||||||
@@ -30,6 +30,14 @@ void (*EXPORT_VAR (grub_grubnet_fini)) (void);
|
|
||||||
|
|
||||||
grub_file_filter_t grub_file_filters[GRUB_FILE_FILTER_MAX];
|
|
||||||
|
|
||||||
+static char *filter_names[] = {
|
|
||||||
+ [GRUB_FILE_FILTER_VERIFY] = "GRUB_FILE_FILTER_VERIFY",
|
|
||||||
+ [GRUB_FILE_FILTER_GZIO] = "GRUB_FILE_FILTER_GZIO",
|
|
||||||
+ [GRUB_FILE_FILTER_XZIO] = "GRUB_FILE_FILTER_XZIO",
|
|
||||||
+ [GRUB_FILE_FILTER_LZOPIO] = "GRUB_FILE_FILTER_LZOPIO",
|
|
||||||
+ [GRUB_FILE_FILTER_MAX] = "GRUB_FILE_FILTER_MAX"
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
/* Get the device part of the filename NAME. It is enclosed by parentheses. */
|
|
||||||
char *
|
|
||||||
grub_file_get_device_name (const char *name)
|
|
||||||
@@ -121,6 +129,9 @@ grub_file_open (const char *name, enum grub_file_type type)
|
|
||||||
if (grub_file_filters[filter])
|
|
||||||
{
|
|
||||||
last_file = file;
|
|
||||||
+ if (filter < GRUB_FILE_FILTER_MAX)
|
|
||||||
+ grub_dprintf ("file", "Running %s file filter\n",
|
|
||||||
+ filter_names[filter]);
|
|
||||||
file = grub_file_filters[filter] (file, type);
|
|
||||||
if (file && file != last_file)
|
|
||||||
{
|
|
@ -1,83 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Peter Jones <pjones@redhat.com>
|
|
||||||
Date: Mon, 1 Aug 2022 14:06:30 -0400
|
|
||||||
Subject: [PATCH] efi: use enumerated array positions for our allocation
|
|
||||||
choices
|
|
||||||
|
|
||||||
In our kernel allocator on EFI systems, we currently have a growing
|
|
||||||
amount of code that references the various allocation policies by
|
|
||||||
position in the array, and of course maintenance of this code scales
|
|
||||||
very poorly.
|
|
||||||
|
|
||||||
This patch changes them to be enumerated, so they're easier to refer to
|
|
||||||
farther along in the code without confusion.
|
|
||||||
|
|
||||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
||||||
(cherry picked from commit 6768026270cca015d7fef0ecc8a4119e9b3d3923)
|
|
||||||
(cherry picked from commit 50b2ca3274b6950393a4ffc7edde04a1a3de594e)
|
|
||||||
---
|
|
||||||
grub-core/loader/i386/efi/linux.c | 31 ++++++++++++++++++++-----------
|
|
||||||
1 file changed, 20 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
|
||||||
index d80d6ec312..23b27f6507 100644
|
|
||||||
--- a/grub-core/loader/i386/efi/linux.c
|
|
||||||
+++ b/grub-core/loader/i386/efi/linux.c
|
|
||||||
@@ -60,17 +60,26 @@ struct allocation_choice {
|
|
||||||
grub_efi_allocate_type_t alloc_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct allocation_choice max_addresses[4] =
|
|
||||||
+enum {
|
|
||||||
+ KERNEL_PREF_ADDRESS,
|
|
||||||
+ KERNEL_4G_LIMIT,
|
|
||||||
+ KERNEL_NO_LIMIT,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct allocation_choice max_addresses[] =
|
|
||||||
{
|
|
||||||
/* the kernel overrides this one with pref_address and
|
|
||||||
* GRUB_EFI_ALLOCATE_ADDRESS */
|
|
||||||
- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
+ [KERNEL_PREF_ADDRESS] =
|
|
||||||
+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
+ /* If the flag in params is set, this one gets changed to be above 4GB. */
|
|
||||||
+ [KERNEL_4G_LIMIT] =
|
|
||||||
+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
/* this one is always below 4GB, which we still *prefer* even if the flag
|
|
||||||
* is set. */
|
|
||||||
- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
- /* If the flag in params is set, this one gets changed to be above 4GB. */
|
|
||||||
- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
- { 0, 0 }
|
|
||||||
+ [KERNEL_NO_LIMIT] =
|
|
||||||
+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
+ { NO_MEM, 0, 0 }
|
|
||||||
};
|
|
||||||
static struct allocation_choice saved_addresses[4];
|
|
||||||
|
|
||||||
@@ -423,7 +432,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
if (lh->xloadflags & LINUX_XLF_CAN_BE_LOADED_ABOVE_4G)
|
|
||||||
{
|
|
||||||
grub_dprintf ("linux", "Loading kernel above 4GB is supported; enabling.\n");
|
|
||||||
- max_addresses[2].addr = GRUB_EFI_MAX_USABLE_ADDRESS;
|
|
||||||
+ max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_USABLE_ADDRESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
@@ -495,11 +504,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
grub_dprintf ("linux", "lh->pref_address: %p\n", (void *)(grub_addr_t)lh->pref_address);
|
|
||||||
if (lh->pref_address < (grub_uint64_t)GRUB_EFI_MAX_ALLOCATION_ADDRESS)
|
|
||||||
{
|
|
||||||
- max_addresses[0].addr = lh->pref_address;
|
|
||||||
- max_addresses[0].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS;
|
|
||||||
+ max_addresses[KERNEL_PREF_ADDRESS].addr = lh->pref_address;
|
|
||||||
+ max_addresses[KERNEL_PREF_ADDRESS].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS;
|
|
||||||
}
|
|
||||||
- max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
|
||||||
- max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
|
||||||
+ max_addresses[KERNEL_4G_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
|
||||||
+ max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
|
||||||
kernel_size = lh->init_size;
|
|
||||||
kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE,
|
|
||||||
N_("can't allocate kernel"));
|
|
@ -1,129 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Peter Jones <pjones@redhat.com>
|
|
||||||
Date: Mon, 1 Aug 2022 14:24:39 -0400
|
|
||||||
Subject: [PATCH] efi: split allocation policy for kernel vs initrd memories.
|
|
||||||
|
|
||||||
Currently in our kernel allocator, we use the same set of choices for
|
|
||||||
all of our various kernel and initramfs allocations, though they do not
|
|
||||||
have exactly the same constraints.
|
|
||||||
|
|
||||||
This patch adds the concept of an allocation purpose, which currently
|
|
||||||
can be KERNEL_MEM or INITRD_MEM, and updates kernel_alloc() calls
|
|
||||||
appropriately, but does not change any current policy decision. It
|
|
||||||
also adds a few debug prints.
|
|
||||||
|
|
||||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
||||||
(cherry picked from commit 36307bed28cd838116fc4af26a30719660d62d4c)
|
|
||||||
(cherry picked from commit dc1196350b0cbe89582832f44df0fce67e0c9fb2)
|
|
||||||
---
|
|
||||||
grub-core/loader/i386/efi/linux.c | 35 +++++++++++++++++++++++++++--------
|
|
||||||
1 file changed, 27 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
|
||||||
index 23b27f6507..09e7596064 100644
|
|
||||||
--- a/grub-core/loader/i386/efi/linux.c
|
|
||||||
+++ b/grub-core/loader/i386/efi/linux.c
|
|
||||||
@@ -55,7 +55,14 @@ struct grub_linuxefi_context {
|
|
||||||
|
|
||||||
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
|
||||||
|
|
||||||
+typedef enum {
|
|
||||||
+ NO_MEM,
|
|
||||||
+ KERNEL_MEM,
|
|
||||||
+ INITRD_MEM,
|
|
||||||
+} kernel_alloc_purpose_t;
|
|
||||||
+
|
|
||||||
struct allocation_choice {
|
|
||||||
+ kernel_alloc_purpose_t purpose;
|
|
||||||
grub_efi_physical_address_t addr;
|
|
||||||
grub_efi_allocate_type_t alloc_type;
|
|
||||||
};
|
|
||||||
@@ -64,6 +71,7 @@ enum {
|
|
||||||
KERNEL_PREF_ADDRESS,
|
|
||||||
KERNEL_4G_LIMIT,
|
|
||||||
KERNEL_NO_LIMIT,
|
|
||||||
+ INITRD_MAX_ADDRESS,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct allocation_choice max_addresses[] =
|
|
||||||
@@ -71,14 +79,17 @@ static struct allocation_choice max_addresses[] =
|
|
||||||
/* the kernel overrides this one with pref_address and
|
|
||||||
* GRUB_EFI_ALLOCATE_ADDRESS */
|
|
||||||
[KERNEL_PREF_ADDRESS] =
|
|
||||||
- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
+ { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
/* If the flag in params is set, this one gets changed to be above 4GB. */
|
|
||||||
[KERNEL_4G_LIMIT] =
|
|
||||||
- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
+ { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
/* this one is always below 4GB, which we still *prefer* even if the flag
|
|
||||||
* is set. */
|
|
||||||
[KERNEL_NO_LIMIT] =
|
|
||||||
- { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
+ { KERNEL_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
+ /* this is for the initrd */
|
|
||||||
+ [INITRD_MAX_ADDRESS] =
|
|
||||||
+ { INITRD_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
{ NO_MEM, 0, 0 }
|
|
||||||
};
|
|
||||||
static struct allocation_choice saved_addresses[4];
|
|
||||||
@@ -95,7 +106,8 @@ kernel_free(void *addr, grub_efi_uintn_t size)
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
-kernel_alloc(grub_efi_uintn_t size,
|
|
||||||
+kernel_alloc(kernel_alloc_purpose_t purpose,
|
|
||||||
+ grub_efi_uintn_t size,
|
|
||||||
grub_efi_memory_type_t memtype,
|
|
||||||
const char * const errmsg)
|
|
||||||
{
|
|
||||||
@@ -108,6 +120,9 @@ kernel_alloc(grub_efi_uintn_t size,
|
|
||||||
grub_uint64_t max = max_addresses[i].addr;
|
|
||||||
grub_efi_uintn_t pages;
|
|
||||||
|
|
||||||
+ if (purpose != max_addresses[i].purpose)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* When we're *not* loading the kernel, or >4GB allocations aren't
|
|
||||||
* supported, these entries are basically all the same, so don't re-try
|
|
||||||
@@ -262,7 +277,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- initrd_mem = kernel_alloc(size, GRUB_EFI_RUNTIME_SERVICES_DATA,
|
|
||||||
+ grub_dprintf ("linux", "Trying to allocate initrd mem\n");
|
|
||||||
+ initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_RUNTIME_SERVICES_DATA,
|
|
||||||
N_("can't allocate initrd"));
|
|
||||||
if (initrd_mem == NULL)
|
|
||||||
goto fail;
|
|
||||||
@@ -440,7 +456,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
- params = kernel_alloc (sizeof(*params), GRUB_EFI_RUNTIME_SERVICES_DATA,
|
|
||||||
+ params = kernel_alloc (KERNEL_MEM, sizeof(*params),
|
|
||||||
+ GRUB_EFI_RUNTIME_SERVICES_DATA,
|
|
||||||
"cannot allocate kernel parameters");
|
|
||||||
if (!params)
|
|
||||||
goto fail;
|
|
||||||
@@ -462,7 +479,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
grub_dprintf ("linux", "new lh is at %p\n", lh);
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "setting up cmdline\n");
|
|
||||||
- cmdline = kernel_alloc (lh->cmdline_size + 1,
|
|
||||||
+ cmdline = kernel_alloc (KERNEL_MEM, lh->cmdline_size + 1,
|
|
||||||
GRUB_EFI_RUNTIME_SERVICES_DATA,
|
|
||||||
N_("can't allocate cmdline"));
|
|
||||||
if (!cmdline)
|
|
||||||
@@ -510,7 +527,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
max_addresses[KERNEL_4G_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
|
||||||
max_addresses[KERNEL_NO_LIMIT].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
|
||||||
kernel_size = lh->init_size;
|
|
||||||
- kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE,
|
|
||||||
+ grub_dprintf ("linux", "Trying to allocate kernel mem\n");
|
|
||||||
+ kernel_mem = kernel_alloc (KERNEL_MEM, kernel_size,
|
|
||||||
+ GRUB_EFI_RUNTIME_SERVICES_CODE,
|
|
||||||
N_("can't allocate kernel"));
|
|
||||||
restore_addresses();
|
|
||||||
if (!kernel_mem)
|
|
@ -1,63 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Peter Jones <pjones@redhat.com>
|
|
||||||
Date: Mon, 1 Aug 2022 13:04:43 -0400
|
|
||||||
Subject: [PATCH] efi: use EFI_LOADER_(CODE|DATA) for kernel and initrd
|
|
||||||
allocations
|
|
||||||
|
|
||||||
At some point due to an erroneous kernel warning, we switched kernel and
|
|
||||||
initramfs to being loaded in EFI_RUNTIME_SERVICES_CODE and
|
|
||||||
EFI_RUNTIME_SERVICES_DATA memory pools. This doesn't appear to be
|
|
||||||
correct according to the spec, and that kernel warning has gone away.
|
|
||||||
|
|
||||||
This patch puts them back in EFI_LOADER_CODE and EFI_LOADER_DATA
|
|
||||||
allocations, respectively.
|
|
||||||
|
|
||||||
Resolves: rhbz#2108456
|
|
||||||
|
|
||||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
||||||
(cherry picked from commit 35b5d5fa47bc394c76022e6595b173e68f53225e)
|
|
||||||
(cherry picked from commit 66e1c922b40957fca488435e06a2f875a219844b)
|
|
||||||
---
|
|
||||||
grub-core/loader/i386/efi/linux.c | 8 ++++----
|
|
||||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
|
||||||
index 09e7596064..4d39023792 100644
|
|
||||||
--- a/grub-core/loader/i386/efi/linux.c
|
|
||||||
+++ b/grub-core/loader/i386/efi/linux.c
|
|
||||||
@@ -278,7 +278,7 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "Trying to allocate initrd mem\n");
|
|
||||||
- initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_RUNTIME_SERVICES_DATA,
|
|
||||||
+ initrd_mem = kernel_alloc(INITRD_MEM, size, GRUB_EFI_LOADER_DATA,
|
|
||||||
N_("can't allocate initrd"));
|
|
||||||
if (initrd_mem == NULL)
|
|
||||||
goto fail;
|
|
||||||
@@ -457,7 +457,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
#endif
|
|
||||||
|
|
||||||
params = kernel_alloc (KERNEL_MEM, sizeof(*params),
|
|
||||||
- GRUB_EFI_RUNTIME_SERVICES_DATA,
|
|
||||||
+ GRUB_EFI_LOADER_DATA,
|
|
||||||
"cannot allocate kernel parameters");
|
|
||||||
if (!params)
|
|
||||||
goto fail;
|
|
||||||
@@ -480,7 +480,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
|
|
||||||
grub_dprintf ("linux", "setting up cmdline\n");
|
|
||||||
cmdline = kernel_alloc (KERNEL_MEM, lh->cmdline_size + 1,
|
|
||||||
- GRUB_EFI_RUNTIME_SERVICES_DATA,
|
|
||||||
+ GRUB_EFI_LOADER_DATA,
|
|
||||||
N_("can't allocate cmdline"));
|
|
||||||
if (!cmdline)
|
|
||||||
goto fail;
|
|
||||||
@@ -529,7 +529,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
kernel_size = lh->init_size;
|
|
||||||
grub_dprintf ("linux", "Trying to allocate kernel mem\n");
|
|
||||||
kernel_mem = kernel_alloc (KERNEL_MEM, kernel_size,
|
|
||||||
- GRUB_EFI_RUNTIME_SERVICES_CODE,
|
|
||||||
+ GRUB_EFI_LOADER_CODE,
|
|
||||||
N_("can't allocate kernel"));
|
|
||||||
restore_addresses();
|
|
||||||
if (!kernel_mem)
|
|
@ -1,72 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Diego Domingos <diegodo@linux.vnet.ibm.com>
|
|
||||||
Date: Thu, 25 Aug 2022 11:37:56 -0400
|
|
||||||
Subject: [PATCH] ieee1275: implement vec5 for cas negotiation
|
|
||||||
|
|
||||||
As a legacy support, if the vector 5 is not implemented, Power
|
|
||||||
Hypervisor will consider the max CPUs as 64 instead 256 currently
|
|
||||||
supported during client-architecture-support negotiation.
|
|
||||||
|
|
||||||
This patch implements the vector 5 and set the MAX CPUs to 256 while
|
|
||||||
setting the others values to 0 (default).
|
|
||||||
|
|
||||||
Signed-off-by: Diego Domingos <diegodo@linux.vnet.ibm.com>
|
|
||||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
(cherry picked from commit f735c65b6da8a9d4251242b37774e1a517511253)
|
|
||||||
(cherry picked from commit 1639f43b2db4ac405ac2a92e50ed4cff351c3baa)
|
|
||||||
---
|
|
||||||
grub-core/kern/ieee1275/init.c | 20 +++++++++++++++++++-
|
|
||||||
1 file changed, 19 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
|
||||||
index 1414695cc6..37f3098c39 100644
|
|
||||||
--- a/grub-core/kern/ieee1275/init.c
|
|
||||||
+++ b/grub-core/kern/ieee1275/init.c
|
|
||||||
@@ -307,6 +307,18 @@ struct option_vector2 {
|
|
||||||
grub_uint8_t max_pft_size;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
+struct option_vector5 {
|
|
||||||
+ grub_uint8_t byte1;
|
|
||||||
+ grub_uint8_t byte2;
|
|
||||||
+ grub_uint8_t byte3;
|
|
||||||
+ grub_uint8_t cmo;
|
|
||||||
+ grub_uint8_t associativity;
|
|
||||||
+ grub_uint8_t bin_opts;
|
|
||||||
+ grub_uint8_t micro_checkpoint;
|
|
||||||
+ grub_uint8_t reserved0;
|
|
||||||
+ grub_uint32_t max_cpus;
|
|
||||||
+} __attribute__((packed));
|
|
||||||
+
|
|
||||||
struct pvr_entry {
|
|
||||||
grub_uint32_t mask;
|
|
||||||
grub_uint32_t entry;
|
|
||||||
@@ -325,6 +337,8 @@ struct cas_vector {
|
|
||||||
grub_uint16_t vec3;
|
|
||||||
grub_uint8_t vec4_size;
|
|
||||||
grub_uint16_t vec4;
|
|
||||||
+ grub_uint8_t vec5_size;
|
|
||||||
+ struct option_vector5 vec5;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
/* Call ibm,client-architecture-support to try to get more RMA.
|
|
||||||
@@ -345,7 +359,7 @@ grub_ieee1275_ibm_cas (void)
|
|
||||||
} args;
|
|
||||||
struct cas_vector vector = {
|
|
||||||
.pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
|
|
||||||
- .num_vecs = 4 - 1,
|
|
||||||
+ .num_vecs = 5 - 1,
|
|
||||||
.vec1_size = 0,
|
|
||||||
.vec1 = 0x80, /* ignore */
|
|
||||||
.vec2_size = 1 + sizeof(struct option_vector2) - 2,
|
|
||||||
@@ -356,6 +370,10 @@ grub_ieee1275_ibm_cas (void)
|
|
||||||
.vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied
|
|
||||||
.vec4_size = 2 - 1,
|
|
||||||
.vec4 = 0x0001, // set required minimum capacity % to the lowest value
|
|
||||||
+ .vec5_size = 1 + sizeof(struct option_vector5) - 2,
|
|
||||||
+ .vec5 = {
|
|
||||||
+ 0, 0, 0, 0, 0, 0, 0, 0, 256
|
|
||||||
+ }
|
|
||||||
};
|
|
||||||
|
|
||||||
INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
|
|
@ -1,38 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Peter Jones <pjones@redhat.com>
|
|
||||||
Date: Tue, 11 Oct 2022 17:00:50 -0400
|
|
||||||
Subject: [PATCH] x86-efi: Fix an incorrect array size in kernel allocation
|
|
||||||
|
|
||||||
In 81a6ebf62bbe166ddc968463df2e8bd481bf697c ("efi: split allocation
|
|
||||||
policy for kernel vs initrd memories."), I introduced a split in the
|
|
||||||
kernel allocator to allow for different dynamic policies for the kernel
|
|
||||||
and the initrd allocations.
|
|
||||||
|
|
||||||
Unfortunately, that change increased the size of the policy data used to
|
|
||||||
make decisions, but did not change the size of the temporary storage we
|
|
||||||
use to back it up and restore. This results in some of .data getting
|
|
||||||
clobbered at runtime, and hilarity ensues.
|
|
||||||
|
|
||||||
This patch makes the size of the backup storage be based on the size of
|
|
||||||
the initial policy data.
|
|
||||||
|
|
||||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
||||||
(cherry picked from commit 37747b22342499a798ca3a8895770cd93b6e1258)
|
|
||||||
(cherry picked from commit 72713ce761720235c86bbda412480c97b2892e00)
|
|
||||||
---
|
|
||||||
grub-core/loader/i386/efi/linux.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
|
||||||
index 4d39023792..3d55f8b8d2 100644
|
|
||||||
--- a/grub-core/loader/i386/efi/linux.c
|
|
||||||
+++ b/grub-core/loader/i386/efi/linux.c
|
|
||||||
@@ -92,7 +92,7 @@ static struct allocation_choice max_addresses[] =
|
|
||||||
{ INITRD_MEM, GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
|
||||||
{ NO_MEM, 0, 0 }
|
|
||||||
};
|
|
||||||
-static struct allocation_choice saved_addresses[4];
|
|
||||||
+static struct allocation_choice saved_addresses[sizeof(max_addresses) / sizeof(max_addresses[0])];
|
|
||||||
|
|
||||||
#define save_addresses() grub_memcpy(saved_addresses, max_addresses, sizeof(max_addresses))
|
|
||||||
#define restore_addresses() grub_memcpy(max_addresses, saved_addresses, sizeof(max_addresses))
|
|
@ -1,25 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
Date: Tue, 18 Oct 2022 14:15:28 -0400
|
|
||||||
Subject: [PATCH] switch-to-blscfg: don't assume newline at end of cfg
|
|
||||||
|
|
||||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
|
||||||
---
|
|
||||||
util/grub-switch-to-blscfg.in | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in
|
|
||||||
index eeea130770..5a97954c39 100644
|
|
||||||
--- a/util/grub-switch-to-blscfg.in
|
|
||||||
+++ b/util/grub-switch-to-blscfg.in
|
|
||||||
@@ -277,7 +277,9 @@ if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \
|
|
||||||
fi
|
|
||||||
GENERATE=1
|
|
||||||
elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then
|
|
||||||
- if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then
|
|
||||||
+ # prepend in case admins have been bad at newlines
|
|
||||||
+ sed -i '1iGRUB_ENABLE_BLSCFG=true' "${etcdefaultgrub}"
|
|
||||||
+ if ! grep -q '^GRUB_ENABLE_BLSCFG=true' "${etcdefaultgrub}" ; then
|
|
||||||
gettext_printf "Updating %s failed\n" "${etcdefaultgrub}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
@ -1,33 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Wed, 3 Aug 2022 19:45:33 +0800
|
|
||||||
Subject: [PATCH] font: Reject glyphs exceeds font->max_glyph_width or
|
|
||||||
font->max_glyph_height
|
|
||||||
|
|
||||||
Check glyph's width and height against limits specified in font's
|
|
||||||
metadata. Reject the glyph (and font) if such limits are exceeded.
|
|
||||||
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit 5760fcfd466cc757540ea0d591bad6a08caeaa16)
|
|
||||||
(cherry picked from commit 3b410ef4bb95e607cadeba2193fa90ae9bddb98d)
|
|
||||||
(cherry picked from commit 8ebe587def61af7893ebcae87d45c883f3cfb713)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index b67507fcc8..8d1a990401 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -760,7 +760,9 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
|
|
||||||
|| read_be_uint16 (font->file, &height) != 0
|
|
||||||
|| read_be_int16 (font->file, &xoff) != 0
|
|
||||||
|| read_be_int16 (font->file, &yoff) != 0
|
|
||||||
- || read_be_int16 (font->file, &dwidth) != 0)
|
|
||||||
+ || read_be_int16 (font->file, &dwidth) != 0
|
|
||||||
+ || width > font->max_char_width
|
|
||||||
+ || height > font->max_char_height)
|
|
||||||
{
|
|
||||||
remove_font (font);
|
|
||||||
return 0;
|
|
@ -1,112 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Fri, 5 Aug 2022 00:51:20 +0800
|
|
||||||
Subject: [PATCH] font: Fix size overflow in grub_font_get_glyph_internal()
|
|
||||||
|
|
||||||
The length of memory allocation and file read may overflow. This patch
|
|
||||||
fixes the problem by using safemath macros.
|
|
||||||
|
|
||||||
There is a lot of code repetition like "(x * y + 7) / 8". It is unsafe
|
|
||||||
if overflow happens. This patch introduces grub_video_bitmap_calc_1bpp_bufsz().
|
|
||||||
It is safe replacement for such code. It has safemath-like prototype.
|
|
||||||
|
|
||||||
This patch also introduces grub_cast(value, pointer), it casts value to
|
|
||||||
typeof(*pointer) then store the value to *pointer. It returns true when
|
|
||||||
overflow occurs or false if there is no overflow. The semantics of arguments
|
|
||||||
and return value are designed to be consistent with other safemath macros.
|
|
||||||
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit 941d10ad6f1dcbd12fb613002249e29ba035f985)
|
|
||||||
(cherry picked from commit 6bca9693878bdf61dd62b8c784862a48e75f569a)
|
|
||||||
(cherry picked from commit edbbda5486cf8c3dc2b68fbd3dead822ab448022)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 17 +++++++++++++----
|
|
||||||
include/grub/bitmap.h | 18 ++++++++++++++++++
|
|
||||||
include/grub/safemath.h | 2 ++
|
|
||||||
3 files changed, 33 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index 8d1a990401..d6df79602d 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -739,7 +739,8 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
|
|
||||||
grub_int16_t xoff;
|
|
||||||
grub_int16_t yoff;
|
|
||||||
grub_int16_t dwidth;
|
|
||||||
- int len;
|
|
||||||
+ grub_ssize_t len;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
if (index_entry->glyph)
|
|
||||||
/* Return cached glyph. */
|
|
||||||
@@ -768,9 +769,17 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- len = (width * height + 7) / 8;
|
|
||||||
- glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
|
|
||||||
- if (!glyph)
|
|
||||||
+ /* Calculate real struct size of current glyph. */
|
|
||||||
+ if (grub_video_bitmap_calc_1bpp_bufsz (width, height, &len) ||
|
|
||||||
+ grub_add (sizeof (struct grub_font_glyph), len, &sz))
|
|
||||||
+ {
|
|
||||||
+ remove_font (font);
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Allocate and initialize the glyph struct. */
|
|
||||||
+ glyph = grub_malloc (sz);
|
|
||||||
+ if (glyph == NULL)
|
|
||||||
{
|
|
||||||
remove_font (font);
|
|
||||||
return 0;
|
|
||||||
diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h
|
|
||||||
index 5728f8ca3a..0d9603f619 100644
|
|
||||||
--- a/include/grub/bitmap.h
|
|
||||||
+++ b/include/grub/bitmap.h
|
|
||||||
@@ -23,6 +23,7 @@
|
|
||||||
#include <grub/symbol.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/video.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
struct grub_video_bitmap
|
|
||||||
{
|
|
||||||
@@ -79,6 +80,23 @@ grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
|
|
||||||
return bitmap->mode_info.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Calculate and store the size of data buffer of 1bit bitmap in result.
|
|
||||||
+ * Equivalent to "*result = (width * height + 7) / 8" if no overflow occurs.
|
|
||||||
+ * Return true when overflow occurs or false if there is no overflow.
|
|
||||||
+ * This function is intentionally implemented as a macro instead of
|
|
||||||
+ * an inline function. Although a bit awkward, it preserves data types for
|
|
||||||
+ * safemath macros and reduces macro side effects as much as possible.
|
|
||||||
+ *
|
|
||||||
+ * XXX: Will report false overflow if width * height > UINT64_MAX.
|
|
||||||
+ */
|
|
||||||
+#define grub_video_bitmap_calc_1bpp_bufsz(width, height, result) \
|
|
||||||
+({ \
|
|
||||||
+ grub_uint64_t _bitmap_pixels; \
|
|
||||||
+ grub_mul ((width), (height), &_bitmap_pixels) ? 1 : \
|
|
||||||
+ grub_cast (_bitmap_pixels / GRUB_CHAR_BIT + !!(_bitmap_pixels % GRUB_CHAR_BIT), (result)); \
|
|
||||||
+})
|
|
||||||
+
|
|
||||||
void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap,
|
|
||||||
struct grub_video_mode_info *mode_info);
|
|
||||||
|
|
||||||
diff --git a/include/grub/safemath.h b/include/grub/safemath.h
|
|
||||||
index 1ccac276b5..30800ad6a1 100644
|
|
||||||
--- a/include/grub/safemath.h
|
|
||||||
+++ b/include/grub/safemath.h
|
|
||||||
@@ -30,6 +30,8 @@
|
|
||||||
#define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res)
|
|
||||||
#define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res)
|
|
||||||
|
|
||||||
+#define grub_cast(a, res) grub_add ((a), 0, (res))
|
|
||||||
+
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* Copyright 2020 Rasmus Villemoes
|
|
@ -1,81 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Fri, 5 Aug 2022 01:58:27 +0800
|
|
||||||
Subject: [PATCH] font: Fix several integer overflows in
|
|
||||||
grub_font_construct_glyph()
|
|
||||||
|
|
||||||
This patch fixes several integer overflows in grub_font_construct_glyph().
|
|
||||||
Glyphs of invalid size, zero or leading to an overflow, are rejected.
|
|
||||||
The inconsistency between "glyph" and "max_glyph_size" when grub_malloc()
|
|
||||||
returns NULL is fixed too.
|
|
||||||
|
|
||||||
Fixes: CVE-2022-2601
|
|
||||||
|
|
||||||
Reported-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit b1805f251b31a9d3cfae5c3572ddfa630145dbbf)
|
|
||||||
(cherry picked from commit b91eb9bd6c724339b7d7bb4765b9d36f1ee88b84)
|
|
||||||
(cherry picked from commit 1ebafd82dd19e522f0d753fd9828553fe8bcac78)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 29 +++++++++++++++++------------
|
|
||||||
1 file changed, 17 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index d6df79602d..129aaa3838 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -1517,6 +1517,7 @@ grub_font_construct_glyph (grub_font_t hinted_font,
|
|
||||||
struct grub_video_signed_rect bounds;
|
|
||||||
static struct grub_font_glyph *glyph = 0;
|
|
||||||
static grub_size_t max_glyph_size = 0;
|
|
||||||
+ grub_size_t cur_glyph_size;
|
|
||||||
|
|
||||||
ensure_comb_space (glyph_id);
|
|
||||||
|
|
||||||
@@ -1533,29 +1534,33 @@ grub_font_construct_glyph (grub_font_t hinted_font,
|
|
||||||
if (!glyph_id->ncomb && !glyph_id->attributes)
|
|
||||||
return main_glyph;
|
|
||||||
|
|
||||||
- if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT)
|
|
||||||
+ if (grub_video_bitmap_calc_1bpp_bufsz (bounds.width, bounds.height, &cur_glyph_size) ||
|
|
||||||
+ grub_add (sizeof (*glyph), cur_glyph_size, &cur_glyph_size))
|
|
||||||
+ return main_glyph;
|
|
||||||
+
|
|
||||||
+ if (max_glyph_size < cur_glyph_size)
|
|
||||||
{
|
|
||||||
grub_free (glyph);
|
|
||||||
- max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2;
|
|
||||||
- if (max_glyph_size < 8)
|
|
||||||
- max_glyph_size = 8;
|
|
||||||
- glyph = grub_malloc (max_glyph_size);
|
|
||||||
+ if (grub_mul (cur_glyph_size, 2, &max_glyph_size))
|
|
||||||
+ max_glyph_size = 0;
|
|
||||||
+ glyph = max_glyph_size > 0 ? grub_malloc (max_glyph_size) : NULL;
|
|
||||||
}
|
|
||||||
if (!glyph)
|
|
||||||
{
|
|
||||||
+ max_glyph_size = 0;
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
return main_glyph;
|
|
||||||
}
|
|
||||||
|
|
||||||
- grub_memset (glyph, 0, sizeof (*glyph)
|
|
||||||
- + (bounds.width * bounds.height
|
|
||||||
- + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT);
|
|
||||||
+ grub_memset (glyph, 0, cur_glyph_size);
|
|
||||||
|
|
||||||
glyph->font = main_glyph->font;
|
|
||||||
- glyph->width = bounds.width;
|
|
||||||
- glyph->height = bounds.height;
|
|
||||||
- glyph->offset_x = bounds.x;
|
|
||||||
- glyph->offset_y = bounds.y;
|
|
||||||
+ if (bounds.width == 0 || bounds.height == 0 ||
|
|
||||||
+ grub_cast (bounds.width, &glyph->width) ||
|
|
||||||
+ grub_cast (bounds.height, &glyph->height) ||
|
|
||||||
+ grub_cast (bounds.x, &glyph->offset_x) ||
|
|
||||||
+ grub_cast (bounds.y, &glyph->offset_y))
|
|
||||||
+ return main_glyph;
|
|
||||||
|
|
||||||
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)
|
|
||||||
grub_font_blit_glyph_mirror (glyph, main_glyph,
|
|
@ -1,42 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Fri, 5 Aug 2022 02:13:29 +0800
|
|
||||||
Subject: [PATCH] font: Remove grub_font_dup_glyph()
|
|
||||||
|
|
||||||
Remove grub_font_dup_glyph() since nobody is using it since 2013, and
|
|
||||||
I'm too lazy to fix the integer overflow problem in it.
|
|
||||||
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit 25ad31c19c331aaa2dbd9bd2b2e2655de5766a9d)
|
|
||||||
(cherry picked from commit ad950e1e033318bb50222ed268a6dcfb97389035)
|
|
||||||
(cherry picked from commit 71644fccc1d43309f0a379dcfe9341ec3bd9657d)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 14 --------------
|
|
||||||
1 file changed, 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index 129aaa3838..347e9dfa29 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -1055,20 +1055,6 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
|
|
||||||
return best_glyph;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#if 0
|
|
||||||
-static struct grub_font_glyph *
|
|
||||||
-grub_font_dup_glyph (struct grub_font_glyph *glyph)
|
|
||||||
-{
|
|
||||||
- static struct grub_font_glyph *ret;
|
|
||||||
- ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8);
|
|
||||||
- if (!ret)
|
|
||||||
- return NULL;
|
|
||||||
- grub_memcpy (ret, glyph, sizeof (*ret)
|
|
||||||
- + (glyph->width * glyph->height + 7) / 8);
|
|
||||||
- return ret;
|
|
||||||
-}
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
/* FIXME: suboptimal. */
|
|
||||||
static void
|
|
||||||
grub_font_blit_glyph (struct grub_font_glyph *target,
|
|
@ -1,48 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Fri, 5 Aug 2022 02:27:05 +0800
|
|
||||||
Subject: [PATCH] font: Fix integer overflow in ensure_comb_space()
|
|
||||||
|
|
||||||
In fact it can't overflow at all because glyph_id->ncomb is only 8-bit
|
|
||||||
wide. But let's keep safe if somebody changes the width of glyph_id->ncomb
|
|
||||||
in the future. This patch also fixes the inconsistency between
|
|
||||||
render_max_comb_glyphs and render_combining_glyphs when grub_malloc()
|
|
||||||
returns NULL.
|
|
||||||
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit b2740b7e4a03bb8331d48b54b119afea76bb9d5f)
|
|
||||||
(cherry picked from commit f66ea1e60c347408e92b6695d5105c7e0f24d568)
|
|
||||||
(cherry picked from commit 0e07159c24cdbb62a9d19fba8199065b049e03c7)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 14 +++++++++-----
|
|
||||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index 347e9dfa29..1367e44743 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -1468,14 +1468,18 @@ ensure_comb_space (const struct grub_unicode_glyph *glyph_id)
|
|
||||||
if (glyph_id->ncomb <= render_max_comb_glyphs)
|
|
||||||
return;
|
|
||||||
|
|
||||||
- render_max_comb_glyphs = 2 * glyph_id->ncomb;
|
|
||||||
- if (render_max_comb_glyphs < 8)
|
|
||||||
+ if (grub_mul (glyph_id->ncomb, 2, &render_max_comb_glyphs))
|
|
||||||
+ render_max_comb_glyphs = 0;
|
|
||||||
+ if (render_max_comb_glyphs > 0 && render_max_comb_glyphs < 8)
|
|
||||||
render_max_comb_glyphs = 8;
|
|
||||||
grub_free (render_combining_glyphs);
|
|
||||||
- render_combining_glyphs = grub_malloc (render_max_comb_glyphs
|
|
||||||
- * sizeof (render_combining_glyphs[0]));
|
|
||||||
+ render_combining_glyphs = (render_max_comb_glyphs > 0) ?
|
|
||||||
+ grub_calloc (render_max_comb_glyphs, sizeof (render_combining_glyphs[0])) : NULL;
|
|
||||||
if (!render_combining_glyphs)
|
|
||||||
- grub_errno = 0;
|
|
||||||
+ {
|
|
||||||
+ render_max_comb_glyphs = 0;
|
|
||||||
+ grub_errno = GRUB_ERR_NONE;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
@ -1,65 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Mon, 15 Aug 2022 02:04:58 +0800
|
|
||||||
Subject: [PATCH] font: Fix integer overflow in BMP index
|
|
||||||
|
|
||||||
The BMP index (font->bmp_idx) is designed as a reverse lookup table of
|
|
||||||
char entries (font->char_index), in order to speed up lookups for BMP
|
|
||||||
chars (i.e. code < 0x10000). The values in BMP index are the subscripts
|
|
||||||
of the corresponding char entries, stored in grub_uint16_t, while 0xffff
|
|
||||||
means not found.
|
|
||||||
|
|
||||||
This patch fixes the problem of large subscript truncated to grub_uint16_t,
|
|
||||||
leading BMP index to return wrong char entry or report false miss. The
|
|
||||||
code now checks for bounds and uses BMP index as a hint, and fallbacks
|
|
||||||
to binary-search if necessary.
|
|
||||||
|
|
||||||
On the occasion add a comment about BMP index is initialized to 0xffff.
|
|
||||||
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit afda8b60ba0712abe01ae1e64c5f7a067a0e6492)
|
|
||||||
(cherry picked from commit 6d90568929e11739b56f09ebbce9185ca9c23519)
|
|
||||||
(cherry picked from commit b8c47c3dd6894b3135db861e3e563f661efad5c3)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 13 +++++++++----
|
|
||||||
1 file changed, 9 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index 1367e44743..059c23dff7 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -300,6 +300,8 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
|
||||||
font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
|
|
||||||
if (!font->bmp_idx)
|
|
||||||
return 1;
|
|
||||||
+
|
|
||||||
+ /* Init the BMP index array to 0xffff. */
|
|
||||||
grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t));
|
|
||||||
|
|
||||||
|
|
||||||
@@ -328,7 +330,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (entry->code < 0x10000)
|
|
||||||
+ if (entry->code < 0x10000 && i < 0xffff)
|
|
||||||
font->bmp_idx[entry->code] = i;
|
|
||||||
|
|
||||||
last_code = entry->code;
|
|
||||||
@@ -696,9 +698,12 @@ find_glyph (const grub_font_t font, grub_uint32_t code)
|
|
||||||
/* Use BMP index if possible. */
|
|
||||||
if (code < 0x10000 && font->bmp_idx)
|
|
||||||
{
|
|
||||||
- if (font->bmp_idx[code] == 0xffff)
|
|
||||||
- return 0;
|
|
||||||
- return &table[font->bmp_idx[code]];
|
|
||||||
+ if (font->bmp_idx[code] < 0xffff)
|
|
||||||
+ return &table[font->bmp_idx[code]];
|
|
||||||
+ /*
|
|
||||||
+ * When we are here then lookup in BMP index result in miss,
|
|
||||||
+ * fallthough to binary-search.
|
|
||||||
+ */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do a binary search in `char_index', which is ordered by code point. */
|
|
@ -1,85 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Sun, 14 Aug 2022 18:09:38 +0800
|
|
||||||
Subject: [PATCH] font: Fix integer underflow in binary search of char index
|
|
||||||
|
|
||||||
If search target is less than all entries in font->index then "hi"
|
|
||||||
variable is set to -1, which translates to SIZE_MAX and leads to errors.
|
|
||||||
|
|
||||||
This patch fixes the problem by replacing the entire binary search code
|
|
||||||
with the libstdc++'s std::lower_bound() implementation.
|
|
||||||
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit c140a086838e7c9af87842036f891b8393a8c4bc)
|
|
||||||
(cherry picked from commit e110997335b1744464ea232d57a7d86e16ca8dee)
|
|
||||||
(cherry picked from commit 403053a5116ae945f9515a82c37ff8cfb927362c)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 40 ++++++++++++++++++++++------------------
|
|
||||||
1 file changed, 22 insertions(+), 18 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index 059c23dff7..31786ab339 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -688,12 +688,12 @@ read_be_int16 (grub_file_t file, grub_int16_t * value)
|
|
||||||
static inline struct char_index_entry *
|
|
||||||
find_glyph (const grub_font_t font, grub_uint32_t code)
|
|
||||||
{
|
|
||||||
- struct char_index_entry *table;
|
|
||||||
- grub_size_t lo;
|
|
||||||
- grub_size_t hi;
|
|
||||||
- grub_size_t mid;
|
|
||||||
+ struct char_index_entry *table, *first, *end;
|
|
||||||
+ grub_size_t len;
|
|
||||||
|
|
||||||
table = font->char_index;
|
|
||||||
+ if (table == NULL)
|
|
||||||
+ return NULL;
|
|
||||||
|
|
||||||
/* Use BMP index if possible. */
|
|
||||||
if (code < 0x10000 && font->bmp_idx)
|
|
||||||
@@ -706,25 +706,29 @@ find_glyph (const grub_font_t font, grub_uint32_t code)
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* Do a binary search in `char_index', which is ordered by code point. */
|
|
||||||
- lo = 0;
|
|
||||||
- hi = font->num_chars - 1;
|
|
||||||
+ /*
|
|
||||||
+ * Do a binary search in char_index which is ordered by code point.
|
|
||||||
+ * The code below is the same as libstdc++'s std::lower_bound().
|
|
||||||
+ */
|
|
||||||
+ first = table;
|
|
||||||
+ len = font->num_chars;
|
|
||||||
+ end = first + len;
|
|
||||||
|
|
||||||
- if (!table)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- while (lo <= hi)
|
|
||||||
+ while (len > 0)
|
|
||||||
{
|
|
||||||
- mid = lo + (hi - lo) / 2;
|
|
||||||
- if (code < table[mid].code)
|
|
||||||
- hi = mid - 1;
|
|
||||||
- else if (code > table[mid].code)
|
|
||||||
- lo = mid + 1;
|
|
||||||
+ grub_size_t half = len >> 1;
|
|
||||||
+ struct char_index_entry *middle = first + half;
|
|
||||||
+
|
|
||||||
+ if (middle->code < code)
|
|
||||||
+ {
|
|
||||||
+ first = middle + 1;
|
|
||||||
+ len = len - half - 1;
|
|
||||||
+ }
|
|
||||||
else
|
|
||||||
- return &table[mid];
|
|
||||||
+ len = half;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return 0;
|
|
||||||
+ return (first < end && first->code == code) ? first : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded
|
|
@ -1,85 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Tue, 6 Sep 2022 03:03:21 +0800
|
|
||||||
Subject: [PATCH] fbutil: Fix integer overflow
|
|
||||||
|
|
||||||
Expressions like u64 = u32 * u32 are unsafe because their products are
|
|
||||||
truncated to u32 even if left hand side is u64. This patch fixes all
|
|
||||||
problems like that one in fbutil.
|
|
||||||
|
|
||||||
To get right result not only left hand side have to be u64 but it's also
|
|
||||||
necessary to cast at least one of the operands of all leaf operators of
|
|
||||||
right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be
|
|
||||||
u64 = (u64)u32 * u32 + (u64)u32 * u32.
|
|
||||||
|
|
||||||
For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any
|
|
||||||
combination of values in (grub_uint64_t)u32 * u32 + u32 expression will
|
|
||||||
not overflow grub_uint64_t.
|
|
||||||
|
|
||||||
Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable.
|
|
||||||
They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32.
|
|
||||||
|
|
||||||
This patch also adds a comment to grub_video_fb_get_video_ptr() which
|
|
||||||
says it's arguments must be valid and no sanity check is performed
|
|
||||||
(like its siblings in grub-core/video/fb/fbutil.c).
|
|
||||||
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit 50a11a81bc842c58962244a2dc86bbd31a426e12)
|
|
||||||
(cherry picked from commit 8fa75d647362c938c4cc302cf5945b31fb92c078)
|
|
||||||
(cherry picked from commit 91005e39b3c8b6ca8dcc84ecb19ac9328966aaea)
|
|
||||||
---
|
|
||||||
grub-core/video/fb/fbutil.c | 4 ++--
|
|
||||||
include/grub/fbutil.h | 13 +++++++++----
|
|
||||||
2 files changed, 11 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c
|
|
||||||
index b98bb51fe8..25ef39f47d 100644
|
|
||||||
--- a/grub-core/video/fb/fbutil.c
|
|
||||||
+++ b/grub-core/video/fb/fbutil.c
|
|
||||||
@@ -67,7 +67,7 @@ get_pixel (struct grub_video_fbblit_info *source,
|
|
||||||
case 1:
|
|
||||||
if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
|
|
||||||
{
|
|
||||||
- int bit_index = y * source->mode_info->width + x;
|
|
||||||
+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
|
|
||||||
grub_uint8_t *ptr = source->data + bit_index / 8;
|
|
||||||
int bit_pos = 7 - bit_index % 8;
|
|
||||||
color = (*ptr >> bit_pos) & 0x01;
|
|
||||||
@@ -138,7 +138,7 @@ set_pixel (struct grub_video_fbblit_info *source,
|
|
||||||
case 1:
|
|
||||||
if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
|
|
||||||
{
|
|
||||||
- int bit_index = y * source->mode_info->width + x;
|
|
||||||
+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x;
|
|
||||||
grub_uint8_t *ptr = source->data + bit_index / 8;
|
|
||||||
int bit_pos = 7 - bit_index % 8;
|
|
||||||
*ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
|
|
||||||
diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h
|
|
||||||
index 4205eb917f..78a1ab3b45 100644
|
|
||||||
--- a/include/grub/fbutil.h
|
|
||||||
+++ b/include/grub/fbutil.h
|
|
||||||
@@ -31,14 +31,19 @@ struct grub_video_fbblit_info
|
|
||||||
grub_uint8_t *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
-/* Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
|
|
||||||
- and it doesn't make sense, in general, to ask for a pointer
|
|
||||||
- to a particular pixel's data. */
|
|
||||||
+/*
|
|
||||||
+ * Don't use for 1-bit bitmaps, addressing needs to be done at the bit level
|
|
||||||
+ * and it doesn't make sense, in general, to ask for a pointer
|
|
||||||
+ * to a particular pixel's data.
|
|
||||||
+ *
|
|
||||||
+ * This function assumes that bounds checking has been done in previous phase
|
|
||||||
+ * and they are opted out in here.
|
|
||||||
+ */
|
|
||||||
static inline void *
|
|
||||||
grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source,
|
|
||||||
unsigned int x, unsigned int y)
|
|
||||||
{
|
|
||||||
- return source->data + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel;
|
|
||||||
+ return source->data + (grub_addr_t) y * source->mode_info->pitch + (grub_addr_t) x * source->mode_info->bytes_per_pixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance pointer by VAL bytes. If there is no unaligned access available,
|
|
@ -1,91 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Mon, 24 Oct 2022 08:05:35 +0800
|
|
||||||
Subject: [PATCH] font: Fix an integer underflow in blit_comb()
|
|
||||||
|
|
||||||
The expression (ctx.bounds.height - combining_glyphs[i]->height) / 2 may
|
|
||||||
evaluate to a very big invalid value even if both ctx.bounds.height and
|
|
||||||
combining_glyphs[i]->height are small integers. For example, if
|
|
||||||
ctx.bounds.height is 10 and combining_glyphs[i]->height is 12, this
|
|
||||||
expression evaluates to 2147483647 (expected -1). This is because
|
|
||||||
coordinates are allowed to be negative but ctx.bounds.height is an
|
|
||||||
unsigned int. So, the subtraction operates on unsigned ints and
|
|
||||||
underflows to a very big value. The division makes things even worse.
|
|
||||||
The quotient is still an invalid value even if converted back to int.
|
|
||||||
|
|
||||||
This patch fixes the problem by casting ctx.bounds.height to int. As
|
|
||||||
a result the subtraction will operate on int and grub_uint16_t which
|
|
||||||
will be promoted to an int. So, the underflow will no longer happen. Other
|
|
||||||
uses of ctx.bounds.height (and ctx.bounds.width) are also casted to int,
|
|
||||||
to ensure coordinates are always calculated on signed integers.
|
|
||||||
|
|
||||||
Fixes: CVE-2022-3775
|
|
||||||
|
|
||||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit 6d2668dea3774ed74c4cd1eadd146f1b846bc3d4)
|
|
||||||
(cherry picked from commit 05e532fb707bbf79aa4e1efbde4d208d7da89d6b)
|
|
||||||
(cherry picked from commit 0b2592fbb245d53c5c42885d695ece03ddb0eb12)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 16 ++++++++--------
|
|
||||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index 31786ab339..fc9d92fce4 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -1203,12 +1203,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
|
||||||
ctx.bounds.height = main_glyph->height;
|
|
||||||
|
|
||||||
above_rightx = main_glyph->offset_x + main_glyph->width;
|
|
||||||
- above_righty = ctx.bounds.y + ctx.bounds.height;
|
|
||||||
+ above_righty = ctx.bounds.y + (int) ctx.bounds.height;
|
|
||||||
|
|
||||||
above_leftx = main_glyph->offset_x;
|
|
||||||
- above_lefty = ctx.bounds.y + ctx.bounds.height;
|
|
||||||
+ above_lefty = ctx.bounds.y + (int) ctx.bounds.height;
|
|
||||||
|
|
||||||
- below_rightx = ctx.bounds.x + ctx.bounds.width;
|
|
||||||
+ below_rightx = ctx.bounds.x + (int) ctx.bounds.width;
|
|
||||||
below_righty = ctx.bounds.y;
|
|
||||||
|
|
||||||
comb = grub_unicode_get_comb (glyph_id);
|
|
||||||
@@ -1221,7 +1221,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
|
||||||
|
|
||||||
if (!combining_glyphs[i])
|
|
||||||
continue;
|
|
||||||
- targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
|
|
||||||
+ targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
|
|
||||||
/* CGJ is to avoid diacritics reordering. */
|
|
||||||
if (comb[i].code
|
|
||||||
== GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
|
|
||||||
@@ -1231,8 +1231,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
|
||||||
case GRUB_UNICODE_COMB_OVERLAY:
|
|
||||||
do_blit (combining_glyphs[i],
|
|
||||||
targetx,
|
|
||||||
- (ctx.bounds.height - combining_glyphs[i]->height) / 2
|
|
||||||
- - (ctx.bounds.height + ctx.bounds.y), &ctx);
|
|
||||||
+ ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2
|
|
||||||
+ - ((int) ctx.bounds.height + ctx.bounds.y), &ctx);
|
|
||||||
if (min_devwidth < combining_glyphs[i]->width)
|
|
||||||
min_devwidth = combining_glyphs[i]->width;
|
|
||||||
break;
|
|
||||||
@@ -1305,7 +1305,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
|
||||||
/* Fallthrough. */
|
|
||||||
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
|
|
||||||
do_blit (combining_glyphs[i], targetx,
|
|
||||||
- -(ctx.bounds.height + ctx.bounds.y + space
|
|
||||||
+ -((int) ctx.bounds.height + ctx.bounds.y + space
|
|
||||||
+ combining_glyphs[i]->height), &ctx);
|
|
||||||
if (min_devwidth < combining_glyphs[i]->width)
|
|
||||||
min_devwidth = combining_glyphs[i]->width;
|
|
||||||
@@ -1313,7 +1313,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
|
||||||
|
|
||||||
case GRUB_UNICODE_COMB_HEBREW_DAGESH:
|
|
||||||
do_blit (combining_glyphs[i], targetx,
|
|
||||||
- -(ctx.bounds.height / 2 + ctx.bounds.y
|
|
||||||
+ -((int) ctx.bounds.height / 2 + ctx.bounds.y
|
|
||||||
+ combining_glyphs[i]->height / 2), &ctx);
|
|
||||||
if (min_devwidth < combining_glyphs[i]->width)
|
|
||||||
min_devwidth = combining_glyphs[i]->width;
|
|
@ -1,75 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Mon, 24 Oct 2022 07:15:41 +0800
|
|
||||||
Subject: [PATCH] font: Harden grub_font_blit_glyph() and
|
|
||||||
grub_font_blit_glyph_mirror()
|
|
||||||
|
|
||||||
As a mitigation and hardening measure add sanity checks to
|
|
||||||
grub_font_blit_glyph() and grub_font_blit_glyph_mirror(). This patch
|
|
||||||
makes these two functions do nothing if target blitting area isn't fully
|
|
||||||
contained in target bitmap. Therefore, if complex calculations in caller
|
|
||||||
overflows and malicious coordinates are given, we are still safe because
|
|
||||||
any coordinates which result in out-of-bound-write are rejected. However,
|
|
||||||
this patch only checks for invalid coordinates, and doesn't provide any
|
|
||||||
protection against invalid source glyph or destination glyph, e.g.
|
|
||||||
mismatch between glyph size and buffer size.
|
|
||||||
|
|
||||||
This hardening measure is designed to mitigate possible overflows in
|
|
||||||
blit_comb(). If overflow occurs, it may return invalid bounding box
|
|
||||||
during dry run and call grub_font_blit_glyph() with malicious
|
|
||||||
coordinates during actual blitting. However, we are still safe because
|
|
||||||
the scratch glyph itself is valid, although its size makes no sense, and
|
|
||||||
any invalid coordinates are rejected.
|
|
||||||
|
|
||||||
It would be better to call grub_fatal() if illegal parameter is detected.
|
|
||||||
However, doing this may end up in a dangerous recursion because grub_fatal()
|
|
||||||
would print messages to the screen and we are in the progress of drawing
|
|
||||||
characters on the screen.
|
|
||||||
|
|
||||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit fcd7aa0c278f7cf3fb9f93f1a3966e1792339eb6)
|
|
||||||
(cherry picked from commit 1d37ec63a1c76a14fdf70f548eada92667b42ddb)
|
|
||||||
(cherry picked from commit 686c72ea0a841343b7d8ab64e815751aa36e24b5)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 14 ++++++++++++++
|
|
||||||
1 file changed, 14 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index fc9d92fce4..cfa4bd5096 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -1069,8 +1069,15 @@ static void
|
|
||||||
grub_font_blit_glyph (struct grub_font_glyph *target,
|
|
||||||
struct grub_font_glyph *src, unsigned dx, unsigned dy)
|
|
||||||
{
|
|
||||||
+ grub_uint16_t max_x, max_y;
|
|
||||||
unsigned src_bit, tgt_bit, src_byte, tgt_byte;
|
|
||||||
unsigned i, j;
|
|
||||||
+
|
|
||||||
+ /* Harden against out-of-bound writes. */
|
|
||||||
+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
|
|
||||||
+ (grub_add (dy, src->height, &max_y) || max_y > target->height))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
for (i = 0; i < src->height; i++)
|
|
||||||
{
|
|
||||||
src_bit = (src->width * i) % 8;
|
|
||||||
@@ -1102,9 +1109,16 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
|
|
||||||
struct grub_font_glyph *src,
|
|
||||||
unsigned dx, unsigned dy)
|
|
||||||
{
|
|
||||||
+ grub_uint16_t max_x, max_y;
|
|
||||||
unsigned tgt_bit, src_byte, tgt_byte;
|
|
||||||
signed src_bit;
|
|
||||||
unsigned i, j;
|
|
||||||
+
|
|
||||||
+ /* Harden against out-of-bound writes. */
|
|
||||||
+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
|
|
||||||
+ (grub_add (dy, src->height, &max_y) || max_y > target->height))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
for (i = 0; i < src->height; i++)
|
|
||||||
{
|
|
||||||
src_bit = (src->width * i + src->width - 1) % 8;
|
|
@ -1,36 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Fri, 28 Oct 2022 17:29:16 +0800
|
|
||||||
Subject: [PATCH] font: Assign null_font to glyphs in ascii_font_glyph[]
|
|
||||||
|
|
||||||
The calculations in blit_comb() need information from glyph's font, e.g.
|
|
||||||
grub_font_get_xheight(main_glyph->font). However, main_glyph->font is
|
|
||||||
NULL if main_glyph comes from ascii_font_glyph[]. Therefore
|
|
||||||
grub_font_get_*() crashes because of NULL pointer.
|
|
||||||
|
|
||||||
There is already a solution, the null_font. So, assign it to those glyphs
|
|
||||||
in ascii_font_glyph[].
|
|
||||||
|
|
||||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit dd539d695482069d28b40f2d3821f710cdcf6ee6)
|
|
||||||
(cherry picked from commit 87526376857eaceae474c9797e3cee5b50597332)
|
|
||||||
(cherry picked from commit b4807bbb09d9adf82fe9ae12a3af1c852dc4e32d)
|
|
||||||
---
|
|
||||||
grub-core/font/font.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
|
||||||
index cfa4bd5096..30cd1fe07f 100644
|
|
||||||
--- a/grub-core/font/font.c
|
|
||||||
+++ b/grub-core/font/font.c
|
|
||||||
@@ -137,7 +137,7 @@ ascii_glyph_lookup (grub_uint32_t code)
|
|
||||||
ascii_font_glyph[current]->offset_x = 0;
|
|
||||||
ascii_font_glyph[current]->offset_y = -2;
|
|
||||||
ascii_font_glyph[current]->device_width = 8;
|
|
||||||
- ascii_font_glyph[current]->font = NULL;
|
|
||||||
+ ascii_font_glyph[current]->font = &null_font;
|
|
||||||
|
|
||||||
grub_memcpy (ascii_font_glyph[current]->bitmap,
|
|
||||||
&ascii_bitmaps[current * ASCII_BITMAP_SIZE],
|
|
@ -1,55 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Date: Fri, 28 Oct 2022 21:31:39 +0800
|
|
||||||
Subject: [PATCH] normal/charset: Fix an integer overflow in
|
|
||||||
grub_unicode_aglomerate_comb()
|
|
||||||
|
|
||||||
The out->ncomb is a bit-field of 8 bits. So, the max possible value is 255.
|
|
||||||
However, code in grub_unicode_aglomerate_comb() doesn't check for an
|
|
||||||
overflow when incrementing out->ncomb. If out->ncomb is already 255,
|
|
||||||
after incrementing it will get 0 instead of 256, and cause illegal
|
|
||||||
memory access in subsequent processing.
|
|
||||||
|
|
||||||
This patch introduces GRUB_UNICODE_NCOMB_MAX to represent the max
|
|
||||||
acceptable value of ncomb. The code now checks for this limit and
|
|
||||||
ignores additional combining characters when limit is reached.
|
|
||||||
|
|
||||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
(cherry picked from commit da90d62316a3b105d2fbd7334d6521936bd6dcf6)
|
|
||||||
(cherry picked from commit 26fafec86000b5322837722a115279ef03922ca6)
|
|
||||||
(cherry picked from commit 872fba1c44dee2ab5cb36b2c7a883847f91ed907)
|
|
||||||
---
|
|
||||||
grub-core/normal/charset.c | 3 +++
|
|
||||||
include/grub/unicode.h | 2 ++
|
|
||||||
2 files changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c
|
|
||||||
index 7b2de12001..4849cf06f7 100644
|
|
||||||
--- a/grub-core/normal/charset.c
|
|
||||||
+++ b/grub-core/normal/charset.c
|
|
||||||
@@ -472,6 +472,9 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|
|
||||||
if (!haveout)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
+ if (out->ncomb == GRUB_UNICODE_NCOMB_MAX)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
if (comb_type == GRUB_UNICODE_COMB_MC
|
|
||||||
|| comb_type == GRUB_UNICODE_COMB_ME
|
|
||||||
|| comb_type == GRUB_UNICODE_COMB_MN)
|
|
||||||
diff --git a/include/grub/unicode.h b/include/grub/unicode.h
|
|
||||||
index 4de986a857..c4f6fca043 100644
|
|
||||||
--- a/include/grub/unicode.h
|
|
||||||
+++ b/include/grub/unicode.h
|
|
||||||
@@ -147,7 +147,9 @@ struct grub_unicode_glyph
|
|
||||||
grub_uint8_t bidi_level:6; /* minimum: 6 */
|
|
||||||
enum grub_bidi_type bidi_type:5; /* minimum: :5 */
|
|
||||||
|
|
||||||
+#define GRUB_UNICODE_NCOMB_MAX ((1 << 8) - 1)
|
|
||||||
unsigned ncomb:8;
|
|
||||||
+
|
|
||||||
/* Hint by unicode subsystem how wide this character usually is.
|
|
||||||
Real width is determined by font. Set only in UTF-8 stream. */
|
|
||||||
int estimated_width:8;
|
|
@ -1,227 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lu Ken <ken.lu@intel.com>
|
|
||||||
Date: Sat, 3 Jul 2021 10:50:37 -0400
|
|
||||||
Subject: [PATCH] Enable TDX measurement to RTMR register
|
|
||||||
|
|
||||||
Intel Trust Domain Extensions(Intel TDX) refers to an Intel technology
|
|
||||||
that extends Virtual Machine Extensions(VMX) and Multi-Key Total Memory
|
|
||||||
Encryption(MK-TME) with a new kind of virtual machine guest called a
|
|
||||||
Trust Domain(TD)[1]. A TD runs in a CPU mode that protects the confidentiality
|
|
||||||
of its memory contents and its CPU state from any other software, including
|
|
||||||
the hosting Virtual Machine Monitor (VMM).
|
|
||||||
|
|
||||||
Trust Domain Virtual Firmware (TDVF) is required to provide TD services to
|
|
||||||
the TD guest OS.[2] Its reference code is available at https://github.com/tianocore/edk2-staging/tree/TDVF.
|
|
||||||
|
|
||||||
To support TD measurement/attestation, TDs provide 4 RTMR registers like
|
|
||||||
TPM/TPM2 PCR as below:
|
|
||||||
- RTMR[0] is for TDVF configuration
|
|
||||||
- RTMR[1] is for the TD OS loader and kernel
|
|
||||||
- RTMR[2] is for the OS application
|
|
||||||
- RTMR[3] is reserved for special usage only
|
|
||||||
|
|
||||||
This patch adds TD Measurement protocol support along with TPM/TPM2 protocol.
|
|
||||||
|
|
||||||
References:
|
|
||||||
[1] https://software.intel.com/content/dam/develop/external/us/en/documents/tdx-whitepaper-v4.pdf
|
|
||||||
[2] https://software.intel.com/content/dam/develop/external/us/en/documents/tdx-virtual-firmware-design-guide-rev-1.pdf
|
|
||||||
|
|
||||||
Signed-off-by: Lu Ken <ken.lu@intel.com>
|
|
||||||
(cherry picked from commit 841a0977397cf12a5498d439b8aaf8bf28ff8544)
|
|
||||||
---
|
|
||||||
grub-core/Makefile.core.def | 1 +
|
|
||||||
grub-core/kern/efi/tdx.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
grub-core/kern/tpm.c | 4 +++
|
|
||||||
include/grub/efi/tdx.h | 26 +++++++++++++++++
|
|
||||||
include/grub/tdx.h | 36 +++++++++++++++++++++++
|
|
||||||
5 files changed, 137 insertions(+)
|
|
||||||
create mode 100644 grub-core/kern/efi/tdx.c
|
|
||||||
create mode 100644 include/grub/efi/tdx.h
|
|
||||||
create mode 100644 include/grub/tdx.h
|
|
||||||
|
|
||||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
|
||||||
index 637d7203e3..2787d59c52 100644
|
|
||||||
--- a/grub-core/Makefile.core.def
|
|
||||||
+++ b/grub-core/Makefile.core.def
|
|
||||||
@@ -200,6 +200,7 @@ kernel = {
|
|
||||||
efi = kern/efi/acpi.c;
|
|
||||||
efi = kern/lockdown.c;
|
|
||||||
efi = lib/envblk.c;
|
|
||||||
+ efi = kern/efi/tdx.c;
|
|
||||||
efi = kern/efi/tpm.c;
|
|
||||||
i386_coreboot = kern/i386/pc/acpi.c;
|
|
||||||
i386_multiboot = kern/i386/pc/acpi.c;
|
|
||||||
diff --git a/grub-core/kern/efi/tdx.c b/grub-core/kern/efi/tdx.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000..3a49f8d117
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/grub-core/kern/efi/tdx.c
|
|
||||||
@@ -0,0 +1,70 @@
|
|
||||||
+#include <grub/err.h>
|
|
||||||
+#include <grub/i18n.h>
|
|
||||||
+#include <grub/efi/api.h>
|
|
||||||
+#include <grub/efi/efi.h>
|
|
||||||
+#include <grub/efi/tpm.h>
|
|
||||||
+#include <grub/efi/tdx.h>
|
|
||||||
+#include <grub/mm.h>
|
|
||||||
+#include <grub/tpm.h>
|
|
||||||
+#include <grub/tdx.h>
|
|
||||||
+
|
|
||||||
+static grub_efi_guid_t tdx_guid = EFI_TDX_GUID;
|
|
||||||
+
|
|
||||||
+static inline grub_err_t grub_tdx_dprintf(grub_efi_status_t status)
|
|
||||||
+{
|
|
||||||
+ switch (status) {
|
|
||||||
+ case GRUB_EFI_SUCCESS:
|
|
||||||
+ return 0;
|
|
||||||
+ case GRUB_EFI_DEVICE_ERROR:
|
|
||||||
+ grub_dprintf ("tdx", "Command failed: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
|
||||||
+ status);
|
|
||||||
+ return GRUB_ERR_IO;
|
|
||||||
+ case GRUB_EFI_INVALID_PARAMETER:
|
|
||||||
+ grub_dprintf ("tdx", "Invalid parameter: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
|
||||||
+ status);
|
|
||||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
|
||||||
+ case GRUB_EFI_VOLUME_FULL:
|
|
||||||
+ grub_dprintf ("tdx", "Volume is full: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
|
||||||
+ status);
|
|
||||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
|
||||||
+ case GRUB_EFI_UNSUPPORTED:
|
|
||||||
+ grub_dprintf ("tdx", "TDX unavailable: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
|
||||||
+ status);
|
|
||||||
+ return GRUB_ERR_UNKNOWN_DEVICE;
|
|
||||||
+ default:
|
|
||||||
+ grub_dprintf ("tdx", "Unknown TDX error: 0x%"PRIxGRUB_EFI_STATUS"\n",
|
|
||||||
+ status);
|
|
||||||
+ return GRUB_ERR_UNKNOWN_DEVICE;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+grub_err_t
|
|
||||||
+grub_tdx_log_event(unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
|
||||||
+ const char *description)
|
|
||||||
+{
|
|
||||||
+ EFI_TCG2_EVENT *event;
|
|
||||||
+ grub_efi_status_t status;
|
|
||||||
+ grub_efi_tdx_protocol_t *tdx;
|
|
||||||
+
|
|
||||||
+ tdx = grub_efi_locate_protocol (&tdx_guid, NULL);
|
|
||||||
+
|
|
||||||
+ if (!tdx)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ event = grub_zalloc(sizeof (EFI_TCG2_EVENT) + grub_strlen(description) + 1);
|
|
||||||
+ if (!event)
|
|
||||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
|
||||||
+ N_("cannot allocate TCG2 event buffer"));
|
|
||||||
+
|
|
||||||
+ event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
|
|
||||||
+ event->Header.HeaderVersion = 1;
|
|
||||||
+ event->Header.PCRIndex = pcr;
|
|
||||||
+ event->Header.EventType = EV_IPL;
|
|
||||||
+ event->Size = sizeof(*event) - sizeof(event->Event) + grub_strlen(description) + 1;
|
|
||||||
+ grub_memcpy(event->Event, description, grub_strlen(description) + 1);
|
|
||||||
+
|
|
||||||
+ status = efi_call_5 (tdx->hash_log_extend_event, tdx, 0, (unsigned long) buf,
|
|
||||||
+ (grub_uint64_t) size, event);
|
|
||||||
+
|
|
||||||
+ return grub_tdx_dprintf(status);
|
|
||||||
+}
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/grub-core/kern/tpm.c b/grub-core/kern/tpm.c
|
|
||||||
index e5e8fced62..71cc4252c1 100644
|
|
||||||
--- a/grub-core/kern/tpm.c
|
|
||||||
+++ b/grub-core/kern/tpm.c
|
|
||||||
@@ -4,6 +4,7 @@
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/tpm.h>
|
|
||||||
#include <grub/term.h>
|
|
||||||
+#include <grub/tdx.h>
|
|
||||||
|
|
||||||
grub_err_t
|
|
||||||
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
|
||||||
@@ -13,6 +14,9 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
|
||||||
char *desc = grub_xasprintf("%s %s", kind, description);
|
|
||||||
if (!desc)
|
|
||||||
return GRUB_ERR_OUT_OF_MEMORY;
|
|
||||||
+
|
|
||||||
+ grub_tdx_log_event(buf, size, pcr, desc);
|
|
||||||
+
|
|
||||||
ret = grub_tpm_log_event(buf, size, pcr, desc);
|
|
||||||
grub_free(desc);
|
|
||||||
return ret;
|
|
||||||
diff --git a/include/grub/efi/tdx.h b/include/grub/efi/tdx.h
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000..9bdac2a275
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/grub/efi/tdx.h
|
|
||||||
@@ -0,0 +1,26 @@
|
|
||||||
+/*
|
|
||||||
+ * GRUB -- GRand Unified Bootloader
|
|
||||||
+ * Copyright (C) 2015 Free Software Foundation, Inc.
|
|
||||||
+ *
|
|
||||||
+ * GRUB is free software: you can redistribute it and/or modify
|
|
||||||
+ * it under the terms of the GNU General Public License as published by
|
|
||||||
+ * the Free Software Foundation, either version 3 of the License, or
|
|
||||||
+ * (at your option) any later version.
|
|
||||||
+ *
|
|
||||||
+ * GRUB is distributed in the hope that it will be useful,
|
|
||||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
+ * GNU General Public License for more details.
|
|
||||||
+ *
|
|
||||||
+ * You should have received a copy of the GNU General Public License
|
|
||||||
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef GRUB_EFI_TDX_HEADER
|
|
||||||
+#define GRUB_EFI_TDX_HEADER 1
|
|
||||||
+
|
|
||||||
+#define EFI_TDX_GUID {0x96751a3d, 0x72f4, 0x41a6, {0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b}};
|
|
||||||
+
|
|
||||||
+typedef grub_efi_tpm2_protocol_t grub_efi_tdx_protocol_t;
|
|
||||||
+
|
|
||||||
+#endif
|
|
||||||
\ No newline at end of file
|
|
||||||
diff --git a/include/grub/tdx.h b/include/grub/tdx.h
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000..4a98008e39
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/grub/tdx.h
|
|
||||||
@@ -0,0 +1,36 @@
|
|
||||||
+/*
|
|
||||||
+ * GRUB -- GRand Unified Bootloader
|
|
||||||
+ * Copyright (C) 2015 Free Software Foundation, Inc.
|
|
||||||
+ *
|
|
||||||
+ * GRUB is free software: you can redistribute it and/or modify
|
|
||||||
+ * it under the terms of the GNU General Public License as published by
|
|
||||||
+ * the Free Software Foundation, either version 3 of the License, or
|
|
||||||
+ * (at your option) any later version.
|
|
||||||
+ *
|
|
||||||
+ * GRUB is distributed in the hope that it will be useful,
|
|
||||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
+ * GNU General Public License for more details.
|
|
||||||
+ *
|
|
||||||
+ * You should have received a copy of the GNU General Public License
|
|
||||||
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#ifndef GRUB_TDX_HEADER
|
|
||||||
+#define GRUB_TDX_HEADER 1
|
|
||||||
+
|
|
||||||
+#if defined (GRUB_MACHINE_EFI)
|
|
||||||
+grub_err_t grub_tdx_log_event(unsigned char *buf, grub_size_t size,
|
|
||||||
+ grub_uint8_t pcr, const char *description);
|
|
||||||
+#else
|
|
||||||
+static inline grub_err_t grub_tdx_log_event(
|
|
||||||
+ unsigned char *buf __attribute__ ((unused)),
|
|
||||||
+ grub_size_t size __attribute__ ((unused)),
|
|
||||||
+ grub_uint8_t pcr __attribute__ ((unused)),
|
|
||||||
+ const char *description __attribute__ ((unused)))
|
|
||||||
+{
|
|
||||||
+ return 0;
|
|
||||||
+};
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#endif
|
|
@ -1,28 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Avnish Chouhan <avnish@linux.vnet.ibm.com>
|
|
||||||
Date: Tue, 24 Jan 2023 08:01:47 -0500
|
|
||||||
Subject: [PATCH] Enable shared processor mode in vector 5
|
|
||||||
|
|
||||||
This patch is to update the vector 5 which is troubling some
|
|
||||||
machines to bootup properly in shared processor mode.
|
|
||||||
|
|
||||||
Signed-off-by: Avnish Chouhan <avnish@linux.vnet.ibm.com>
|
|
||||||
(cherry picked from commit 30d2ee836649386a336f9437c8a149c8e642a46b)
|
|
||||||
(cherry picked from commit 7e309d139c5eca1f03659e612a14499213e79c95)
|
|
||||||
---
|
|
||||||
grub-core/kern/ieee1275/init.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
|
||||||
index 37f3098c39..3ea9b73b2a 100644
|
|
||||||
--- a/grub-core/kern/ieee1275/init.c
|
|
||||||
+++ b/grub-core/kern/ieee1275/init.c
|
|
||||||
@@ -372,7 +372,7 @@ grub_ieee1275_ibm_cas (void)
|
|
||||||
.vec4 = 0x0001, // set required minimum capacity % to the lowest value
|
|
||||||
.vec5_size = 1 + sizeof(struct option_vector5) - 2,
|
|
||||||
.vec5 = {
|
|
||||||
- 0, 0, 0, 0, 0, 0, 0, 0, 256
|
|
||||||
+ 0, 192, 0, 128, 0, 0, 0, 0, 256
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Matt Hsiao <matt.hsiao@hpe.com>
|
|
||||||
Date: Mon, 24 Apr 2023 13:39:05 +0800
|
|
||||||
Subject: [PATCH] efi/http: change uint32_t to uintn_t for
|
|
||||||
grub_efi_http_message_t
|
|
||||||
|
|
||||||
Modify UINT32 to UINTN in EFI_HTTP_MESSAGE to be UEFI 2.9 compliant.
|
|
||||||
|
|
||||||
Signed-off-by: Matt Hsiao <matt.hsiao@hpe.com>
|
|
||||||
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
|
|
||||||
---
|
|
||||||
include/grub/efi/http.h | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/grub/efi/http.h b/include/grub/efi/http.h
|
|
||||||
index c5e9a89f5050..ad164ba1913d 100644
|
|
||||||
--- a/include/grub/efi/http.h
|
|
||||||
+++ b/include/grub/efi/http.h
|
|
||||||
@@ -171,9 +171,9 @@ typedef struct {
|
|
||||||
grub_efi_http_request_data_t *request;
|
|
||||||
grub_efi_http_response_data_t *response;
|
|
||||||
} data;
|
|
||||||
- grub_efi_uint32_t header_count;
|
|
||||||
+ grub_efi_uintn_t header_count;
|
|
||||||
grub_efi_http_header_t *headers;
|
|
||||||
- grub_efi_uint32_t body_length;
|
|
||||||
+ grub_efi_uintn_t body_length;
|
|
||||||
void *body;
|
|
||||||
} grub_efi_http_message_t;
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Avnish Chouhan <avnish@linux.vnet.ibm.com>
|
|
||||||
Date: Thu, 23 Mar 2023 08:16:25 -0400
|
|
||||||
Subject: [PATCH] ieee1275 : Converting plain numbers to constants in Vec5
|
|
||||||
|
|
||||||
This patch converts the plain numbers used in Vec5 properties to
|
|
||||||
constants.
|
|
||||||
|
|
||||||
1. LPAR : Client program supports logical partitioning and
|
|
||||||
associated hcall()s.
|
|
||||||
2. SPLPAR : Client program supports the Shared
|
|
||||||
Processor LPAR Option.
|
|
||||||
3. CMO : Enables the Cooperative Memory Over-commitment Option.
|
|
||||||
4. MAX_CPU : Defines maximum number of CPUs supported.
|
|
||||||
|
|
||||||
Signed-off-by: Avnish Chouhan <avnish@linux.vnet.ibm.com>
|
|
||||||
---
|
|
||||||
grub-core/kern/ieee1275/init.c | 8 +++++++-
|
|
||||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
|
||||||
index 3ea9b73b2a59..2516e02091cb 100644
|
|
||||||
--- a/grub-core/kern/ieee1275/init.c
|
|
||||||
+++ b/grub-core/kern/ieee1275/init.c
|
|
||||||
@@ -56,6 +56,12 @@ extern char _end[];
|
|
||||||
grub_addr_t grub_ieee1275_original_stack;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#define LPAR 0x80
|
|
||||||
+#define SPLPAR 0x40
|
|
||||||
+#define BYTE2 (LPAR | SPLPAR)
|
|
||||||
+#define CMO 0x80
|
|
||||||
+#define MAX_CPU 256
|
|
||||||
+
|
|
||||||
void
|
|
||||||
grub_exit (int rc __attribute__((unused)))
|
|
||||||
{
|
|
||||||
@@ -372,7 +378,7 @@ grub_ieee1275_ibm_cas (void)
|
|
||||||
.vec4 = 0x0001, // set required minimum capacity % to the lowest value
|
|
||||||
.vec5_size = 1 + sizeof(struct option_vector5) - 2,
|
|
||||||
.vec5 = {
|
|
||||||
- 0, 192, 0, 128, 0, 0, 0, 0, 256
|
|
||||||
+ 0, BYTE2, 0, CMO, 0, 0, 0, 0, MAX_CPU
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Avnish Chouhan <avnish@linux.vnet.ibm.com>
|
|
||||||
Date: Thu, 23 Mar 2023 08:33:12 -0400
|
|
||||||
Subject: [PATCH] ieee1275 : extended support in options vector5
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
This patch enables the multiple options in Options Vector5 which are
|
|
||||||
required and solves the boot issue seen on some machines which are looking for these specific options.
|
|
||||||
|
|
||||||
1. LPAR : Client program supports logical partitioning and
|
|
||||||
associated hcall()s.
|
|
||||||
2. SPLPAR : Client program supports the Shared
|
|
||||||
Processor LPAR Option.
|
|
||||||
3. DYN_RCON_MEM : Client program supports the
|
|
||||||
“ibm,dynamic-reconfiguration-memory” property and it may be
|
|
||||||
presented in the device tree.
|
|
||||||
4. LARGE_PAGES : Client supports pages larger than 4 KB.
|
|
||||||
5. DONATE_DCPU_CLS : Client supports donating dedicated processor cycles.
|
|
||||||
6. PCI_EXP : Client supports PCI Express implementations
|
|
||||||
utilizing Message Signaled Interrupts (MSIs).
|
|
||||||
|
|
||||||
7. CMOC : Enables the Cooperative Memory Over-commitment Option.
|
|
||||||
8. EXT_CMO : Enables the Extended Cooperative Memory Over-commit
|
|
||||||
Option.
|
|
||||||
|
|
||||||
9. ASSOC_REF : Enables “ibm,associativity” and
|
|
||||||
“ibm,associativity-reference-points” properties.
|
|
||||||
10. AFFINITY : Enables Platform Resource Reassignment Notification.
|
|
||||||
11. NUMA : Supports NUMA Distance Lookup Table Option.
|
|
||||||
|
|
||||||
12. HOTPLUG_INTRPT : Supports Hotplug Interrupts.
|
|
||||||
13. HPT_RESIZE : Enable Hash Page Table Resize Option.
|
|
||||||
|
|
||||||
14. MAX_CPU : Defines maximum number of CPUs supported.
|
|
||||||
|
|
||||||
15. PFO_HWRNG : Supports Random Number Generator.
|
|
||||||
16. PFO_HW_COMP : Supports Compression Engine.
|
|
||||||
17. PFO_ENCRYPT : Supports Encryption Engine.
|
|
||||||
|
|
||||||
18. SUB_PROCESSORS : Supports Sub-Processors.
|
|
||||||
|
|
||||||
19. DY_MEM_V2 : Client program supports the “ibm,dynamic-memory-v2” property in the
|
|
||||||
“ibm,dynamic-reconfiguration-memory” node and it may be presented in the device tree.
|
|
||||||
20. DRC_INFO : Client program supports the “ibm,drc-info” property definition and it may be
|
|
||||||
presented in the device tree.
|
|
||||||
|
|
||||||
Signed-off-by: Avnish Chouhan <avnish@linux.vnet.ibm.com>
|
|
||||||
---
|
|
||||||
grub-core/kern/ieee1275/init.c | 47 ++++++++++++++++++++++++++++++++++++------
|
|
||||||
1 file changed, 41 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
|
||||||
index 2516e02091cb..1fae84440403 100644
|
|
||||||
--- a/grub-core/kern/ieee1275/init.c
|
|
||||||
+++ b/grub-core/kern/ieee1275/init.c
|
|
||||||
@@ -56,11 +56,41 @@ extern char _end[];
|
|
||||||
grub_addr_t grub_ieee1275_original_stack;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-#define LPAR 0x80
|
|
||||||
-#define SPLPAR 0x40
|
|
||||||
-#define BYTE2 (LPAR | SPLPAR)
|
|
||||||
-#define CMO 0x80
|
|
||||||
-#define MAX_CPU 256
|
|
||||||
+/* Options vector5 properties */
|
|
||||||
+
|
|
||||||
+#define LPAR 0x80
|
|
||||||
+#define SPLPAR 0x40
|
|
||||||
+#define DYN_RCON_MEM 0x20
|
|
||||||
+#define LARGE_PAGES 0x10
|
|
||||||
+#define DONATE_DCPU_CLS 0x02
|
|
||||||
+#define PCI_EXP 0x01
|
|
||||||
+#define BYTE2 (LPAR | SPLPAR | DYN_RCON_MEM | LARGE_PAGES | DONATE_DCPU_CLS | PCI_EXP)
|
|
||||||
+
|
|
||||||
+#define CMOC 0x80
|
|
||||||
+#define EXT_CMO 0x40
|
|
||||||
+#define CMO (CMOC | EXT_CMO)
|
|
||||||
+
|
|
||||||
+#define ASSOC_REF 0x80
|
|
||||||
+#define AFFINITY 0x40
|
|
||||||
+#define NUMA 0x20
|
|
||||||
+#define ASSOCIATIVITY (ASSOC_REF | AFFINITY | NUMA)
|
|
||||||
+
|
|
||||||
+#define HOTPLUG_INTRPT 0x04
|
|
||||||
+#define HPT_RESIZE 0x01
|
|
||||||
+#define BIN_OPTS (HOTPLUG_INTRPT | HPT_RESIZE)
|
|
||||||
+
|
|
||||||
+#define MAX_CPU 256
|
|
||||||
+
|
|
||||||
+#define PFO_HWRNG 0x80000000
|
|
||||||
+#define PFO_HW_COMP 0x40000000
|
|
||||||
+#define PFO_ENCRYPT 0x20000000
|
|
||||||
+#define PLATFORM_FACILITIES (PFO_HWRNG | PFO_HW_COMP | PFO_ENCRYPT)
|
|
||||||
+
|
|
||||||
+#define SUB_PROCESSORS 1
|
|
||||||
+
|
|
||||||
+#define DY_MEM_V2 0x80
|
|
||||||
+#define DRC_INFO 0x40
|
|
||||||
+#define BYTE22 (DY_MEM_V2 | DRC_INFO)
|
|
||||||
|
|
||||||
void
|
|
||||||
grub_exit (int rc __attribute__((unused)))
|
|
||||||
@@ -323,6 +353,11 @@ struct option_vector5 {
|
|
||||||
grub_uint8_t micro_checkpoint;
|
|
||||||
grub_uint8_t reserved0;
|
|
||||||
grub_uint32_t max_cpus;
|
|
||||||
+ grub_uint16_t base_PAPR;
|
|
||||||
+ grub_uint16_t mem_reference;
|
|
||||||
+ grub_uint32_t platform_facilities;
|
|
||||||
+ grub_uint8_t sub_processors;
|
|
||||||
+ grub_uint8_t byte22;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct pvr_entry {
|
|
||||||
@@ -378,7 +413,7 @@ grub_ieee1275_ibm_cas (void)
|
|
||||||
.vec4 = 0x0001, // set required minimum capacity % to the lowest value
|
|
||||||
.vec5_size = 1 + sizeof(struct option_vector5) - 2,
|
|
||||||
.vec5 = {
|
|
||||||
- 0, BYTE2, 0, CMO, 0, 0, 0, 0, MAX_CPU
|
|
||||||
+ 0, BYTE2, 0, CMO, ASSOCIATIVITY, BIN_OPTS, 0, 0, MAX_CPU, 0, 0, PLATFORM_FACILITIES, SUB_PROCESSORS, BYTE22
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
|||||||
From 8c74431327e0c7d7fe47462b0e69fcbe3bbac56e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Marta Lewandowska <mlewando@redhat.com>
|
|
||||||
Date: Fri, 24 Mar 2023 09:14:29 -0400
|
|
||||||
Subject: [PATCH] Regenerate kernelopts if missing on ppc
|
|
||||||
|
|
||||||
Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
|
|
||||||
---
|
|
||||||
util/grub.d/10_linux_bls.in | 12 ++++++++++++
|
|
||||||
1 file changed, 12 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/util/grub.d/10_linux_bls.in b/util/grub.d/10_linux_bls.in
|
|
||||||
index 855dbdd..f2281bc 100644
|
|
||||||
--- a/util/grub.d/10_linux_bls.in
|
|
||||||
+++ b/util/grub.d/10_linux_bls.in
|
|
||||||
@@ -117,6 +117,18 @@ cat <<EOF
|
|
||||||
# This section was generated by a script. Do not modify the generated file - all changes
|
|
||||||
# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
|
|
||||||
|
|
||||||
+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu
|
|
||||||
+# entries populated from BootLoaderSpec files that use this variable work correctly even
|
|
||||||
+# without a grubenv file, define a fallback kernelopts variable if this has not been set.
|
|
||||||
+#
|
|
||||||
+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by
|
|
||||||
+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX
|
|
||||||
+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both
|
|
||||||
+# the kernelopts variable in the grubenv file and the fallback kernelopts variable.
|
|
||||||
+if [ -z "\${kernelopts}" ]; then
|
|
||||||
+ set kernelopts="root=${linux_root_device_thisversion} ro ${args}"
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.39.1
|
|
||||||
|
|
@ -1,210 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
|
||||||
Date: Tue, 8 Aug 2023 12:21:55 -0400
|
|
||||||
Subject: [PATCH] kern/ieee1275/init: ppc64: Restrict high memory in presence
|
|
||||||
of fadump
|
|
||||||
|
|
||||||
This is a backport of the patch with the same name to grub 2.02.
|
|
||||||
|
|
||||||
When a kernel dump is present then restrict the high memory regions to
|
|
||||||
avoid allocating memory where the kernel dump resides. Use the
|
|
||||||
ibm,kernel-dump node under /rtas to determine whether a kernel dump exists
|
|
||||||
and up to which limit grub can use available memory. Set the
|
|
||||||
upper_mem_limit to the size of the kernel dump section of type
|
|
||||||
'REAL_MODE_REGION' and therefore only allow grub's memory usage for high
|
|
||||||
addresses from 768MB to 'upper_mem_limit'. This means that grub can
|
|
||||||
use high memory in the range of 768MB to upper_mem_limit and
|
|
||||||
the kernel-dump memory regions above 'upper_mem_limit' remain untouched.
|
|
||||||
This change has no effect on memory allocations below 640MB.
|
|
||||||
|
|
||||||
Also, fall back to allocating below 640MB in case the chunk of
|
|
||||||
memory there would be larger than the chunk of memory above 768MB.
|
|
||||||
This can for example occur if a free memory area is found starting at 300MB
|
|
||||||
extending up to 1GB but a kernel dump is located at 768MB and therefore
|
|
||||||
does not allow the allocation of the high memory area but requiring to use
|
|
||||||
the chunk starting at 300MB to avoid an unnecessary out-of-memory
|
|
||||||
condition.
|
|
||||||
|
|
||||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
|
||||||
Cc: Hari Bathini <hbathini@linux.ibm.com>
|
|
||||||
Cc: Pavithra Prakash <pavrampu@in.ibm.com>
|
|
||||||
Cc: Michael Ellerman <mpe@ellerman.id.au>
|
|
||||||
Cc: Carolyn Scherrer <cpscherr@us.ibm.com>
|
|
||||||
Cc: Mahesh Salgaonkar <mahesh@linux.ibm.com>
|
|
||||||
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
|
|
||||||
---
|
|
||||||
grub-core/kern/ieee1275/init.c | 139 +++++++++++++++++++++++++++++++++++++++++
|
|
||||||
1 file changed, 139 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
|
||||||
index 1fae84440403..31843ab70a62 100644
|
|
||||||
--- a/grub-core/kern/ieee1275/init.c
|
|
||||||
+++ b/grub-core/kern/ieee1275/init.c
|
|
||||||
@@ -17,6 +17,8 @@
|
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
+#include <stddef.h> /* offsetof() */
|
|
||||||
+
|
|
||||||
#include <grub/kernel.h>
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/disk.h>
|
|
||||||
@@ -180,6 +182,97 @@ grub_claim_heap (void)
|
|
||||||
+ GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
+
|
|
||||||
+/* ibm,kernel-dump data structures */
|
|
||||||
+struct kd_section
|
|
||||||
+{
|
|
||||||
+ grub_uint32_t flags;
|
|
||||||
+ grub_uint16_t src_datatype;
|
|
||||||
+#define KD_SRC_DATATYPE_REAL_MODE_REGION 0x0011
|
|
||||||
+ grub_uint16_t error_flags;
|
|
||||||
+ grub_uint64_t src_address;
|
|
||||||
+ grub_uint64_t num_bytes;
|
|
||||||
+ grub_uint64_t act_bytes;
|
|
||||||
+ grub_uint64_t dst_address;
|
|
||||||
+} GRUB_PACKED;
|
|
||||||
+
|
|
||||||
+#define MAX_KD_SECTIONS 10
|
|
||||||
+
|
|
||||||
+struct kernel_dump
|
|
||||||
+{
|
|
||||||
+ grub_uint32_t format;
|
|
||||||
+ grub_uint16_t num_sections;
|
|
||||||
+ grub_uint16_t status_flags;
|
|
||||||
+ grub_uint32_t offset_1st_section;
|
|
||||||
+ grub_uint32_t num_blocks;
|
|
||||||
+ grub_uint64_t start_block;
|
|
||||||
+ grub_uint64_t num_blocks_avail;
|
|
||||||
+ grub_uint32_t offet_path_string;
|
|
||||||
+ grub_uint32_t max_time_allowed;
|
|
||||||
+ struct kd_section kds[MAX_KD_SECTIONS]; /* offset_1st_section should point to kds[0] */
|
|
||||||
+} GRUB_PACKED;
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Determine if a kernel dump exists and if it does, then determine the highest
|
|
||||||
+ * address that grub can use for memory allocations.
|
|
||||||
+ * The caller must have initialized *highest to ~0. *highest will not
|
|
||||||
+ * be modified if no kernel dump is found.
|
|
||||||
+ */
|
|
||||||
+static int
|
|
||||||
+check_kernel_dump (grub_uint64_t *highest)
|
|
||||||
+{
|
|
||||||
+ struct kernel_dump kernel_dump;
|
|
||||||
+ grub_ssize_t kernel_dump_size;
|
|
||||||
+ grub_ieee1275_phandle_t rtas;
|
|
||||||
+ struct kd_section *kds;
|
|
||||||
+ grub_size_t i;
|
|
||||||
+
|
|
||||||
+ /* If there's a kernel-dump it must have at least one section */
|
|
||||||
+ if (grub_ieee1275_finddevice ("/rtas", &rtas) ||
|
|
||||||
+ grub_ieee1275_get_property (rtas, "ibm,kernel-dump", &kernel_dump,
|
|
||||||
+ sizeof (kernel_dump), &kernel_dump_size) ||
|
|
||||||
+ kernel_dump_size <= (grub_ssize_t) offsetof (struct kernel_dump, kds[1]))
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ kernel_dump_size = grub_min (kernel_dump_size, (grub_ssize_t) sizeof (kernel_dump));
|
|
||||||
+
|
|
||||||
+ if (grub_be_to_cpu32 (kernel_dump.format) != 1)
|
|
||||||
+ {
|
|
||||||
+ grub_printf (_("Error: ibm,kernel-dump has an unexpected format version '%u'\n"),
|
|
||||||
+ grub_be_to_cpu32 (kernel_dump.format));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (grub_be_to_cpu16 (kernel_dump.num_sections) > MAX_KD_SECTIONS)
|
|
||||||
+ {
|
|
||||||
+ grub_printf (_("Error: Too many kernel dump sections: %d\n"),
|
|
||||||
+ grub_be_to_cpu32 (kernel_dump.num_sections));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < grub_be_to_cpu16 (kernel_dump.num_sections); i++)
|
|
||||||
+ {
|
|
||||||
+ kds = (struct kd_section *) ((grub_addr_t) &kernel_dump +
|
|
||||||
+ grub_be_to_cpu32 (kernel_dump.offset_1st_section) +
|
|
||||||
+ i * sizeof (struct kd_section));
|
|
||||||
+ /* sanity check the address is within the 'kernel_dump' struct */
|
|
||||||
+ if ((grub_addr_t) kds > (grub_addr_t) &kernel_dump + kernel_dump_size + sizeof (*kds))
|
|
||||||
+ {
|
|
||||||
+ grub_printf (_("Error: 'kds' address beyond last available section\n"));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if ((grub_be_to_cpu16 (kds->src_datatype) == KD_SRC_DATATYPE_REAL_MODE_REGION) &&
|
|
||||||
+ (grub_be_to_cpu64 (kds->src_address) == 0))
|
|
||||||
+ {
|
|
||||||
+ *highest = grub_min (*highest, grub_be_to_cpu64 (kds->num_bytes));
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* Helper for grub_claim_heap on powerpc. */
|
|
||||||
static int
|
|
||||||
heap_size (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
|
|
||||||
@@ -207,7 +300,9 @@ static int
|
|
||||||
heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
+ grub_uint64_t upper_mem_limit = ~0;
|
|
||||||
grub_uint32_t total = *(grub_uint32_t *)data;
|
|
||||||
+ int has_kernel_dump;
|
|
||||||
|
|
||||||
if (type != GRUB_MEMORY_AVAILABLE)
|
|
||||||
return 0;
|
|
||||||
@@ -243,6 +338,50 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ has_kernel_dump = check_kernel_dump (&upper_mem_limit);
|
|
||||||
+ if (has_kernel_dump)
|
|
||||||
+ {
|
|
||||||
+ grub_uint64_t lo_len = 0, hi_len = 0;
|
|
||||||
+
|
|
||||||
+ if (addr > upper_mem_limit || upper_mem_limit == (grub_uint64_t)~0)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ /* limit len to stay below upper_mem_limit */
|
|
||||||
+ if (addr < upper_mem_limit && (addr + len) > upper_mem_limit)
|
|
||||||
+ {
|
|
||||||
+ len = grub_min (len, upper_mem_limit - addr);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* We can allocate below 640MB or above 768MB.
|
|
||||||
+ * Choose the bigger chunk below 640MB or above 768MB.
|
|
||||||
+ */
|
|
||||||
+ if (addr < 0x28000000)
|
|
||||||
+ {
|
|
||||||
+ lo_len = grub_min (len, 0x28000000 - addr);
|
|
||||||
+ }
|
|
||||||
+ if (addr + len > 0x30000000)
|
|
||||||
+ {
|
|
||||||
+ if (addr < 0x30000000)
|
|
||||||
+ hi_len = len - (0x30000000 - addr);
|
|
||||||
+ else
|
|
||||||
+ hi_len = len;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (hi_len > lo_len)
|
|
||||||
+ {
|
|
||||||
+ len = hi_len;
|
|
||||||
+ if (addr < 0x30000000)
|
|
||||||
+ addr = 0x30000000;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ len = lo_len;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (len == 0)
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* If this block contains 0x30000000 (768MB), do not claim below that.
|
|
||||||
Linux likes to claim memory at min(RMO top, 768MB) and works down
|
|
||||||
without reference to /memory/available. */
|
|
@ -1,34 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nicolas Frayer <nfrayer@redhat.com>
|
|
||||||
Date: Wed, 24 May 2023 11:22:47 +0200
|
|
||||||
Subject: [PATCH] util: Enable default kernel for updates
|
|
||||||
|
|
||||||
Several kernel variants can be installed on a system in parallel.
|
|
||||||
In order to allow the user to choose which kernel will be set to
|
|
||||||
default after an update, re-enable grub's usage of DEFAULTKERNEL as
|
|
||||||
set in /etc/sysconfig/kernel
|
|
||||||
|
|
||||||
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
|
|
||||||
---
|
|
||||||
util/grub-get-kernel-settings.in | 8 ++++++++
|
|
||||||
1 file changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/util/grub-get-kernel-settings.in b/util/grub-get-kernel-settings.in
|
|
||||||
index 7e87dfccc0e4..f71bc64360b0 100644
|
|
||||||
--- a/util/grub-get-kernel-settings.in
|
|
||||||
+++ b/util/grub-get-kernel-settings.in
|
|
||||||
@@ -68,6 +68,14 @@ if test -f /etc/sysconfig/kernel ; then
|
|
||||||
. /etc/sysconfig/kernel
|
|
||||||
fi
|
|
||||||
|
|
||||||
+GRUB_DEFAULT_KERNEL_TYPE=${DEFAULTKERNEL/-core/}
|
|
||||||
+if [ "$GRUB_DEFAULT_KERNEL_TYPE" != "kernel" ]; then
|
|
||||||
+ echo GRUB_NON_STANDARD_KERNEL=true
|
|
||||||
+ echo export GRUB_NON_STANDARD_KERNEL
|
|
||||||
+ GRUB_DEFAULT_KERNEL_TYPE=${GRUB_DEFAULT_KERNEL_TYPE/kernel-/}
|
|
||||||
+fi
|
|
||||||
+echo GRUB_DEFAULT_KERNEL_TYPE=$GRUB_DEFAULT_KERNEL_TYPE
|
|
||||||
+echo export GRUB_DEFAULT_KERNEL_TYPE
|
|
||||||
if [ "$MAKEDEBUG" = "yes" ]; then
|
|
||||||
echo GRUB_LINUX_MAKE_DEBUG=true
|
|
||||||
echo export GRUB_LINUX_MAKE_DEBUG
|
|
@ -1,150 +0,0 @@
|
|||||||
From 9ca4c3fe1c7dbd62e8ad6a23cb1b1fda695fdb44 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Solar Designer <solar@openwall.com>
|
|
||||||
Date: Tue, 6 Feb 2024 21:39:41 +0100
|
|
||||||
Subject: [PATCH 1/3] grub-set-bootflag: Conservative partial fix for
|
|
||||||
CVE-2024-1048
|
|
||||||
|
|
||||||
Following up on CVE-2019-14865 and taking a fresh look at
|
|
||||||
grub2-set-bootflag now (through my work at CIQ on Rocky Linux), I saw some
|
|
||||||
other ways in which users could still abuse this little program:
|
|
||||||
|
|
||||||
1. After CVE-2019-14865 fix, grub2-set-bootflag no longer rewrites the
|
|
||||||
grubenv file in-place, but writes into a temporary file and renames it
|
|
||||||
over the original, checking for error returns from each call first.
|
|
||||||
This prevents the original file truncation vulnerability, but it can
|
|
||||||
leave the temporary file around if the program is killed before it can
|
|
||||||
rename or remove the file. There are still many ways to get the program
|
|
||||||
killed, such as through RLIMIT_FSIZE triggering SIGXFSZ (tested,
|
|
||||||
reliable) or by careful timing (tricky) of signals sent by process group
|
|
||||||
leader, pty, pre-scheduled timers, SIGXCPU (probably not an exhaustive
|
|
||||||
list). Invoking the program multiple times fills up /boot (or if /boot
|
|
||||||
is not separate, then it can fill up the root filesystem). Since the
|
|
||||||
files are tiny, the filesystem is likely to run out of free inodes
|
|
||||||
before it'd run out of blocks, but the effect is similar - can't create
|
|
||||||
new files after this point (but still can add data to existing files,
|
|
||||||
such as logs).
|
|
||||||
|
|
||||||
2. After CVE-2019-14865 fix, grub2-set-bootflag naively tries to protect
|
|
||||||
itself from signals by becoming full root. (This does protect it from
|
|
||||||
signals sent by the user directly to the PID, but e.g. "kill -9 -1" by
|
|
||||||
the user still works.) A side effect of such "protection" is that it's
|
|
||||||
possible to invoke more concurrent instances of grub2-set-bootflag than
|
|
||||||
the user's RLIMIT_NPROC would normally permit (as specified e.g. in
|
|
||||||
/etc/security/limits.conf, or say in Apache httpd's RLimitNPROC if
|
|
||||||
grub2-set-bootflag would be abused by a website script), thereby
|
|
||||||
exhausting system resources (e.g., bypassing RAM usage limit if
|
|
||||||
RLIMIT_AS was also set).
|
|
||||||
|
|
||||||
3. umask is inherited. Again, due to how the CVE-2019-14865 fix creates
|
|
||||||
a new file, and due to how mkstemp() works, this affects grubenv's new
|
|
||||||
file permissions. Luckily, mkstemp() forces them to be no more relaxed
|
|
||||||
than 0600, but the user ends up being able to set them e.g. to 0.
|
|
||||||
Luckily, at least in my testing GRUB still works fine even when the file
|
|
||||||
has such (lack of) permissions.
|
|
||||||
|
|
||||||
This commit deals with the abuses above as follows:
|
|
||||||
|
|
||||||
1. RLIMIT_FSIZE is pre-checked, so this specific way to get the process
|
|
||||||
killed should no longer work. However, this isn't a complete fix
|
|
||||||
because there are other ways to get the process killed after it has
|
|
||||||
created the temporary file.
|
|
||||||
|
|
||||||
The commit also fixes bug 1975892 ("RFE: grub2-set-bootflag should not
|
|
||||||
write the grubenv when the flag being written is already set") and
|
|
||||||
similar for "menu_show_once", which further reduces the abuse potential.
|
|
||||||
|
|
||||||
2. RLIMIT_NPROC bypass should be avoided by not becoming full root (aka
|
|
||||||
dropping the partial "kill protection").
|
|
||||||
|
|
||||||
3. A safe umask is set.
|
|
||||||
|
|
||||||
This is a partial fix (temporary files can still accumulate, but this is
|
|
||||||
harder to trigger).
|
|
||||||
|
|
||||||
While at it, this commit also fixes potential 1- or 2-byte over-read of
|
|
||||||
env[] if its content is malformed - this was not a security issue since the
|
|
||||||
grubenv file is trusted input, and the fix is just for robustness.
|
|
||||||
|
|
||||||
Signed-off-by: Solar Designer <solar@openwall.com>
|
|
||||||
---
|
|
||||||
util/grub-set-bootflag.c | 29 ++++++++++++++++-------------
|
|
||||||
1 file changed, 16 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c
|
|
||||||
index a85f11fceacb..5b932f76b6f4 100644
|
|
||||||
--- a/util/grub-set-bootflag.c
|
|
||||||
+++ b/util/grub-set-bootflag.c
|
|
||||||
@@ -32,6 +32,8 @@
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
+#include <sys/stat.h>
|
|
||||||
+#include <sys/resource.h>
|
|
||||||
|
|
||||||
#define GRUBENV "/" GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME "/" GRUB_ENVBLK_DEFCFG
|
|
||||||
#define GRUBENV_SIZE 1024
|
|
||||||
@@ -54,12 +56,17 @@ static void usage(void)
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
/* NOTE buf must be at least the longest bootflag length + 4 bytes */
|
|
||||||
- char env[GRUBENV_SIZE + 1], buf[64], *s;
|
|
||||||
+ char env[GRUBENV_SIZE + 1 + 2], buf[64], *s;
|
|
||||||
/* +1 for 0 termination, +6 for "XXXXXX" in tmp filename */
|
|
||||||
char env_filename[PATH_MAX + 1], tmp_filename[PATH_MAX + 6 + 1];
|
|
||||||
const char *bootflag;
|
|
||||||
int i, fd, len, ret;
|
|
||||||
FILE *f;
|
|
||||||
+ struct rlimit rlim;
|
|
||||||
+
|
|
||||||
+ if (getrlimit(RLIMIT_FSIZE, &rlim) || rlim.rlim_cur < GRUBENV_SIZE || rlim.rlim_max < GRUBENV_SIZE)
|
|
||||||
+ return 1;
|
|
||||||
+ umask(077);
|
|
||||||
|
|
||||||
if (argc != 2)
|
|
||||||
{
|
|
||||||
@@ -81,20 +88,11 @@ int main(int argc, char *argv[])
|
|
||||||
len = strlen (bootflag);
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Really become root. setuid avoids an user killing us, possibly leaking
|
|
||||||
- * the tmpfile. setgid avoids the new grubenv's gid being that of the user.
|
|
||||||
+ * setegid avoids the new grubenv's gid being that of the user.
|
|
||||||
*/
|
|
||||||
- ret = setuid(0);
|
|
||||||
- if (ret)
|
|
||||||
- {
|
|
||||||
- perror ("Error setuid(0) failed");
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = setgid(0);
|
|
||||||
- if (ret)
|
|
||||||
+ if (setegid(0))
|
|
||||||
{
|
|
||||||
- perror ("Error setgid(0) failed");
|
|
||||||
+ perror ("Error setegid(0) failed");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -123,6 +121,9 @@ int main(int argc, char *argv[])
|
|
||||||
|
|
||||||
/* 0 terminate env */
|
|
||||||
env[GRUBENV_SIZE] = 0;
|
|
||||||
+ /* not a valid flag value */
|
|
||||||
+ env[GRUBENV_SIZE + 1] = 0;
|
|
||||||
+ env[GRUBENV_SIZE + 2] = 0;
|
|
||||||
|
|
||||||
if (strncmp (env, GRUB_ENVBLK_SIGNATURE, strlen (GRUB_ENVBLK_SIGNATURE)))
|
|
||||||
{
|
|
||||||
@@ -158,6 +159,8 @@ int main(int argc, char *argv[])
|
|
||||||
|
|
||||||
/* The grubenv is not 0 terminated, so memcpy the name + '=' , '1', '\n' */
|
|
||||||
snprintf(buf, sizeof(buf), "%s=1\n", bootflag);
|
|
||||||
+ if (!memcmp(s, buf, len + 3))
|
|
||||||
+ return 0; /* nothing to do */
|
|
||||||
memcpy(s, buf, len + 3);
|
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,187 +0,0 @@
|
|||||||
From f4c7783c2b695794938748a6567e86456ed2314a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Solar Designer <solar@openwall.com>
|
|
||||||
Date: Tue, 6 Feb 2024 21:56:21 +0100
|
|
||||||
Subject: [PATCH 2/3] grub-set-bootflag: More complete fix for CVE-2024-1048
|
|
||||||
|
|
||||||
Switch to per-user fixed temporary filenames along with a weird locking
|
|
||||||
mechanism, which is explained in source code comments. This is a more
|
|
||||||
complete fix than the previous commit (temporary files can't accumulate).
|
|
||||||
Unfortunately, it introduces new risks (by working on a temporary file
|
|
||||||
shared between the user's invocations), which are _hopefully_ avoided by
|
|
||||||
the patch's elaborate logic. I actually got it wrong at first, which
|
|
||||||
suggests that this logic is hard to reason about, and more errors or
|
|
||||||
omissions are possible. It also relies on the kernel's primitives' exact
|
|
||||||
semantics to a greater extent (nothing out of the ordinary, though).
|
|
||||||
|
|
||||||
Remaining issues that I think cannot reasonably be fixed without a
|
|
||||||
redesign (e.g., having per-flag files with nothing else in them) and
|
|
||||||
without introducing new issues:
|
|
||||||
|
|
||||||
A. A user can still revert a concurrent user's attempt of setting the
|
|
||||||
other flag - or of making other changes to grubenv by means other than
|
|
||||||
this program.
|
|
||||||
|
|
||||||
B. One leftover temporary file per user is still possible.
|
|
||||||
|
|
||||||
Signed-off-by: Solar Designer <solar@openwall.com>
|
|
||||||
---
|
|
||||||
util/grub-set-bootflag.c | 87 ++++++++++++++++++++++++++++++++++------
|
|
||||||
1 file changed, 75 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c
|
|
||||||
index 5b932f76b6f4..698b55a1ab93 100644
|
|
||||||
--- a/util/grub-set-bootflag.c
|
|
||||||
+++ b/util/grub-set-bootflag.c
|
|
||||||
@@ -32,6 +32,7 @@
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
+#include <sys/file.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
|
|
||||||
@@ -57,15 +58,12 @@ int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
/* NOTE buf must be at least the longest bootflag length + 4 bytes */
|
|
||||||
char env[GRUBENV_SIZE + 1 + 2], buf[64], *s;
|
|
||||||
- /* +1 for 0 termination, +6 for "XXXXXX" in tmp filename */
|
|
||||||
- char env_filename[PATH_MAX + 1], tmp_filename[PATH_MAX + 6 + 1];
|
|
||||||
+ /* +1 for 0 termination, +11 for ".%u" in tmp filename */
|
|
||||||
+ char env_filename[PATH_MAX + 1], tmp_filename[PATH_MAX + 11 + 1];
|
|
||||||
const char *bootflag;
|
|
||||||
int i, fd, len, ret;
|
|
||||||
FILE *f;
|
|
||||||
- struct rlimit rlim;
|
|
||||||
|
|
||||||
- if (getrlimit(RLIMIT_FSIZE, &rlim) || rlim.rlim_cur < GRUBENV_SIZE || rlim.rlim_max < GRUBENV_SIZE)
|
|
||||||
- return 1;
|
|
||||||
umask(077);
|
|
||||||
|
|
||||||
if (argc != 2)
|
|
||||||
@@ -92,7 +90,7 @@ int main(int argc, char *argv[])
|
|
||||||
*/
|
|
||||||
if (setegid(0))
|
|
||||||
{
|
|
||||||
- perror ("Error setegid(0) failed");
|
|
||||||
+ perror ("setegid(0) failed");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -163,19 +161,82 @@ int main(int argc, char *argv[])
|
|
||||||
return 0; /* nothing to do */
|
|
||||||
memcpy(s, buf, len + 3);
|
|
||||||
|
|
||||||
+ struct rlimit rlim;
|
|
||||||
+ if (getrlimit(RLIMIT_FSIZE, &rlim) || rlim.rlim_cur < GRUBENV_SIZE || rlim.rlim_max < GRUBENV_SIZE)
|
|
||||||
+ {
|
|
||||||
+ fprintf (stderr, "Resource limits undetermined or too low\n");
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Here we work under the premise that we shouldn't write into the target
|
|
||||||
+ * file directly because we might not be able to have all of our changes
|
|
||||||
+ * written completely and atomically. That was CVE-2019-14865, known to
|
|
||||||
+ * have been triggerable via RLIMIT_FSIZE. While we've dealt with that
|
|
||||||
+ * specific attack via the check above, there may be other possibilities.
|
|
||||||
+ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a tempfile for writing the new env. Use the canonicalized filename
|
|
||||||
* for the template so that the tmpfile is in the same dir / on same fs.
|
|
||||||
+ *
|
|
||||||
+ * We now use per-user fixed temporary filenames, so that a user cannot cause
|
|
||||||
+ * multiple files to accumulate.
|
|
||||||
+ *
|
|
||||||
+ * We don't use O_EXCL so that a stale temporary file doesn't prevent further
|
|
||||||
+ * usage of the program by the user.
|
|
||||||
*/
|
|
||||||
- snprintf(tmp_filename, sizeof(tmp_filename), "%sXXXXXX", env_filename);
|
|
||||||
- fd = mkstemp(tmp_filename);
|
|
||||||
+ snprintf(tmp_filename, sizeof(tmp_filename), "%s.%u", env_filename, getuid());
|
|
||||||
+ fd = open(tmp_filename, O_CREAT | O_WRONLY, 0600);
|
|
||||||
if (fd == -1)
|
|
||||||
{
|
|
||||||
perror ("Creating tmpfile failed");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * The lock prevents the same user from reaching further steps ending in
|
|
||||||
+ * rename() concurrently, in which case the temporary file only partially
|
|
||||||
+ * written by one invocation could be renamed to the target file by another.
|
|
||||||
+ *
|
|
||||||
+ * The lock also guards the slow fsync() from concurrent calls. After the
|
|
||||||
+ * first time that and the rename() complete, further invocations for the
|
|
||||||
+ * same flag become no-ops.
|
|
||||||
+ *
|
|
||||||
+ * We lock the temporary file rather than the target file because locking the
|
|
||||||
+ * latter would allow any user having SIGSTOP'ed their process to make all
|
|
||||||
+ * other users' invocations fail (or lock up if we'd use blocking mode).
|
|
||||||
+ *
|
|
||||||
+ * We use non-blocking mode (LOCK_NB) because the lock having been taken by
|
|
||||||
+ * another process implies that the other process would normally have already
|
|
||||||
+ * renamed the file to target by the time it releases the lock (and we could
|
|
||||||
+ * acquire it), so we'd be working directly on the target if we proceeded,
|
|
||||||
+ * which is undesirable, and we'd kind of fail on the already-done rename.
|
|
||||||
+ */
|
|
||||||
+ if (flock(fd, LOCK_EX | LOCK_NB))
|
|
||||||
+ {
|
|
||||||
+ perror ("Locking tmpfile failed");
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Deal with the potential that another invocation proceeded all the way to
|
|
||||||
+ * rename() and process exit while we were between open() and flock().
|
|
||||||
+ */
|
|
||||||
+ {
|
|
||||||
+ struct stat st1, st2;
|
|
||||||
+ if (fstat(fd, &st1) || stat(tmp_filename, &st2))
|
|
||||||
+ {
|
|
||||||
+ perror ("stat of tmpfile failed");
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
|
|
||||||
+ {
|
|
||||||
+ fprintf (stderr, "Another invocation won race\n");
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
f = fdopen (fd, "w");
|
|
||||||
if (!f)
|
|
||||||
{
|
|
||||||
@@ -200,23 +261,25 @@ int main(int argc, char *argv[])
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = fsync (fileno (f));
|
|
||||||
+ ret = ftruncate (fileno (f), GRUBENV_SIZE);
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
- perror ("Error syncing tmpfile");
|
|
||||||
+ perror ("Error truncating tmpfile");
|
|
||||||
unlink(tmp_filename);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = fclose (f);
|
|
||||||
+ ret = fsync (fileno (f));
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
- perror ("Error closing tmpfile");
|
|
||||||
+ perror ("Error syncing tmpfile");
|
|
||||||
unlink(tmp_filename);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
+ * We must not close the file before rename() as that would remove the lock.
|
|
||||||
+ *
|
|
||||||
* And finally rename the tmpfile with the new env over the old env, the
|
|
||||||
* linux kernel guarantees that this is atomic (from a syscall pov).
|
|
||||||
*/
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
From a7192a650c1e94221a86b49f5132fb47a4dda6ea Mon Sep 17 00:00:00 2001
|
|
||||||
From: Solar Designer <solar@openwall.com>
|
|
||||||
Date: Tue, 6 Feb 2024 22:05:45 +0100
|
|
||||||
Subject: [PATCH 3/3] grub-set-bootflag: Exit calmly when not running as root
|
|
||||||
|
|
||||||
Exit calmly when not installed SUID root and invoked by non-root. This
|
|
||||||
allows installing user/grub-boot-success.service unconditionally while
|
|
||||||
supporting non-SUID installation of the program for some limited usage.
|
|
||||||
|
|
||||||
Signed-off-by: Solar Designer <solar@openwall.com>
|
|
||||||
---
|
|
||||||
util/grub-set-bootflag.c | 11 +++++++++++
|
|
||||||
1 file changed, 11 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c
|
|
||||||
index 698b55a1ab93..a51805fa8cec 100644
|
|
||||||
--- a/util/grub-set-bootflag.c
|
|
||||||
+++ b/util/grub-set-bootflag.c
|
|
||||||
@@ -85,6 +85,17 @@ int main(int argc, char *argv[])
|
|
||||||
bootflag = bootflags[i];
|
|
||||||
len = strlen (bootflag);
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Exit calmly when not installed SUID root and invoked by non-root. This
|
|
||||||
+ * allows installing user/grub-boot-success.service unconditionally while
|
|
||||||
+ * supporting non-SUID installation of the program for some limited usage.
|
|
||||||
+ */
|
|
||||||
+ if (geteuid())
|
|
||||||
+ {
|
|
||||||
+ printf ("grub-set-bootflag not running as root, no action taken\n");
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* setegid avoids the new grubenv's gid being that of the user.
|
|
||||||
*/
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
|||||||
From 43651027d24e62a7a463254165e1e46e42aecdea Mon Sep 17 00:00:00 2001
|
|
||||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Date: Mon, 28 Aug 2023 16:31:57 +0300
|
|
||||||
Subject: [PATCH 1/6] fs/ntfs: Fix an OOB write when parsing the
|
|
||||||
$ATTRIBUTE_LIST attribute for the $MFT file
|
|
||||||
|
|
||||||
When parsing an extremely fragmented $MFT file, i.e., the file described
|
|
||||||
using the $ATTRIBUTE_LIST attribute, current NTFS code will reuse a buffer
|
|
||||||
containing bytes read from the underlying drive to store sector numbers,
|
|
||||||
which are consumed later to read data from these sectors into another buffer.
|
|
||||||
|
|
||||||
These sectors numbers, two 32-bit integers, are always stored at predefined
|
|
||||||
offsets, 0x10 and 0x14, relative to first byte of the selected entry within
|
|
||||||
the $ATTRIBUTE_LIST attribute. Usually, this won't cause any problem.
|
|
||||||
|
|
||||||
However, when parsing a specially-crafted file system image, this may cause
|
|
||||||
the NTFS code to write these integers beyond the buffer boundary, likely
|
|
||||||
causing the GRUB memory allocator to misbehave or fail. These integers contain
|
|
||||||
values which are controlled by on-disk structures of the NTFS file system.
|
|
||||||
|
|
||||||
Such modification and resulting misbehavior may touch a memory range not
|
|
||||||
assigned to the GRUB and owned by firmware or another EFI application/driver.
|
|
||||||
|
|
||||||
This fix introduces checks to ensure that these sector numbers are never
|
|
||||||
written beyond the boundary.
|
|
||||||
|
|
||||||
Fixes: CVE-2023-4692
|
|
||||||
|
|
||||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ntfs.c | 18 +++++++++++++++++-
|
|
||||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index bbdbe24ada83..c3c4db117bba 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -184,7 +184,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
}
|
|
||||||
if (at->attr_end)
|
|
||||||
{
|
|
||||||
- grub_uint8_t *pa;
|
|
||||||
+ grub_uint8_t *pa, *pa_end;
|
|
||||||
|
|
||||||
at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
|
||||||
if (at->emft_buf == NULL)
|
|
||||||
@@ -209,11 +209,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
}
|
|
||||||
at->attr_nxt = at->edat_buf;
|
|
||||||
at->attr_end = at->edat_buf + u32at (pa, 0x30);
|
|
||||||
+ pa_end = at->edat_buf + n;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
at->attr_nxt = at->attr_end + u16at (pa, 0x14);
|
|
||||||
at->attr_end = at->attr_end + u32at (pa, 4);
|
|
||||||
+ pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
|
||||||
}
|
|
||||||
at->flags |= GRUB_NTFS_AF_ALST;
|
|
||||||
while (at->attr_nxt < at->attr_end)
|
|
||||||
@@ -230,6 +232,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
at->flags |= GRUB_NTFS_AF_GPOS;
|
|
||||||
at->attr_cur = at->attr_nxt;
|
|
||||||
pa = at->attr_cur;
|
|
||||||
+
|
|
||||||
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
grub_set_unaligned32 ((char *) pa + 0x10,
|
|
||||||
grub_cpu_to_le32 (at->mft->data->mft_start));
|
|
||||||
grub_set_unaligned32 ((char *) pa + 0x14,
|
|
||||||
@@ -240,6 +249,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
{
|
|
||||||
if (*pa != attr)
|
|
||||||
break;
|
|
||||||
+
|
|
||||||
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (read_attr
|
|
||||||
(at, pa + 0x10,
|
|
||||||
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
From 0ed2458cc4eff6d9a9199527e2a0b6d445802f94 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Date: Mon, 28 Aug 2023 16:32:33 +0300
|
|
||||||
Subject: [PATCH 2/6] fs/ntfs: Fix an OOB read when reading data from the
|
|
||||||
resident $DATA attribute
|
|
||||||
|
|
||||||
When reading a file containing resident data, i.e., the file data is stored in
|
|
||||||
the $DATA attribute within the NTFS file record, not in external clusters,
|
|
||||||
there are no checks that this resident data actually fits the corresponding
|
|
||||||
file record segment.
|
|
||||||
|
|
||||||
When parsing a specially-crafted file system image, the current NTFS code will
|
|
||||||
read the file data from an arbitrary, attacker-chosen memory offset and of
|
|
||||||
arbitrary, attacker-chosen length.
|
|
||||||
|
|
||||||
This allows an attacker to display arbitrary chunks of memory, which could
|
|
||||||
contain sensitive information like password hashes or even plain-text,
|
|
||||||
obfuscated passwords from BS EFI variables.
|
|
||||||
|
|
||||||
This fix implements a check to ensure that resident data is read from the
|
|
||||||
corresponding file record segment only.
|
|
||||||
|
|
||||||
Fixes: CVE-2023-4693
|
|
||||||
|
|
||||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ntfs.c | 13 ++++++++++++-
|
|
||||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index c3c4db117bba..a68e173d8285 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -401,7 +401,18 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
|
|
||||||
{
|
|
||||||
if (ofs + len > u32at (pa, 0x10))
|
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "read out of range");
|
|
||||||
- grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
|
|
||||||
+
|
|
||||||
+ if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
|
|
||||||
+
|
|
||||||
+ if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
|
||||||
+
|
|
||||||
+ if (u16at (pa, 0x14) + u32at (pa, 0x10) >
|
|
||||||
+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
|
||||||
+
|
|
||||||
+ grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
|||||||
From 7e5f031a6a6a3decc2360a7b0c71abbe598e7354 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Date: Mon, 28 Aug 2023 16:33:17 +0300
|
|
||||||
Subject: [PATCH 3/6] fs/ntfs: Fix an OOB read when parsing directory entries
|
|
||||||
from resident and non-resident index attributes
|
|
||||||
|
|
||||||
This fix introduces checks to ensure that index entries are never read
|
|
||||||
beyond the corresponding directory index.
|
|
||||||
|
|
||||||
The lack of this check is a minor issue, likely not exploitable in any way.
|
|
||||||
|
|
||||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ntfs.c | 13 +++++++++++--
|
|
||||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index a68e173d8285..2d78b96e19fb 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -599,7 +599,7 @@ get_utf8 (grub_uint8_t *in, grub_size_t len)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
-list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
|
|
||||||
+list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, grub_uint8_t *end_pos,
|
|
||||||
grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
|
|
||||||
{
|
|
||||||
grub_uint8_t *np;
|
|
||||||
@@ -610,6 +610,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
|
|
||||||
grub_uint8_t namespace;
|
|
||||||
char *ustr;
|
|
||||||
|
|
||||||
+ if ((pos >= end_pos) || (end_pos - pos < 0x52))
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
if (pos[0xC] & 2) /* end signature */
|
|
||||||
break;
|
|
||||||
|
|
||||||
@@ -617,6 +620,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
|
|
||||||
ns = *(np++);
|
|
||||||
namespace = *(np++);
|
|
||||||
|
|
||||||
+ if (2 * ns > end_pos - pos - 0x52)
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Ignore files in DOS namespace, as they will reappear as Win32
|
|
||||||
* names.
|
|
||||||
@@ -806,7 +812,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_pos += 0x10; /* Skip index root */
|
|
||||||
- ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook, hook_data);
|
|
||||||
+ ret = list_file (mft, cur_pos + u16at (cur_pos, 0),
|
|
||||||
+ at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
|
|
||||||
+ hook, hook_data);
|
|
||||||
if (ret)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
@@ -893,6 +901,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
(const grub_uint8_t *) "INDX")))
|
|
||||||
goto done;
|
|
||||||
ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)],
|
|
||||||
+ indx + (mft->data->idx_size << GRUB_NTFS_BLK_SHR),
|
|
||||||
hook, hook_data);
|
|
||||||
if (ret)
|
|
||||||
goto done;
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
From 7a5a116739fa6d8a625da7d6b9272c9a2462f967 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Date: Mon, 28 Aug 2023 16:33:44 +0300
|
|
||||||
Subject: [PATCH 4/6] fs/ntfs: Fix an OOB read when parsing bitmaps for index
|
|
||||||
attributes
|
|
||||||
|
|
||||||
This fix introduces checks to ensure that bitmaps for directory indices
|
|
||||||
are never read beyond their actual sizes.
|
|
||||||
|
|
||||||
The lack of this check is a minor issue, likely not exploitable in any way.
|
|
||||||
|
|
||||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ntfs.c | 19 +++++++++++++++++++
|
|
||||||
1 file changed, 19 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index 2d78b96e19fb..bb70c89fb803 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -843,6 +843,25 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
|
|
||||||
if (is_resident)
|
|
||||||
{
|
|
||||||
+ if (bitmap_len > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap too large");
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (cur_pos >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range");
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (u16at (cur_pos, 0x14) + u32at (cur_pos, 0x10) >
|
|
||||||
+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) cur_pos)
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range");
|
|
||||||
+ goto done;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14),
|
|
||||||
bitmap_len);
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
|||||||
From 1fe82c41e070385e273d7bb1cfb482627a3c28e8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Date: Mon, 28 Aug 2023 16:38:19 +0300
|
|
||||||
Subject: [PATCH 5/6] fs/ntfs: Fix an OOB read when parsing a volume label
|
|
||||||
|
|
||||||
This fix introduces checks to ensure that an NTFS volume label is always
|
|
||||||
read from the corresponding file record segment.
|
|
||||||
|
|
||||||
The current NTFS code allows the volume label string to be read from an
|
|
||||||
arbitrary, attacker-chosen memory location. However, the bytes read are
|
|
||||||
always treated as UTF-16LE. So, the final string displayed is mostly
|
|
||||||
unreadable and it can't be easily converted back to raw bytes.
|
|
||||||
|
|
||||||
The lack of this check is a minor issue, likely not causing a significant
|
|
||||||
data leak.
|
|
||||||
|
|
||||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ntfs.c | 18 +++++++++++++++++-
|
|
||||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index bb70c89fb803..ff5e3740f0dd 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -1213,13 +1213,29 @@ grub_ntfs_label (grub_device_t device, char **label)
|
|
||||||
|
|
||||||
init_attr (&mft->attr, mft);
|
|
||||||
pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME);
|
|
||||||
+
|
|
||||||
+ if (pa >= mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa < 0x16)
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
|
|
||||||
+ goto fail;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
|
|
||||||
len = u32at (pa, 0x10) / 2;
|
|
||||||
pa += u16at (pa, 0x14);
|
|
||||||
- *label = get_utf8 (pa, len);
|
|
||||||
+ if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len)
|
|
||||||
+ *label = get_utf8 (pa, len);
|
|
||||||
+ else
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
|||||||
From e58b870ff926415e23fc386af41ff81b2f588763 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Date: Mon, 28 Aug 2023 16:40:07 +0300
|
|
||||||
Subject: [PATCH 6/6] fs/ntfs: Make code more readable
|
|
||||||
|
|
||||||
Move some calls used to access NTFS attribute header fields into
|
|
||||||
functions with human-readable names.
|
|
||||||
|
|
||||||
Suggested-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ntfs.c | 48 +++++++++++++++++++++++++++++++--------------
|
|
||||||
1 file changed, 33 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index ff5e3740f0dd..de435aa14d85 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -52,6 +52,24 @@ u64at (void *ptr, grub_size_t ofs)
|
|
||||||
return grub_le_to_cpu64 (grub_get_unaligned64 ((char *) ptr + ofs));
|
|
||||||
}
|
|
||||||
|
|
||||||
+static grub_uint16_t
|
|
||||||
+first_attr_off (void *mft_buf_ptr)
|
|
||||||
+{
|
|
||||||
+ return u16at (mft_buf_ptr, 0x14);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static grub_uint16_t
|
|
||||||
+res_attr_data_off (void *res_attr_ptr)
|
|
||||||
+{
|
|
||||||
+ return u16at (res_attr_ptr, 0x14);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static grub_uint32_t
|
|
||||||
+res_attr_data_len (void *res_attr_ptr)
|
|
||||||
+{
|
|
||||||
+ return u32at (res_attr_ptr, 0x10);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
grub_ntfscomp_func_t grub_ntfscomp_func;
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
@@ -106,7 +124,7 @@ init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
|
|
||||||
{
|
|
||||||
at->mft = mft;
|
|
||||||
at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0;
|
|
||||||
- at->attr_nxt = mft->buf + u16at (mft->buf, 0x14);
|
|
||||||
+ at->attr_nxt = mft->buf + first_attr_off (mft->buf);
|
|
||||||
at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -154,7 +172,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)];
|
|
||||||
+ new_pos = &at->emft_buf[first_attr_off (at->emft_buf)];
|
|
||||||
while (*new_pos != 0xFF)
|
|
||||||
{
|
|
||||||
if ((*new_pos == *at->attr_cur)
|
|
||||||
@@ -213,7 +231,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
- at->attr_nxt = at->attr_end + u16at (pa, 0x14);
|
|
||||||
+ at->attr_nxt = at->attr_end + res_attr_data_off (pa);
|
|
||||||
at->attr_end = at->attr_end + u32at (pa, 4);
|
|
||||||
pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
|
||||||
}
|
|
||||||
@@ -399,20 +417,20 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
|
|
||||||
|
|
||||||
if (pa[8] == 0)
|
|
||||||
{
|
|
||||||
- if (ofs + len > u32at (pa, 0x10))
|
|
||||||
+ if (ofs + len > res_attr_data_len (pa))
|
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "read out of range");
|
|
||||||
|
|
||||||
- if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
|
||||||
+ if (res_attr_data_len (pa) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
|
|
||||||
|
|
||||||
if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
|
||||||
|
|
||||||
- if (u16at (pa, 0x14) + u32at (pa, 0x10) >
|
|
||||||
+ if (res_attr_data_off (pa) + res_attr_data_len (pa) >
|
|
||||||
(grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
|
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
|
||||||
|
|
||||||
- grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
|
|
||||||
+ grub_memcpy (dest, pa + res_attr_data_off (pa) + ofs, len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -556,7 +574,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno)
|
|
||||||
(unsigned long long) mftno);
|
|
||||||
|
|
||||||
if (!pa[8])
|
|
||||||
- mft->size = u32at (pa, 0x10);
|
|
||||||
+ mft->size = res_attr_data_len (pa);
|
|
||||||
else
|
|
||||||
mft->size = u64at (pa, 0x30);
|
|
||||||
|
|
||||||
@@ -805,7 +823,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
(u32at (cur_pos, 0x18) != 0x490024) ||
|
|
||||||
(u32at (cur_pos, 0x1C) != 0x300033))
|
|
||||||
continue;
|
|
||||||
- cur_pos += u16at (cur_pos, 0x14);
|
|
||||||
+ cur_pos += res_attr_data_off (cur_pos);
|
|
||||||
if (*cur_pos != 0x30) /* Not filename index */
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
@@ -834,7 +852,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
{
|
|
||||||
int is_resident = (cur_pos[8] == 0);
|
|
||||||
|
|
||||||
- bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) :
|
|
||||||
+ bitmap_len = ((is_resident) ? res_attr_data_len (cur_pos) :
|
|
||||||
u32at (cur_pos, 0x28));
|
|
||||||
|
|
||||||
bmp = grub_malloc (bitmap_len);
|
|
||||||
@@ -855,14 +873,14 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (u16at (cur_pos, 0x14) + u32at (cur_pos, 0x10) >
|
|
||||||
+ if (res_attr_data_off (cur_pos) + res_attr_data_len (cur_pos) >
|
|
||||||
(grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) cur_pos)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
- grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14),
|
|
||||||
+ grub_memcpy (bmp, cur_pos + res_attr_data_off (cur_pos),
|
|
||||||
bitmap_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
@@ -1226,12 +1244,12 @@ grub_ntfs_label (grub_device_t device, char **label)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
|
|
||||||
+ if ((pa) && (pa[8] == 0) && (res_attr_data_len (pa)))
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
|
|
||||||
- len = u32at (pa, 0x10) / 2;
|
|
||||||
- pa += u16at (pa, 0x14);
|
|
||||||
+ len = res_attr_data_len (pa) / 2;
|
|
||||||
+ pa += res_attr_data_off (pa);
|
|
||||||
if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len)
|
|
||||||
*label = get_utf8 (pa, len);
|
|
||||||
else
|
|
||||||
--
|
|
||||||
2.43.0
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Sandoval <lsandova@redhat.com>
|
|
||||||
Date: Thu, 19 Sep 2024 10:15: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.
|
|
||||||
|
|
||||||
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 a1c00776d..573004915 100644
|
|
||||||
--- a/util/grub-mkconfig.in
|
|
||||||
+++ b/util/grub-mkconfig.in
|
|
||||||
@@ -317,7 +317,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,65 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sat, 15 Jun 2024 02:33:08 +0100
|
|
||||||
Subject: [PATCH] misc: Implement grub_strlcpy()
|
|
||||||
|
|
||||||
grub_strlcpy() acts the same way as strlcpy() does on most *NIX,
|
|
||||||
returning the length of src and ensuring dest is always NUL
|
|
||||||
terminated except when size is 0.
|
|
||||||
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
include/grub/misc.h | 39 +++++++++++++++++++++++++++++++++++++++
|
|
||||||
1 file changed, 39 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
|
||||||
index 1b722c818..88fc2a6b0 100644
|
|
||||||
--- a/include/grub/misc.h
|
|
||||||
+++ b/include/grub/misc.h
|
|
||||||
@@ -72,6 +72,45 @@ grub_stpcpy (char *dest, const char *src)
|
|
||||||
return d - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static inline grub_size_t
|
|
||||||
+grub_strlcpy (char *dest, const char *src, grub_size_t size)
|
|
||||||
+{
|
|
||||||
+ char *d = dest;
|
|
||||||
+ grub_size_t res = 0;
|
|
||||||
+ /*
|
|
||||||
+ * We do not subtract one from size here to avoid dealing with underflowing
|
|
||||||
+ * the value, which is why to_copy is always checked to be greater than one
|
|
||||||
+ * throughout this function.
|
|
||||||
+ */
|
|
||||||
+ grub_size_t to_copy = size;
|
|
||||||
+
|
|
||||||
+ /* Copy size - 1 bytes to dest. */
|
|
||||||
+ if (to_copy > 1)
|
|
||||||
+ while ((*d++ = *src++) != '\0' && ++res && --to_copy > 1)
|
|
||||||
+ ;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * NUL terminate if size != 0. The previous step may have copied a NUL byte
|
|
||||||
+ * if it reached the end of the string, but we know dest[size - 1] must always
|
|
||||||
+ * be a NUL byte.
|
|
||||||
+ */
|
|
||||||
+ if (size != 0)
|
|
||||||
+ dest[size - 1] = '\0';
|
|
||||||
+
|
|
||||||
+ /* If there is still space in dest, but are here, we reached the end of src. */
|
|
||||||
+ if (to_copy > 1)
|
|
||||||
+ return res;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If we haven't reached the end of the string, iterate through to determine
|
|
||||||
+ * the strings total length.
|
|
||||||
+ */
|
|
||||||
+ while (*src++ != '\0' && ++res)
|
|
||||||
+ ;
|
|
||||||
+
|
|
||||||
+ return res;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */
|
|
||||||
static inline void *
|
|
||||||
grub_memcpy (void *dest, const void *src, grub_size_t n)
|
|
@ -1,31 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 02:03:33 +0100
|
|
||||||
Subject: [PATCH] fs/ufs: Fix a heap OOB write
|
|
||||||
|
|
||||||
grub_strcpy() was used to copy a symlink name from the filesystem
|
|
||||||
image to a heap allocated buffer. This led to a OOB write to adjacent
|
|
||||||
heap allocations. Fix by using grub_strlcpy().
|
|
||||||
|
|
||||||
Fixes: CVE-2024-45781
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ufs.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c
|
|
||||||
index 293f027aa..0c2004fd7 100644
|
|
||||||
--- a/grub-core/fs/ufs.c
|
|
||||||
+++ b/grub-core/fs/ufs.c
|
|
||||||
@@ -463,7 +463,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
|
|
||||||
/* Check against zero is paylindromic, no need to swap. */
|
|
||||||
if (data->inode.nblocks == 0
|
|
||||||
&& INODE_SIZE (data) <= sizeof (data->inode.symlink))
|
|
||||||
- grub_strcpy (symlink, (char *) data->inode.symlink);
|
|
||||||
+ grub_strlcpy (symlink, (char *) data->inode.symlink, sz);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0)
|
|
@ -1,31 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 02:48:33 +0100
|
|
||||||
Subject: [PATCH] fs/hfs: Fix stack OOB write with grub_strcpy()
|
|
||||||
|
|
||||||
Replaced with grub_strlcpy().
|
|
||||||
|
|
||||||
Fixes: CVE-2024-45782
|
|
||||||
Fixes: CVE-2024-56737
|
|
||||||
Fixes: https://savannah.gnu.org/bugs/?66599
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/hfs.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
|
|
||||||
index 49d1831c8..44859fe43 100644
|
|
||||||
--- a/grub-core/fs/hfs.c
|
|
||||||
+++ b/grub-core/fs/hfs.c
|
|
||||||
@@ -379,7 +379,7 @@ grub_hfs_mount (grub_disk_t disk)
|
|
||||||
volume name. */
|
|
||||||
key.parent_dir = grub_cpu_to_be32_compile_time (1);
|
|
||||||
key.strlen = data->sblock.volname[0];
|
|
||||||
- grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1));
|
|
||||||
+ grub_strlcpy ((char *) key.str, (char *) (data->sblock.volname + 1), sizeof (key.str));
|
|
||||||
|
|
||||||
if (grub_hfs_find_node (data, (char *) &key, data->cat_root,
|
|
||||||
0, (char *) &dir, sizeof (dir)) == 0)
|
|
@ -1,40 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 02:47:54 +0100
|
|
||||||
Subject: [PATCH] fs/tar: Initialize name in grub_cpio_find_file()
|
|
||||||
|
|
||||||
It was possible to iterate through grub_cpio_find_file() without
|
|
||||||
allocating name and not setting mode to GRUB_ARCHELP_ATTR_END, which
|
|
||||||
would cause the uninitialized value for name to be used as an argument
|
|
||||||
for canonicalize() in grub_archelp_dir().
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/tar.c | 5 +++++
|
|
||||||
1 file changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
|
|
||||||
index 4864451e1..f1e6571c2 100644
|
|
||||||
--- a/grub-core/fs/tar.c
|
|
||||||
+++ b/grub-core/fs/tar.c
|
|
||||||
@@ -78,6 +78,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
int reread = 0, have_longname = 0, have_longlink = 0;
|
|
||||||
|
|
||||||
data->hofs = data->next_hofs;
|
|
||||||
+ *name = NULL;
|
|
||||||
|
|
||||||
for (reread = 0; reread < 3; reread++)
|
|
||||||
{
|
|
||||||
@@ -202,6 +203,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
}
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ if (*name == NULL)
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive");
|
|
||||||
+
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Fri, 22 Nov 2024 06:27:58 +0000
|
|
||||||
Subject: [PATCH] fs/tar: Integer overflow leads to heap OOB write
|
|
||||||
|
|
||||||
Both namesize and linksize are derived from hd.size, a 12-digit octal
|
|
||||||
number parsed by read_number(). Later direct arithmetic calculation like
|
|
||||||
"namesize + 1" and "linksize + 1" may exceed the maximum value of
|
|
||||||
grub_size_t leading to heap OOB write. This patch fixes the issue by
|
|
||||||
using grub_add() and checking for an overflow.
|
|
||||||
|
|
||||||
Fixes: CVE-2024-45780
|
|
||||||
|
|
||||||
Reported-by: Nils Langius <nils@langius.de>
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/tar.c | 23 ++++++++++++++++++-----
|
|
||||||
1 file changed, 18 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
|
|
||||||
index f1e6571c2..28baa5845 100644
|
|
||||||
--- a/grub-core/fs/tar.c
|
|
||||||
+++ b/grub-core/fs/tar.c
|
|
||||||
@@ -25,6 +25,7 @@
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -76,6 +77,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
{
|
|
||||||
struct head hd;
|
|
||||||
int reread = 0, have_longname = 0, have_longlink = 0;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
data->hofs = data->next_hofs;
|
|
||||||
*name = NULL;
|
|
||||||
@@ -98,7 +100,11 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
{
|
|
||||||
grub_err_t err;
|
|
||||||
grub_size_t namesize = read_number (hd.size, sizeof (hd.size));
|
|
||||||
- *name = grub_malloc (namesize + 1);
|
|
||||||
+
|
|
||||||
+ if (grub_add (namesize, 1, &sz))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("name size overflow"));
|
|
||||||
+
|
|
||||||
+ *name = grub_malloc (sz);
|
|
||||||
if (*name == NULL)
|
|
||||||
return grub_errno;
|
|
||||||
err = grub_disk_read (data->disk, 0,
|
|
||||||
@@ -118,15 +124,19 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
{
|
|
||||||
grub_err_t err;
|
|
||||||
grub_size_t linksize = read_number (hd.size, sizeof (hd.size));
|
|
||||||
- if (data->linkname_alloc < linksize + 1)
|
|
||||||
+
|
|
||||||
+ if (grub_add (linksize, 1, &sz))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("link size overflow"));
|
|
||||||
+
|
|
||||||
+ if (data->linkname_alloc < sz)
|
|
||||||
{
|
|
||||||
char *n;
|
|
||||||
- n = grub_calloc (2, linksize + 1);
|
|
||||||
+ n = grub_calloc (2, sz);
|
|
||||||
if (!n)
|
|
||||||
return grub_errno;
|
|
||||||
grub_free (data->linkname);
|
|
||||||
data->linkname = n;
|
|
||||||
- data->linkname_alloc = 2 * (linksize + 1);
|
|
||||||
+ data->linkname_alloc = 2 * (sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
err = grub_disk_read (data->disk, 0,
|
|
||||||
@@ -149,7 +159,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
while (extra_size < sizeof (hd.prefix)
|
|
||||||
&& hd.prefix[extra_size])
|
|
||||||
extra_size++;
|
|
||||||
- *name = grub_malloc (sizeof (hd.name) + extra_size + 2);
|
|
||||||
+
|
|
||||||
+ if (grub_add (sizeof (hd.name) + 2, extra_size, &sz))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("long name size overflow"));
|
|
||||||
+ *name = grub_malloc (sz);
|
|
||||||
if (*name == NULL)
|
|
||||||
return grub_errno;
|
|
||||||
if (hd.prefix[0])
|
|
@ -1,31 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 06:15:03 +0100
|
|
||||||
Subject: [PATCH] fs/f2fs: Set a grub_errno if mount fails
|
|
||||||
|
|
||||||
It was previously possible for grub_errno to not be set when
|
|
||||||
grub_f2fs_mount() failed if nat_bitmap_ptr() returned NULL.
|
|
||||||
|
|
||||||
This issue is solved by ensuring a grub_errno is set in the fail case.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/f2fs.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
|
|
||||||
index 07ea34196..706e595d3 100644
|
|
||||||
--- a/grub-core/fs/f2fs.c
|
|
||||||
+++ b/grub-core/fs/f2fs.c
|
|
||||||
@@ -871,6 +871,9 @@ grub_f2fs_mount (grub_disk_t disk)
|
|
||||||
return data;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
+ if (grub_errno == GRUB_ERR_NONE)
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "not a F2FS filesystem");
|
|
||||||
+
|
|
||||||
grub_free (data);
|
|
||||||
|
|
||||||
return NULL;
|
|
@ -1,35 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 06:22:51 +0100
|
|
||||||
Subject: [PATCH] fs/hfsplus: Set a grub_errno if mount fails
|
|
||||||
|
|
||||||
It was possible for mount to fail but not set grub_errno. This led to
|
|
||||||
a possible double decrement of the module reference count if the NULL
|
|
||||||
page was mapped.
|
|
||||||
|
|
||||||
Fixing in general as a similar bug was fixed in commit 61b13c187
|
|
||||||
(fs/hfsplus: Set grub_errno to prevent NULL pointer access) and there
|
|
||||||
are likely more variants around.
|
|
||||||
|
|
||||||
Fixes: CVE-2024-45783
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/hfsplus.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
|
|
||||||
index 8c0c80473..2edb1649d 100644
|
|
||||||
--- a/grub-core/fs/hfsplus.c
|
|
||||||
+++ b/grub-core/fs/hfsplus.c
|
|
||||||
@@ -392,7 +392,7 @@ grub_hfsplus_mount (grub_disk_t disk)
|
|
||||||
|
|
||||||
fail:
|
|
||||||
|
|
||||||
- if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
|
||||||
+ if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE)
|
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
|
|
||||||
|
|
||||||
grub_free (data);
|
|
@ -1,33 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 06:37:08 +0100
|
|
||||||
Subject: [PATCH] fs/iso9660: Set a grub_errno if mount fails
|
|
||||||
|
|
||||||
It was possible for a grub_errno to not be set if mount of an ISO 9660
|
|
||||||
filesystem failed when set_rockridge() returned 0.
|
|
||||||
|
|
||||||
This isn't known to be exploitable as the other filesystems due to
|
|
||||||
filesystem helper checking the requested file type. Though fixing
|
|
||||||
as a precaution.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/iso9660.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
|
|
||||||
index a4403e29d..736d56770 100644
|
|
||||||
--- a/grub-core/fs/iso9660.c
|
|
||||||
+++ b/grub-core/fs/iso9660.c
|
|
||||||
@@ -491,6 +491,9 @@ grub_iso9660_mount (grub_disk_t disk)
|
|
||||||
return data;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
+ if (grub_errno == GRUB_ERR_NONE)
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
|
|
||||||
+
|
|
||||||
grub_free (data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Michael Chang <mchang@suse.com>
|
|
||||||
Date: Fri, 31 May 2024 15:14:42 +0800
|
|
||||||
Subject: [PATCH] fs/iso9660: Fix invalid free
|
|
||||||
|
|
||||||
The ctx->filename can point to either a string literal or a dynamically
|
|
||||||
allocated string. The ctx->filename_alloc field is used to indicate the
|
|
||||||
type of allocation.
|
|
||||||
|
|
||||||
An issue has been identified where ctx->filename is reassigned to
|
|
||||||
a string literal in susp_iterate_dir() but ctx->filename_alloc is not
|
|
||||||
correctly handled. This oversight causes a memory leak and an invalid
|
|
||||||
free operation later.
|
|
||||||
|
|
||||||
The fix involves checking ctx->filename_alloc, freeing the allocated
|
|
||||||
string if necessary and clearing ctx->filename_alloc for string literals.
|
|
||||||
|
|
||||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/iso9660.c | 14 ++++++++++++--
|
|
||||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
|
|
||||||
index 736d56770..cf17702e2 100644
|
|
||||||
--- a/grub-core/fs/iso9660.c
|
|
||||||
+++ b/grub-core/fs/iso9660.c
|
|
||||||
@@ -568,9 +568,19 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry,
|
|
||||||
filename type is stored. */
|
|
||||||
/* FIXME: Fix this slightly improper cast. */
|
|
||||||
if (entry->data[0] & GRUB_ISO9660_RR_DOT)
|
|
||||||
- ctx->filename = (char *) ".";
|
|
||||||
+ {
|
|
||||||
+ if (ctx->filename_alloc)
|
|
||||||
+ grub_free (ctx->filename);
|
|
||||||
+ ctx->filename_alloc = 0;
|
|
||||||
+ ctx->filename = (char *) ".";
|
|
||||||
+ }
|
|
||||||
else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT)
|
|
||||||
- ctx->filename = (char *) "..";
|
|
||||||
+ {
|
|
||||||
+ if (ctx->filename_alloc)
|
|
||||||
+ grub_free (ctx->filename);
|
|
||||||
+ ctx->filename_alloc = 0;
|
|
||||||
+ ctx->filename = (char *) "..";
|
|
||||||
+ }
|
|
||||||
else if (entry->len >= 5)
|
|
||||||
{
|
|
||||||
grub_size_t off = 0, csize = 1;
|
|
@ -1,63 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Fri, 22 Nov 2024 06:27:59 +0000
|
|
||||||
Subject: [PATCH] fs/jfs: Fix OOB read in jfs_getent()
|
|
||||||
|
|
||||||
The JFS fuzzing revealed an OOB read in grub_jfs_getent(). The crash
|
|
||||||
was caused by an invalid leaf nodes count, diro->dirpage->header.count,
|
|
||||||
which was larger than the maximum number of leaf nodes allowed in an
|
|
||||||
inode. This fix is to ensure that the leaf nodes count is validated in
|
|
||||||
grub_jfs_opendir() before calling grub_jfs_getent().
|
|
||||||
|
|
||||||
On the occasion replace existing raw numbers with newly defined constant.
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/jfs.c | 17 +++++++++++++++--
|
|
||||||
1 file changed, 15 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
|
|
||||||
index 20d966abf..d4207eb64 100644
|
|
||||||
--- a/grub-core/fs/jfs.c
|
|
||||||
+++ b/grub-core/fs/jfs.c
|
|
||||||
@@ -41,6 +41,12 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
#define GRUB_JFS_TREE_LEAF 2
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * Define max entries stored in-line in an inode.
|
|
||||||
+ * https://jfs.sourceforge.net/project/pub/jfslayout.pdf
|
|
||||||
+ */
|
|
||||||
+#define GRUB_JFS_INODE_INLINE_ENTRIES 8
|
|
||||||
+
|
|
||||||
struct grub_jfs_sblock
|
|
||||||
{
|
|
||||||
/* The magic for JFS. It should contain the string "JFS1". */
|
|
||||||
@@ -203,9 +209,9 @@ struct grub_jfs_inode
|
|
||||||
grub_uint8_t freecnt;
|
|
||||||
grub_uint8_t freelist;
|
|
||||||
grub_uint32_t idotdot;
|
|
||||||
- grub_uint8_t sorted[8];
|
|
||||||
+ grub_uint8_t sorted[GRUB_JFS_INODE_INLINE_ENTRIES];
|
|
||||||
} header;
|
|
||||||
- struct grub_jfs_leaf_dirent dirents[8];
|
|
||||||
+ struct grub_jfs_leaf_dirent dirents[GRUB_JFS_INODE_INLINE_ENTRIES];
|
|
||||||
} GRUB_PACKED dir;
|
|
||||||
/* Fast symlink. */
|
|
||||||
struct
|
|
||||||
@@ -453,6 +459,13 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
|
|
||||||
/* Check if the entire tree is contained within the inode. */
|
|
||||||
if (inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
|
|
||||||
{
|
|
||||||
+ if (inode->dir.header.count > GRUB_JFS_INODE_INLINE_ENTRIES)
|
|
||||||
+ {
|
|
||||||
+ grub_free (diro);
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, N_("invalid JFS inode"));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
diro->leaf = inode->dir.dirents;
|
|
||||||
diro->next_leaf = (struct grub_jfs_leaf_next_dirent *) de;
|
|
||||||
diro->sorted = inode->dir.header.sorted;
|
|
@ -1,64 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Fri, 22 Nov 2024 06:28:00 +0000
|
|
||||||
Subject: [PATCH] fs/jfs: Fix OOB read caused by invalid dir slot index
|
|
||||||
|
|
||||||
While fuzz testing JFS with ASAN enabled an OOB read was detected in
|
|
||||||
grub_jfs_opendir(). The issue occurred due to an invalid directory slot
|
|
||||||
index in the first entry of the sorted directory slot array in the inode
|
|
||||||
directory header. The fix ensures the slot index is validated before
|
|
||||||
accessing it. Given that an internal or a leaf node in a directory B+
|
|
||||||
tree is a 4 KiB in size and each directory slot is always 32 bytes, the
|
|
||||||
max number of slots in a node is 128. The validation ensures that the
|
|
||||||
slot index doesn't exceed this limit.
|
|
||||||
|
|
||||||
[1] https://jfs.sourceforge.net/project/pub/jfslayout.pdf
|
|
||||||
|
|
||||||
JFS will allocate 4K of disk space for an internal node of the B+ tree.
|
|
||||||
An internal node looks the same as a leaf node.
|
|
||||||
- page 10
|
|
||||||
|
|
||||||
Fixed number of Directory Slots depending on the size of the node. These are
|
|
||||||
the slots to be used for storing the directory slot array and the directory
|
|
||||||
entries or router entries. A directory slot is always 32 bytes.
|
|
||||||
...
|
|
||||||
A Directory Slot Array which is a sorted array of indices to the directory
|
|
||||||
slots that are currently in use.
|
|
||||||
...
|
|
||||||
An internal or a leaf node in the directory B+ tree is a 4K page.
|
|
||||||
- page 25
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/jfs.c | 9 +++++++++
|
|
||||||
1 file changed, 9 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
|
|
||||||
index d4207eb64..60dd62fe2 100644
|
|
||||||
--- a/grub-core/fs/jfs.c
|
|
||||||
+++ b/grub-core/fs/jfs.c
|
|
||||||
@@ -46,6 +46,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
* https://jfs.sourceforge.net/project/pub/jfslayout.pdf
|
|
||||||
*/
|
|
||||||
#define GRUB_JFS_INODE_INLINE_ENTRIES 8
|
|
||||||
+#define GRUB_JFS_DIR_MAX_SLOTS 128
|
|
||||||
|
|
||||||
struct grub_jfs_sblock
|
|
||||||
{
|
|
||||||
@@ -481,6 +482,14 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (inode->dir.header.sorted[0] >= GRUB_JFS_DIR_MAX_SLOTS)
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, N_("invalid directory slot index"));
|
|
||||||
+ grub_free (diro->dirpage);
|
|
||||||
+ grub_free (diro);
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
blk = grub_le_to_cpu32 (de[inode->dir.header.sorted[0]].ex.blk2);
|
|
||||||
blk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS);
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Mon, 16 Dec 2024 20:22:39 +0000
|
|
||||||
Subject: [PATCH] fs/jfs: Use full 40 bits offset and address for a data extent
|
|
||||||
|
|
||||||
An extent's logical offset and address are represented as a 40-bit value
|
|
||||||
split into two parts: the most significant 8 bits and the least
|
|
||||||
significant 32 bits. Currently the JFS code uses only the least
|
|
||||||
significant 32 bits value for offsets and addresses assuming the data
|
|
||||||
size will never exceed the 32-bit range. This approach ignores the most
|
|
||||||
significant 8 bits potentially leading to incorrect offsets and
|
|
||||||
addresses for larger values. The patch fixes it by incorporating the
|
|
||||||
most significant 8 bits into the calculation to get the full 40-bits
|
|
||||||
value for offsets and addresses.
|
|
||||||
|
|
||||||
https://jfs.sourceforge.net/project/pub/jfslayout.pdf
|
|
||||||
|
|
||||||
"off1,off2 is a 40-bit field, containing the logical offset of the first
|
|
||||||
block in the extent.
|
|
||||||
...
|
|
||||||
addr1,addr2 is a 40-bit field, containing the address of the extent."
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/jfs.c | 41 +++++++++++++++++++++++++++++------------
|
|
||||||
1 file changed, 29 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
|
|
||||||
index 60dd62fe2..8a908f00d 100644
|
|
||||||
--- a/grub-core/fs/jfs.c
|
|
||||||
+++ b/grub-core/fs/jfs.c
|
|
||||||
@@ -265,6 +265,20 @@ static grub_dl_t my_mod;
|
|
||||||
|
|
||||||
static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint32_t ino);
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * An extent's offset, physical and logical, is represented as a 40-bit value.
|
|
||||||
+ * This 40-bit value is split into two parts:
|
|
||||||
+ * - offset1: the most signficant 8 bits of the offset,
|
|
||||||
+ * - offset2: the least significant 32 bits of the offset.
|
|
||||||
+ *
|
|
||||||
+ * This function calculates and returns the 64-bit offset of an extent.
|
|
||||||
+ */
|
|
||||||
+static grub_uint64_t
|
|
||||||
+get_ext_offset (grub_uint8_t offset1, grub_uint32_t offset2)
|
|
||||||
+{
|
|
||||||
+ return (((grub_uint64_t) offset1 << 32) | grub_le_to_cpu32 (offset2));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static grub_int64_t
|
|
||||||
getblk (struct grub_jfs_treehead *treehead,
|
|
||||||
struct grub_jfs_tree_extent *extents,
|
|
||||||
@@ -274,22 +288,25 @@ getblk (struct grub_jfs_treehead *treehead,
|
|
||||||
{
|
|
||||||
int found = -1;
|
|
||||||
int i;
|
|
||||||
+ grub_uint64_t ext_offset, ext_blk;
|
|
||||||
|
|
||||||
for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 &&
|
|
||||||
i < max_extents; i++)
|
|
||||||
{
|
|
||||||
+ ext_offset = get_ext_offset (extents[i].offset1, extents[i].offset2);
|
|
||||||
+ ext_blk = get_ext_offset (extents[i].extent.blk1, extents[i].extent.blk2);
|
|
||||||
+
|
|
||||||
if (treehead->flags & GRUB_JFS_TREE_LEAF)
|
|
||||||
{
|
|
||||||
/* Read the leafnode. */
|
|
||||||
- if (grub_le_to_cpu32 (extents[i].offset2) <= blk
|
|
||||||
+ if (ext_offset <= blk
|
|
||||||
&& ((grub_le_to_cpu16 (extents[i].extent.length))
|
|
||||||
+ (extents[i].extent.length2 << 16)
|
|
||||||
- + grub_le_to_cpu32 (extents[i].offset2)) > blk)
|
|
||||||
- return (blk - grub_le_to_cpu32 (extents[i].offset2)
|
|
||||||
- + grub_le_to_cpu32 (extents[i].extent.blk2));
|
|
||||||
+ + ext_offset) > blk)
|
|
||||||
+ return (blk - ext_offset + ext_blk);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
- if (blk >= grub_le_to_cpu32 (extents[i].offset2))
|
|
||||||
+ if (blk >= ext_offset)
|
|
||||||
found = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -307,10 +324,9 @@ getblk (struct grub_jfs_treehead *treehead,
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!grub_disk_read (data->disk,
|
|
||||||
- ((grub_disk_addr_t) grub_le_to_cpu32 (extents[found].extent.blk2))
|
|
||||||
- << (grub_le_to_cpu16 (data->sblock.log2_blksz)
|
|
||||||
- - GRUB_DISK_SECTOR_BITS), 0,
|
|
||||||
- sizeof (*tree), (char *) tree))
|
|
||||||
+ (grub_disk_addr_t) ext_blk
|
|
||||||
+ << (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS),
|
|
||||||
+ 0, sizeof (*tree), (char *) tree))
|
|
||||||
{
|
|
||||||
if (grub_memcmp (&tree->treehead, treehead, sizeof (struct grub_jfs_treehead)) ||
|
|
||||||
grub_memcmp (&tree->extents, extents, 254 * sizeof (struct grub_jfs_tree_extent)))
|
|
||||||
@@ -361,7 +377,7 @@ grub_jfs_read_inode (struct grub_jfs_data *data, grub_uint32_t ino,
|
|
||||||
sizeof (iag_inodes), &iag_inodes))
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
- inoblk = grub_le_to_cpu32 (iag_inodes[inoext].blk2);
|
|
||||||
+ inoblk = get_ext_offset (iag_inodes[inoext].blk1, iag_inodes[inoext].blk2);
|
|
||||||
inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz)
|
|
||||||
- GRUB_DISK_SECTOR_BITS);
|
|
||||||
inoblk += inonum;
|
|
||||||
@@ -490,7 +506,8 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- blk = grub_le_to_cpu32 (de[inode->dir.header.sorted[0]].ex.blk2);
|
|
||||||
+ blk = get_ext_offset (de[inode->dir.header.sorted[0]].ex.blk1,
|
|
||||||
+ de[inode->dir.header.sorted[0]].ex.blk2);
|
|
||||||
blk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS);
|
|
||||||
|
|
||||||
/* Read in the nodes until we are on the leaf node level. */
|
|
||||||
@@ -508,7 +525,7 @@ grub_jfs_opendir (struct grub_jfs_data *data, struct grub_jfs_inode *inode)
|
|
||||||
|
|
||||||
de = (struct grub_jfs_internal_dirent *) diro->dirpage->dirent;
|
|
||||||
index = diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
|
|
||||||
- blk = (grub_le_to_cpu32 (de[index].ex.blk2)
|
|
||||||
+ blk = (get_ext_offset (de[index].ex.blk1, de[index].ex.blk2)
|
|
||||||
<< (grub_le_to_cpu16 (data->sblock.log2_blksz)
|
|
||||||
- GRUB_DISK_SECTOR_BITS));
|
|
||||||
} while (!(diro->dirpage->header.flags & GRUB_JFS_TREE_LEAF));
|
|
@ -1,85 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Mon, 16 Dec 2024 20:22:40 +0000
|
|
||||||
Subject: [PATCH] fs/jfs: Inconsistent signed/unsigned types usage in return
|
|
||||||
values
|
|
||||||
|
|
||||||
The getblk() returns a value of type grub_int64_t which is assigned to
|
|
||||||
iagblk and inoblk, both of type grub_uint64_t, in grub_jfs_read_inode()
|
|
||||||
via grub_jfs_blkno(). This patch fixes the type mismatch in the
|
|
||||||
functions. Additionally, the getblk() will return 0 instead of -1 on
|
|
||||||
failure cases. This change is safe because grub_errno is always set in
|
|
||||||
getblk() to indicate errors and it is later checked in the callers.
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/jfs.c | 15 +++++++++------
|
|
||||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
|
|
||||||
index 8a908f00d..739b3c540 100644
|
|
||||||
--- a/grub-core/fs/jfs.c
|
|
||||||
+++ b/grub-core/fs/jfs.c
|
|
||||||
@@ -279,7 +279,7 @@ get_ext_offset (grub_uint8_t offset1, grub_uint32_t offset2)
|
|
||||||
return (((grub_uint64_t) offset1 << 32) | grub_le_to_cpu32 (offset2));
|
|
||||||
}
|
|
||||||
|
|
||||||
-static grub_int64_t
|
|
||||||
+static grub_uint64_t
|
|
||||||
getblk (struct grub_jfs_treehead *treehead,
|
|
||||||
struct grub_jfs_tree_extent *extents,
|
|
||||||
int max_extents,
|
|
||||||
@@ -290,6 +290,8 @@ getblk (struct grub_jfs_treehead *treehead,
|
|
||||||
int i;
|
|
||||||
grub_uint64_t ext_offset, ext_blk;
|
|
||||||
|
|
||||||
+ grub_errno = GRUB_ERR_NONE;
|
|
||||||
+
|
|
||||||
for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 &&
|
|
||||||
i < max_extents; i++)
|
|
||||||
{
|
|
||||||
@@ -312,7 +314,7 @@ getblk (struct grub_jfs_treehead *treehead,
|
|
||||||
|
|
||||||
if (found != -1)
|
|
||||||
{
|
|
||||||
- grub_int64_t ret = -1;
|
|
||||||
+ grub_uint64_t ret = 0;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
struct grub_jfs_treehead treehead;
|
|
||||||
@@ -321,7 +323,7 @@ getblk (struct grub_jfs_treehead *treehead,
|
|
||||||
|
|
||||||
tree = grub_zalloc (sizeof (*tree));
|
|
||||||
if (!tree)
|
|
||||||
- return -1;
|
|
||||||
+ return 0;
|
|
||||||
|
|
||||||
if (!grub_disk_read (data->disk,
|
|
||||||
(grub_disk_addr_t) ext_blk
|
|
||||||
@@ -334,19 +336,20 @@ getblk (struct grub_jfs_treehead *treehead,
|
|
||||||
else
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FS, "jfs: infinite recursion detected");
|
|
||||||
- ret = -1;
|
|
||||||
+ ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
grub_free (tree);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return -1;
|
|
||||||
+ grub_error (GRUB_ERR_READ_ERROR, "jfs: block %" PRIuGRUB_UINT64_T " not found", blk);
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the block number for the block BLK in the node INODE in the
|
|
||||||
mounted filesystem DATA. */
|
|
||||||
-static grub_int64_t
|
|
||||||
+static grub_uint64_t
|
|
||||||
grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
|
|
||||||
grub_uint64_t blk)
|
|
||||||
{
|
|
@ -1,46 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Michael Chang <mchang@suse.com>
|
|
||||||
Date: Fri, 31 May 2024 15:14:23 +0800
|
|
||||||
Subject: [PATCH] fs/ext2: Fix out-of-bounds read for inline extents
|
|
||||||
|
|
||||||
When inline extents are used, i.e. the extent tree depth equals zero,
|
|
||||||
a maximum of four entries can fit into the inode's data block. If the
|
|
||||||
extent header states a number of entries greater than four the current
|
|
||||||
ext2 implementation causes an out-of-bounds read. Fix this issue by
|
|
||||||
capping the number of extents to four when reading inline extents.
|
|
||||||
|
|
||||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ext2.c | 10 +++++++++-
|
|
||||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
|
|
||||||
index 3d59cf131..de5c268a9 100644
|
|
||||||
--- a/grub-core/fs/ext2.c
|
|
||||||
+++ b/grub-core/fs/ext2.c
|
|
||||||
@@ -473,6 +473,8 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
|
||||||
struct grub_ext4_extent *ext;
|
|
||||||
int i;
|
|
||||||
grub_disk_addr_t ret;
|
|
||||||
+ grub_uint16_t nent;
|
|
||||||
+ const grub_uint16_t max_inline_ext = sizeof (inode->blocks) / sizeof (*ext) - 1; /* Minus 1 extent header. */
|
|
||||||
|
|
||||||
leaf = grub_ext4_find_leaf (data, (struct grub_ext4_extent_header *) inode->blocks.dir_blocks, fileblock);
|
|
||||||
if (! leaf)
|
|
||||||
@@ -482,7 +484,13 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
|
||||||
}
|
|
||||||
|
|
||||||
ext = (struct grub_ext4_extent *) (leaf + 1);
|
|
||||||
- for (i = 0; i < grub_le_to_cpu16 (leaf->entries); i++)
|
|
||||||
+
|
|
||||||
+ nent = grub_le_to_cpu16 (leaf->entries);
|
|
||||||
+
|
|
||||||
+ if (leaf->depth == 0)
|
|
||||||
+ nent = grub_min (nent, max_inline_ext);
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < nent; i++)
|
|
||||||
{
|
|
||||||
if (fileblock < grub_le_to_cpu32 (ext[i].block))
|
|
||||||
break;
|
|
@ -1,47 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Michael Chang <mchang@suse.com>
|
|
||||||
Date: Mon, 3 Jun 2024 12:12:06 +0800
|
|
||||||
Subject: [PATCH] fs/ntfs: Fix out-of-bounds read
|
|
||||||
|
|
||||||
When parsing NTFS file records the presence of the 0xFF marker indicates
|
|
||||||
the end of the attribute list. This value signifies that there are no
|
|
||||||
more attributes to process.
|
|
||||||
|
|
||||||
However, when the end marker is missing due to corrupted metadata the
|
|
||||||
loop continues to read beyond the attribute list resulting in out-of-bounds
|
|
||||||
reads and potentially entering an infinite loop.
|
|
||||||
|
|
||||||
This patch adds a check to provide a stop condition for the loop ensuring
|
|
||||||
it stops at the end of the attribute list or at the end of the Master File
|
|
||||||
Table. This guards against out-of-bounds reads and prevents infinite loops.
|
|
||||||
|
|
||||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ntfs.c | 5 ++++-
|
|
||||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index d3fb5b48f..9c4d9be98 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -139,6 +139,8 @@ free_attr (struct grub_ntfs_attr *at)
|
|
||||||
static grub_uint8_t *
|
|
||||||
find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
{
|
|
||||||
+ grub_uint8_t *mft_end;
|
|
||||||
+
|
|
||||||
if (at->flags & GRUB_NTFS_AF_ALST)
|
|
||||||
{
|
|
||||||
retry:
|
|
||||||
@@ -191,7 +193,8 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
at->attr_cur = at->attr_nxt;
|
|
||||||
- while (*at->attr_cur != 0xFF)
|
|
||||||
+ mft_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
|
||||||
+ while (at->attr_cur < mft_end && *at->attr_cur != 0xFF)
|
|
||||||
{
|
|
||||||
at->attr_nxt += u16at (at->attr_cur, 4);
|
|
||||||
if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST)
|
|
@ -1,141 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Tue, 7 Jan 2025 11:38:34 +0000
|
|
||||||
Subject: [PATCH] fs/ntfs: Track the end of the MFT attribute buffer
|
|
||||||
|
|
||||||
The end of the attribute buffer should be stored alongside the rest of
|
|
||||||
the attribute struct as right now it is not possible to implement bounds
|
|
||||||
checking when accessing attributes sequentially.
|
|
||||||
|
|
||||||
This is done via:
|
|
||||||
- updating init_attr() to set at->end and check is is not initially out of bounds,
|
|
||||||
- implementing checks as init_attr() had its type change in its callers,
|
|
||||||
- updating the value of at->end when needed.
|
|
||||||
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ntfs.c | 34 ++++++++++++++++++++++++++++------
|
|
||||||
include/grub/ntfs.h | 1 +
|
|
||||||
2 files changed, 29 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index 9c4d9be98..699cdb3c0 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -119,13 +119,20 @@ static grub_err_t read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa,
|
|
||||||
grub_disk_read_hook_t read_hook,
|
|
||||||
void *read_hook_data);
|
|
||||||
|
|
||||||
-static void
|
|
||||||
+static grub_err_t
|
|
||||||
init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
|
|
||||||
{
|
|
||||||
at->mft = mft;
|
|
||||||
at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0;
|
|
||||||
at->attr_nxt = mft->buf + first_attr_off (mft->buf);
|
|
||||||
+ at->end = mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
|
||||||
+
|
|
||||||
+ if (at->attr_nxt > at->end)
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, "attributes start outside the MFT");
|
|
||||||
+
|
|
||||||
at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
|
|
||||||
+
|
|
||||||
+ return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
@@ -239,6 +246,10 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
|
||||||
}
|
|
||||||
at->flags |= GRUB_NTFS_AF_ALST;
|
|
||||||
+
|
|
||||||
+ /* From this point on pa_end is the end of the buffer */
|
|
||||||
+ at->end = pa_end;
|
|
||||||
+
|
|
||||||
while (at->attr_nxt < at->attr_end)
|
|
||||||
{
|
|
||||||
if ((*at->attr_nxt == attr) || (attr == 0))
|
|
||||||
@@ -298,7 +309,9 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
|
|
||||||
{
|
|
||||||
grub_uint8_t *pa;
|
|
||||||
|
|
||||||
- init_attr (at, mft);
|
|
||||||
+ if (init_attr (at, mft) != GRUB_ERR_NONE)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
pa = find_attr (at, attr);
|
|
||||||
if (pa == NULL)
|
|
||||||
return NULL;
|
|
||||||
@@ -314,7 +327,8 @@ locate_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft,
|
|
||||||
}
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
free_attr (at);
|
|
||||||
- init_attr (at, mft);
|
|
||||||
+ if (init_attr (at, mft) != GRUB_ERR_NONE)
|
|
||||||
+ return NULL;
|
|
||||||
pa = find_attr (at, attr);
|
|
||||||
}
|
|
||||||
return pa;
|
|
||||||
@@ -585,7 +599,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno)
|
|
||||||
mft->attr.attr_end = 0; /* Don't jump to attribute list */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
- init_attr (&mft->attr, mft);
|
|
||||||
+ return init_attr (&mft->attr, mft);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -807,7 +821,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
bmp = NULL;
|
|
||||||
|
|
||||||
at = &attr;
|
|
||||||
- init_attr (at, mft);
|
|
||||||
+ if (init_attr (at, mft) != GRUB_ERR_NONE)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
cur_pos = find_attr (at, GRUB_NTFS_AT_INDEX_ROOT);
|
|
||||||
@@ -838,7 +854,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
bitmap = NULL;
|
|
||||||
bitmap_len = 0;
|
|
||||||
free_attr (at);
|
|
||||||
+ /* No need to check errors here, as it will already be fine */
|
|
||||||
init_attr (at, mft);
|
|
||||||
+
|
|
||||||
while ((cur_pos = find_attr (at, GRUB_NTFS_AT_BITMAP)) != NULL)
|
|
||||||
{
|
|
||||||
int ofs;
|
|
||||||
@@ -1203,6 +1221,7 @@ grub_ntfs_label (grub_device_t device, char **label)
|
|
||||||
struct grub_ntfs_data *data = 0;
|
|
||||||
struct grub_fshelp_node *mft = 0;
|
|
||||||
grub_uint8_t *pa;
|
|
||||||
+ grub_err_t err;
|
|
||||||
|
|
||||||
grub_dl_ref (my_mod);
|
|
||||||
|
|
||||||
@@ -1228,7 +1247,10 @@ grub_ntfs_label (grub_device_t device, char **label)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
- init_attr (&mft->attr, mft);
|
|
||||||
+ err = init_attr (&mft->attr, mft);
|
|
||||||
+ if (err != GRUB_ERR_NONE)
|
|
||||||
+ return err;
|
|
||||||
+
|
|
||||||
pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME);
|
|
||||||
|
|
||||||
if (pa >= mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
|
||||||
diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h
|
|
||||||
index d1a6af696..ec1c4db38 100644
|
|
||||||
--- a/include/grub/ntfs.h
|
|
||||||
+++ b/include/grub/ntfs.h
|
|
||||||
@@ -134,6 +134,7 @@ struct grub_ntfs_attr
|
|
||||||
grub_uint8_t *attr_cur, *attr_nxt, *attr_end;
|
|
||||||
grub_uint32_t save_pos;
|
|
||||||
grub_uint8_t *sbuf;
|
|
||||||
+ grub_uint8_t *end;
|
|
||||||
struct grub_ntfs_file *mft;
|
|
||||||
};
|
|
||||||
|
|
@ -1,183 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Tue, 14 May 2024 12:39:56 +0100
|
|
||||||
Subject: [PATCH] fs/ntfs: Use a helper function to access attributes
|
|
||||||
|
|
||||||
Right now to access the next attribute the code reads the length of the
|
|
||||||
current attribute and adds that to the current pointer. This is error
|
|
||||||
prone as bounds checking needs to be performed all over the place. So,
|
|
||||||
implement a helper and ensure its used across find_attr() and read_attr().
|
|
||||||
|
|
||||||
This commit does *not* implement full bounds checking. It is just the
|
|
||||||
preparation work for this to be added into the helper.
|
|
||||||
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/ntfs.c | 69 +++++++++++++++++++++++++++++++++++++++++++----------
|
|
||||||
include/grub/ntfs.h | 2 ++
|
|
||||||
2 files changed, 58 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index 699cdb3c0..5b3189ab2 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -70,6 +70,25 @@ res_attr_data_len (void *res_attr_ptr)
|
|
||||||
return u32at (res_attr_ptr, 0x10);
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* Return the next attribute if it exists, otherwise return NULL. */
|
|
||||||
+static grub_uint8_t *
|
|
||||||
+next_attribute (grub_uint8_t *curr_attribute, void *end)
|
|
||||||
+{
|
|
||||||
+ grub_uint8_t *next = curr_attribute;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Need to verify we aren't exceeding the end of the buffer by reading the
|
|
||||||
+ * header for the current attribute
|
|
||||||
+ */
|
|
||||||
+ if (curr_attribute + GRUB_NTFS_ATTRIBUTE_HEADER_SIZE >= (grub_uint8_t *) end)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ next += u16at (curr_attribute, 4);
|
|
||||||
+
|
|
||||||
+ return next;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
grub_ntfscomp_func_t grub_ntfscomp_func;
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
@@ -151,13 +170,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
if (at->flags & GRUB_NTFS_AF_ALST)
|
|
||||||
{
|
|
||||||
retry:
|
|
||||||
- while (at->attr_nxt < at->attr_end)
|
|
||||||
+ while (at->attr_nxt)
|
|
||||||
{
|
|
||||||
at->attr_cur = at->attr_nxt;
|
|
||||||
- at->attr_nxt += u16at (at->attr_cur, 4);
|
|
||||||
+ at->attr_nxt = next_attribute (at->attr_cur, at->attr_end);
|
|
||||||
if ((*at->attr_cur == attr) || (attr == 0))
|
|
||||||
{
|
|
||||||
- grub_uint8_t *new_pos;
|
|
||||||
+ grub_uint8_t *new_pos, *end;
|
|
||||||
|
|
||||||
if (at->flags & GRUB_NTFS_AF_MMFT)
|
|
||||||
{
|
|
||||||
@@ -181,15 +200,36 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * Only time emft_bufs is defined is in this function, with this
|
|
||||||
+ * size.
|
|
||||||
+ */
|
|
||||||
+ grub_size_t emft_buf_size =
|
|
||||||
+ at->mft->data->mft_size << GRUB_NTFS_BLK_SHR;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Needs to be enough space for the successful case to even
|
|
||||||
+ * bother.
|
|
||||||
+ */
|
|
||||||
+ if (first_attr_off (at->emft_buf) >= (emft_buf_size - 0x18 - 2))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS,
|
|
||||||
+ "can\'t find 0x%X in attribute list",
|
|
||||||
+ (unsigned char) *at->attr_cur);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
new_pos = &at->emft_buf[first_attr_off (at->emft_buf)];
|
|
||||||
- while (*new_pos != 0xFF)
|
|
||||||
+ end = &at->emft_buf[emft_buf_size];
|
|
||||||
+
|
|
||||||
+ while (new_pos && *new_pos != 0xFF)
|
|
||||||
{
|
|
||||||
if ((*new_pos == *at->attr_cur)
|
|
||||||
&& (u16at (new_pos, 0xE) == u16at (at->attr_cur, 0x18)))
|
|
||||||
{
|
|
||||||
return new_pos;
|
|
||||||
}
|
|
||||||
- new_pos += u16at (new_pos, 4);
|
|
||||||
+ new_pos = next_attribute (new_pos, end);
|
|
||||||
}
|
|
||||||
grub_error (GRUB_ERR_BAD_FS,
|
|
||||||
"can\'t find 0x%X in attribute list",
|
|
||||||
@@ -203,7 +243,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
mft_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
|
||||||
while (at->attr_cur < mft_end && *at->attr_cur != 0xFF)
|
|
||||||
{
|
|
||||||
- at->attr_nxt += u16at (at->attr_cur, 4);
|
|
||||||
+ at->attr_nxt = next_attribute (at->attr_cur, at->end);
|
|
||||||
if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST)
|
|
||||||
at->attr_end = at->attr_cur;
|
|
||||||
if ((*at->attr_cur == attr) || (attr == 0))
|
|
||||||
@@ -250,13 +290,14 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
/* From this point on pa_end is the end of the buffer */
|
|
||||||
at->end = pa_end;
|
|
||||||
|
|
||||||
- while (at->attr_nxt < at->attr_end)
|
|
||||||
+ while (at->attr_nxt)
|
|
||||||
{
|
|
||||||
if ((*at->attr_nxt == attr) || (attr == 0))
|
|
||||||
break;
|
|
||||||
- at->attr_nxt += u16at (at->attr_nxt, 4);
|
|
||||||
+ at->attr_nxt = next_attribute (at->attr_nxt, pa_end);
|
|
||||||
}
|
|
||||||
- if (at->attr_nxt >= at->attr_end)
|
|
||||||
+
|
|
||||||
+ if (at->attr_nxt >= at->attr_end || at->attr_nxt == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if ((at->flags & GRUB_NTFS_AF_MMFT) && (attr == GRUB_NTFS_AT_DATA))
|
|
||||||
@@ -277,7 +318,8 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
grub_cpu_to_le32 (at->mft->data->mft_start
|
|
||||||
+ 1));
|
|
||||||
pa = at->attr_nxt + u16at (pa, 4);
|
|
||||||
- while (pa < at->attr_end)
|
|
||||||
+
|
|
||||||
+ while (pa)
|
|
||||||
{
|
|
||||||
if (*pa != attr)
|
|
||||||
break;
|
|
||||||
@@ -293,7 +335,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
|
||||||
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
|
|
||||||
at->mft->data->mft_size << GRUB_NTFS_BLK_SHR, 0, 0, 0))
|
|
||||||
return NULL;
|
|
||||||
- pa += u16at (pa, 4);
|
|
||||||
+ pa = next_attribute (pa, pa_end);
|
|
||||||
}
|
|
||||||
at->attr_nxt = at->attr_cur;
|
|
||||||
at->flags &= ~GRUB_NTFS_AF_GPOS;
|
|
||||||
@@ -530,14 +572,15 @@ read_attr (struct grub_ntfs_attr *at, grub_uint8_t *dest, grub_disk_addr_t ofs,
|
|
||||||
else
|
|
||||||
vcn = ofs >> (at->mft->data->log_spc + GRUB_NTFS_BLK_SHR);
|
|
||||||
pa = at->attr_nxt + u16at (at->attr_nxt, 4);
|
|
||||||
- while (pa < at->attr_end)
|
|
||||||
+
|
|
||||||
+ while (pa)
|
|
||||||
{
|
|
||||||
if (*pa != attr)
|
|
||||||
break;
|
|
||||||
if (u32at (pa, 8) > vcn)
|
|
||||||
break;
|
|
||||||
at->attr_nxt = pa;
|
|
||||||
- pa += u16at (pa, 4);
|
|
||||||
+ pa = next_attribute (pa, at->attr_end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pp = find_attr (at, attr);
|
|
||||||
diff --git a/include/grub/ntfs.h b/include/grub/ntfs.h
|
|
||||||
index ec1c4db38..2c8078403 100644
|
|
||||||
--- a/include/grub/ntfs.h
|
|
||||||
+++ b/include/grub/ntfs.h
|
|
||||||
@@ -89,6 +89,8 @@ enum
|
|
||||||
#define GRUB_NTFS_COM_SEC (GRUB_NTFS_COM_LEN >> GRUB_NTFS_BLK_SHR)
|
|
||||||
#define GRUB_NTFS_LOG_COM_SEC (GRUB_NTFS_COM_LOG_LEN - GRUB_NTFS_BLK_SHR)
|
|
||||||
|
|
||||||
+#define GRUB_NTFS_ATTRIBUTE_HEADER_SIZE 16
|
|
||||||
+
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
GRUB_NTFS_AF_ALST = 1,
|
|
@ -1,42 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Michael Chang <mchang@suse.com>
|
|
||||||
Date: Fri, 31 May 2024 15:14:57 +0800
|
|
||||||
Subject: [PATCH] fs/xfs: Fix out-of-bounds read
|
|
||||||
|
|
||||||
The number of records in the root key array read from disk was not being
|
|
||||||
validated against the size of the root node. This could lead to an
|
|
||||||
out-of-bounds read.
|
|
||||||
|
|
||||||
This patch adds a check to ensure that the number of records in the root
|
|
||||||
key array does not exceed the expected size of a root node read from
|
|
||||||
disk. If this check detects an out-of-bounds condition the operation is
|
|
||||||
aborted to prevent random errors due to metadata corruption.
|
|
||||||
|
|
||||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/xfs.c | 10 ++++++++++
|
|
||||||
1 file changed, 10 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
|
||||||
index 66e66dd58..f919bfd2a 100644
|
|
||||||
--- a/grub-core/fs/xfs.c
|
|
||||||
+++ b/grub-core/fs/xfs.c
|
|
||||||
@@ -540,6 +540,16 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
+ grub_addr_t keys_end, data_end;
|
|
||||||
+ if (grub_mul (sizeof (grub_uint64_t), nrec, &keys_end) ||
|
|
||||||
+ grub_add ((grub_addr_t) keys, keys_end, &keys_end) ||
|
|
||||||
+ grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) ||
|
|
||||||
+ keys_end > data_end)
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS root keys");
|
|
||||||
+ grub_free (leaf);
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < nrec; i++)
|
|
||||||
{
|
|
@ -1,42 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 06:03:58 +0100
|
|
||||||
Subject: [PATCH] fs/xfs: Ensuring failing to mount sets a grub_errno
|
|
||||||
|
|
||||||
It was previously possible for grub_xfs_mount() to return NULL without
|
|
||||||
setting grub_errno if the XFS version was invalid. This resulted in it
|
|
||||||
being possible for grub_dl_unref() to be called twice allowing the XFS
|
|
||||||
module to be unloaded while there were still references to it.
|
|
||||||
|
|
||||||
Fixing this problem in general by ensuring a grub_errno is set if the
|
|
||||||
fail label is reached.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/xfs.c | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
|
||||||
index f919bfd2a..c9818a96a 100644
|
|
||||||
--- a/grub-core/fs/xfs.c
|
|
||||||
+++ b/grub-core/fs/xfs.c
|
|
||||||
@@ -297,6 +297,8 @@ static int grub_xfs_sb_valid(struct grub_xfs_data *data)
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ grub_error (GRUB_ERR_BAD_FS, "unsupported XFS filesystem version");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -952,7 +954,7 @@ grub_xfs_mount (grub_disk_t disk)
|
|
||||||
return data;
|
|
||||||
fail:
|
|
||||||
|
|
||||||
- if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
|
||||||
+ if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE)
|
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem");
|
|
||||||
|
|
||||||
grub_free (data);
|
|
@ -1,32 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 03:01:40 +0100
|
|
||||||
Subject: [PATCH] kern/file: Ensure file->data is set
|
|
||||||
|
|
||||||
This is to avoid a generic issue were some filesystems would not set
|
|
||||||
data and also not set a grub_errno. This meant it was possible for many
|
|
||||||
filesystems to grub_dl_unref() themselves multiple times resulting in
|
|
||||||
it being possible to unload the filesystems while there were still
|
|
||||||
references to them, e.g., via a loopback.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/kern/file.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
|
|
||||||
index 5e1f29d0d..596f16ced 100644
|
|
||||||
--- a/grub-core/kern/file.c
|
|
||||||
+++ b/grub-core/kern/file.c
|
|
||||||
@@ -121,6 +121,9 @@ grub_file_open (const char *name, enum grub_file_type type)
|
|
||||||
if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
+ if (file->data == NULL)
|
|
||||||
+ goto fail;
|
|
||||||
+
|
|
||||||
file->name = grub_strdup (name);
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
|
|
@ -1,430 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 10:15:03 +0100
|
|
||||||
Subject: [PATCH] kern/file: Implement filesystem reference counting
|
|
||||||
|
|
||||||
The grub_file_open() and grub_file_close() should be the only places
|
|
||||||
that allow a reference to a filesystem to stay open. So, add grub_dl_t
|
|
||||||
to grub_fs_t and set this in the GRUB_MOD_INIT() for each filesystem to
|
|
||||||
avoid issues when filesystems forget to do it themselves or do not track
|
|
||||||
their own references, e.g. squash4.
|
|
||||||
|
|
||||||
The fs_label(), fs_uuid(), fs_mtime() and fs_read() should all ref and
|
|
||||||
unref in the same function but it is essentially redundant in GRUB
|
|
||||||
single threaded model.
|
|
||||||
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/affs.c | 1 +
|
|
||||||
grub-core/fs/bfs.c | 1 +
|
|
||||||
grub-core/fs/btrfs.c | 1 +
|
|
||||||
grub-core/fs/cbfs.c | 1 +
|
|
||||||
grub-core/fs/cpio.c | 1 +
|
|
||||||
grub-core/fs/cpio_be.c | 1 +
|
|
||||||
grub-core/fs/ext2.c | 1 +
|
|
||||||
grub-core/fs/f2fs.c | 1 +
|
|
||||||
grub-core/fs/fat.c | 1 +
|
|
||||||
grub-core/fs/hfs.c | 1 +
|
|
||||||
grub-core/fs/hfsplus.c | 1 +
|
|
||||||
grub-core/fs/iso9660.c | 1 +
|
|
||||||
grub-core/fs/jfs.c | 1 +
|
|
||||||
grub-core/fs/minix.c | 1 +
|
|
||||||
grub-core/fs/newc.c | 1 +
|
|
||||||
grub-core/fs/nilfs2.c | 1 +
|
|
||||||
grub-core/fs/ntfs.c | 1 +
|
|
||||||
grub-core/fs/odc.c | 1 +
|
|
||||||
grub-core/fs/proc.c | 1 +
|
|
||||||
grub-core/fs/reiserfs.c | 1 +
|
|
||||||
grub-core/fs/romfs.c | 1 +
|
|
||||||
grub-core/fs/sfs.c | 1 +
|
|
||||||
grub-core/fs/squash4.c | 1 +
|
|
||||||
grub-core/fs/tar.c | 1 +
|
|
||||||
grub-core/fs/udf.c | 1 +
|
|
||||||
grub-core/fs/ufs.c | 1 +
|
|
||||||
grub-core/fs/xfs.c | 1 +
|
|
||||||
grub-core/fs/zfs/zfs.c | 1 +
|
|
||||||
grub-core/kern/file.c | 4 ++++
|
|
||||||
include/grub/fs.h | 4 ++++
|
|
||||||
30 files changed, 36 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
|
|
||||||
index e4615c743..6347ca368 100644
|
|
||||||
--- a/grub-core/fs/affs.c
|
|
||||||
+++ b/grub-core/fs/affs.c
|
|
||||||
@@ -699,6 +699,7 @@ static struct grub_fs grub_affs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(affs)
|
|
||||||
{
|
|
||||||
+ grub_affs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_affs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c
|
|
||||||
index d2b490bce..6afdfc987 100644
|
|
||||||
--- a/grub-core/fs/bfs.c
|
|
||||||
+++ b/grub-core/fs/bfs.c
|
|
||||||
@@ -1104,6 +1104,7 @@ GRUB_MOD_INIT (bfs)
|
|
||||||
{
|
|
||||||
COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE ==
|
|
||||||
sizeof (struct grub_bfs_extent));
|
|
||||||
+ grub_bfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_bfs_fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
|
|
||||||
index 9da2952f7..65213549e 100644
|
|
||||||
--- a/grub-core/fs/btrfs.c
|
|
||||||
+++ b/grub-core/fs/btrfs.c
|
|
||||||
@@ -2802,6 +2802,7 @@ subvol_get_env (struct grub_env_var *var __attribute__ ((unused)),
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (btrfs)
|
|
||||||
{
|
|
||||||
+ grub_btrfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_btrfs_fs);
|
|
||||||
cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info,
|
|
||||||
"DEVICE",
|
|
||||||
diff --git a/grub-core/fs/cbfs.c b/grub-core/fs/cbfs.c
|
|
||||||
index 0842701a6..395edcbbd 100644
|
|
||||||
--- a/grub-core/fs/cbfs.c
|
|
||||||
+++ b/grub-core/fs/cbfs.c
|
|
||||||
@@ -390,6 +390,7 @@ GRUB_MOD_INIT (cbfs)
|
|
||||||
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
|
|
||||||
init_cbfsdisk ();
|
|
||||||
#endif
|
|
||||||
+ grub_cbfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_cbfs_fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c
|
|
||||||
index dab5f9898..1799f7ff5 100644
|
|
||||||
--- a/grub-core/fs/cpio.c
|
|
||||||
+++ b/grub-core/fs/cpio.c
|
|
||||||
@@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size)
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (cpio)
|
|
||||||
{
|
|
||||||
+ grub_cpio_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_cpio_fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/cpio_be.c b/grub-core/fs/cpio_be.c
|
|
||||||
index 846548892..7bed1b848 100644
|
|
||||||
--- a/grub-core/fs/cpio_be.c
|
|
||||||
+++ b/grub-core/fs/cpio_be.c
|
|
||||||
@@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size)
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (cpio_be)
|
|
||||||
{
|
|
||||||
+ grub_cpio_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_cpio_fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
|
|
||||||
index de5c268a9..dc62a6cfe 100644
|
|
||||||
--- a/grub-core/fs/ext2.c
|
|
||||||
+++ b/grub-core/fs/ext2.c
|
|
||||||
@@ -1105,6 +1105,7 @@ static struct grub_fs grub_ext2_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(ext2)
|
|
||||||
{
|
|
||||||
+ grub_ext2_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_ext2_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
|
|
||||||
index 706e595d3..149f33695 100644
|
|
||||||
--- a/grub-core/fs/f2fs.c
|
|
||||||
+++ b/grub-core/fs/f2fs.c
|
|
||||||
@@ -1339,6 +1339,7 @@ static struct grub_fs grub_f2fs_fs = {
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (f2fs)
|
|
||||||
{
|
|
||||||
+ grub_f2fs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_f2fs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c
|
|
||||||
index 8d8dc35ce..72785a798 100644
|
|
||||||
--- a/grub-core/fs/fat.c
|
|
||||||
+++ b/grub-core/fs/fat.c
|
|
||||||
@@ -1254,6 +1254,7 @@ GRUB_MOD_INIT(fat)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32);
|
|
||||||
+ grub_fat_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_fat_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
|
|
||||||
index 44859fe43..66b9fca83 100644
|
|
||||||
--- a/grub-core/fs/hfs.c
|
|
||||||
+++ b/grub-core/fs/hfs.c
|
|
||||||
@@ -1434,6 +1434,7 @@ static struct grub_fs grub_hfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(hfs)
|
|
||||||
{
|
|
||||||
+ grub_hfs_fs.mod = mod;
|
|
||||||
if (!grub_is_lockdown ())
|
|
||||||
grub_fs_register (&grub_hfs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
|
|
||||||
index 2edb1649d..a1805eed0 100644
|
|
||||||
--- a/grub-core/fs/hfsplus.c
|
|
||||||
+++ b/grub-core/fs/hfsplus.c
|
|
||||||
@@ -1139,6 +1139,7 @@ static struct grub_fs grub_hfsplus_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(hfsplus)
|
|
||||||
{
|
|
||||||
+ grub_hfsplus_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_hfsplus_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
|
|
||||||
index cf17702e2..576505535 100644
|
|
||||||
--- a/grub-core/fs/iso9660.c
|
|
||||||
+++ b/grub-core/fs/iso9660.c
|
|
||||||
@@ -1165,6 +1165,7 @@ static struct grub_fs grub_iso9660_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(iso9660)
|
|
||||||
{
|
|
||||||
+ grub_iso9660_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_iso9660_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
|
|
||||||
index 739b3c540..46941248b 100644
|
|
||||||
--- a/grub-core/fs/jfs.c
|
|
||||||
+++ b/grub-core/fs/jfs.c
|
|
||||||
@@ -998,6 +998,7 @@ static struct grub_fs grub_jfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(jfs)
|
|
||||||
{
|
|
||||||
+ grub_jfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_jfs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c
|
|
||||||
index d451b3426..28571c49e 100644
|
|
||||||
--- a/grub-core/fs/minix.c
|
|
||||||
+++ b/grub-core/fs/minix.c
|
|
||||||
@@ -716,6 +716,7 @@ GRUB_MOD_INIT(minix)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
+ grub_minix_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_minix_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/newc.c b/grub-core/fs/newc.c
|
|
||||||
index 4fb8b2e3d..43b7f8b64 100644
|
|
||||||
--- a/grub-core/fs/newc.c
|
|
||||||
+++ b/grub-core/fs/newc.c
|
|
||||||
@@ -64,6 +64,7 @@ read_number (const char *str, grub_size_t size)
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (newc)
|
|
||||||
{
|
|
||||||
+ grub_cpio_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_cpio_fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
|
|
||||||
index c4c4610be..3c1e4d1f6 100644
|
|
||||||
--- a/grub-core/fs/nilfs2.c
|
|
||||||
+++ b/grub-core/fs/nilfs2.c
|
|
||||||
@@ -1231,6 +1231,7 @@ GRUB_MOD_INIT (nilfs2)
|
|
||||||
grub_nilfs2_dat_entry));
|
|
||||||
COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE
|
|
||||||
== sizeof (struct grub_nilfs2_inode));
|
|
||||||
+ grub_nilfs2_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_nilfs2_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index 86222413c..9244e95dd 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -1537,6 +1537,7 @@ static struct grub_fs grub_ntfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (ntfs)
|
|
||||||
{
|
|
||||||
+ grub_ntfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_ntfs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/odc.c b/grub-core/fs/odc.c
|
|
||||||
index 790000622..8e4e8aeac 100644
|
|
||||||
--- a/grub-core/fs/odc.c
|
|
||||||
+++ b/grub-core/fs/odc.c
|
|
||||||
@@ -52,6 +52,7 @@ read_number (const char *str, grub_size_t size)
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (odc)
|
|
||||||
{
|
|
||||||
+ grub_cpio_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_cpio_fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/proc.c b/grub-core/fs/proc.c
|
|
||||||
index 31f3aa9a4..317118b81 100644
|
|
||||||
--- a/grub-core/fs/proc.c
|
|
||||||
+++ b/grub-core/fs/proc.c
|
|
||||||
@@ -192,6 +192,7 @@ static struct grub_fs grub_procfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (procfs)
|
|
||||||
{
|
|
||||||
+ grub_procfs_fs.mod = mod;
|
|
||||||
grub_disk_dev_register (&grub_procfs_dev);
|
|
||||||
grub_fs_register (&grub_procfs_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c
|
|
||||||
index 9556c15ff..e65b81467 100644
|
|
||||||
--- a/grub-core/fs/reiserfs.c
|
|
||||||
+++ b/grub-core/fs/reiserfs.c
|
|
||||||
@@ -1407,6 +1407,7 @@ static struct grub_fs grub_reiserfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(reiserfs)
|
|
||||||
{
|
|
||||||
+ grub_reiserfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_reiserfs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c
|
|
||||||
index 2e3544408..f282cff86 100644
|
|
||||||
--- a/grub-core/fs/romfs.c
|
|
||||||
+++ b/grub-core/fs/romfs.c
|
|
||||||
@@ -475,6 +475,7 @@ static struct grub_fs grub_romfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(romfs)
|
|
||||||
{
|
|
||||||
+ grub_romfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_romfs_fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
|
|
||||||
index 61d6c303c..c6b9fb49a 100644
|
|
||||||
--- a/grub-core/fs/sfs.c
|
|
||||||
+++ b/grub-core/fs/sfs.c
|
|
||||||
@@ -779,6 +779,7 @@ static struct grub_fs grub_sfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(sfs)
|
|
||||||
{
|
|
||||||
+ grub_sfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_sfs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
|
|
||||||
index f9bef38fc..1505832d5 100644
|
|
||||||
--- a/grub-core/fs/squash4.c
|
|
||||||
+++ b/grub-core/fs/squash4.c
|
|
||||||
@@ -1032,6 +1032,7 @@ static struct grub_fs grub_squash_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(squash4)
|
|
||||||
{
|
|
||||||
+ grub_squash_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_squash_fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
|
|
||||||
index 28baa5845..01738ec55 100644
|
|
||||||
--- a/grub-core/fs/tar.c
|
|
||||||
+++ b/grub-core/fs/tar.c
|
|
||||||
@@ -354,6 +354,7 @@ static struct grub_fs grub_cpio_fs = {
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (tar)
|
|
||||||
{
|
|
||||||
+ grub_cpio_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_cpio_fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
|
|
||||||
index 6670beb56..8db2b5686 100644
|
|
||||||
--- a/grub-core/fs/udf.c
|
|
||||||
+++ b/grub-core/fs/udf.c
|
|
||||||
@@ -1382,6 +1382,7 @@ static struct grub_fs grub_udf_fs = {
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (udf)
|
|
||||||
{
|
|
||||||
+ grub_udf_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_udf_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c
|
|
||||||
index 0c2004fd7..a2c63d646 100644
|
|
||||||
--- a/grub-core/fs/ufs.c
|
|
||||||
+++ b/grub-core/fs/ufs.c
|
|
||||||
@@ -899,6 +899,7 @@ GRUB_MOD_INIT(ufs1)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
+ grub_ufs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_ufs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
|
||||||
index c9818a96a..5b7643eb1 100644
|
|
||||||
--- a/grub-core/fs/xfs.c
|
|
||||||
+++ b/grub-core/fs/xfs.c
|
|
||||||
@@ -1167,6 +1167,7 @@ static struct grub_fs grub_xfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(xfs)
|
|
||||||
{
|
|
||||||
+ grub_xfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_xfs_fs);
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
|
|
||||||
index 0d8c08eec..0c4b15f08 100644
|
|
||||||
--- a/grub-core/fs/zfs/zfs.c
|
|
||||||
+++ b/grub-core/fs/zfs/zfs.c
|
|
||||||
@@ -4391,6 +4391,7 @@ static struct grub_fs grub_zfs_fs = {
|
|
||||||
GRUB_MOD_INIT (zfs)
|
|
||||||
{
|
|
||||||
COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE);
|
|
||||||
+ grub_zfs_fs.mod = mod;
|
|
||||||
grub_fs_register (&grub_zfs_fs);
|
|
||||||
#ifndef GRUB_UTIL
|
|
||||||
my_mod = mod;
|
|
||||||
diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c
|
|
||||||
index 596f16ced..7e64609d4 100644
|
|
||||||
--- a/grub-core/kern/file.c
|
|
||||||
+++ b/grub-core/kern/file.c
|
|
||||||
@@ -25,6 +25,7 @@
|
|
||||||
#include <grub/fs.h>
|
|
||||||
#include <grub/device.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/dl.h>
|
|
||||||
|
|
||||||
void (*EXPORT_VAR (grub_grubnet_fini)) (void);
|
|
||||||
|
|
||||||
@@ -124,6 +125,9 @@ grub_file_open (const char *name, enum grub_file_type type)
|
|
||||||
if (file->data == NULL)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
+ if (file->fs->mod)
|
|
||||||
+ grub_dl_ref (file->fs->mod);
|
|
||||||
+
|
|
||||||
file->name = grub_strdup (name);
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
|
|
||||||
diff --git a/include/grub/fs.h b/include/grub/fs.h
|
|
||||||
index 5678c60c2..cb1040b50 100644
|
|
||||||
--- a/include/grub/fs.h
|
|
||||||
+++ b/include/grub/fs.h
|
|
||||||
@@ -23,6 +23,7 @@
|
|
||||||
#include <grub/device.h>
|
|
||||||
#include <grub/symbol.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
+#include <grub/dl.h>
|
|
||||||
|
|
||||||
#include <grub/list.h>
|
|
||||||
/* For embedding types. */
|
|
||||||
@@ -57,6 +58,9 @@ struct grub_fs
|
|
||||||
/* My name. */
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
+ /* My module */
|
|
||||||
+ grub_dl_t mod;
|
|
||||||
+
|
|
||||||
/* Call HOOK with each file under DIR. */
|
|
||||||
grub_err_t (*dir) (grub_device_t device, const char *path,
|
|
||||||
grub_fs_dir_hook_t hook, void *hook_data);
|
|
@ -1,103 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 03:26:19 +0100
|
|
||||||
Subject: [PATCH] disk/loopback: Reference tracking for the loopback
|
|
||||||
|
|
||||||
It was possible to delete a loopback while there were still references
|
|
||||||
to it. This led to an exploitable use-after-free.
|
|
||||||
|
|
||||||
Fixed by implementing a reference counting in the grub_loopback struct.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/disk/loopback.c | 18 ++++++++++++++++++
|
|
||||||
include/grub/err.h | 3 ++-
|
|
||||||
2 files changed, 20 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c
|
|
||||||
index 9406d931c..e7052a9cb 100644
|
|
||||||
--- a/grub-core/disk/loopback.c
|
|
||||||
+++ b/grub-core/disk/loopback.c
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/extcmd.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ struct grub_loopback
|
|
||||||
grub_file_t file;
|
|
||||||
struct grub_loopback *next;
|
|
||||||
unsigned long id;
|
|
||||||
+ grub_uint64_t refcnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct grub_loopback *loopback_list;
|
|
||||||
@@ -63,6 +65,8 @@ delete_loopback (const char *name)
|
|
||||||
if (! dev)
|
|
||||||
return grub_error (GRUB_ERR_BAD_DEVICE, "device not found");
|
|
||||||
|
|
||||||
+ if (dev->refcnt > 0)
|
|
||||||
+ return grub_error (GRUB_ERR_STILL_REFERENCED, "device still referenced");
|
|
||||||
/* Remove the device from the list. */
|
|
||||||
*prev = dev->next;
|
|
||||||
|
|
||||||
@@ -124,6 +128,7 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args)
|
|
||||||
|
|
||||||
newdev->file = file;
|
|
||||||
newdev->id = last_id++;
|
|
||||||
+ newdev->refcnt = 0;
|
|
||||||
|
|
||||||
/* Add the new entry to the list. */
|
|
||||||
newdev->next = loopback_list;
|
|
||||||
@@ -165,6 +170,9 @@ grub_loopback_open (const char *name, grub_disk_t disk)
|
|
||||||
if (! dev)
|
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
|
|
||||||
|
|
||||||
+ if (grub_add (dev->refcnt, 1, &dev->refcnt))
|
|
||||||
+ grub_fatal ("Reference count overflow");
|
|
||||||
+
|
|
||||||
/* Use the filesize for the disk size, round up to a complete sector. */
|
|
||||||
if (dev->file->size != GRUB_FILE_SIZE_UNKNOWN)
|
|
||||||
disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1)
|
|
||||||
@@ -182,6 +190,15 @@ grub_loopback_open (const char *name, grub_disk_t disk)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void
|
|
||||||
+grub_loopback_close (grub_disk_t disk)
|
|
||||||
+{
|
|
||||||
+ struct grub_loopback *dev = disk->data;
|
|
||||||
+
|
|
||||||
+ if (grub_sub (dev->refcnt, 1, &dev->refcnt))
|
|
||||||
+ grub_fatal ("Reference count underflow");
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static grub_err_t
|
|
||||||
grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|
||||||
grub_size_t size, char *buf)
|
|
||||||
@@ -224,6 +241,7 @@ static struct grub_disk_dev grub_loopback_dev =
|
|
||||||
.id = GRUB_DISK_DEVICE_LOOPBACK_ID,
|
|
||||||
.iterate = grub_loopback_iterate,
|
|
||||||
.open = grub_loopback_open,
|
|
||||||
+ .close = grub_loopback_close,
|
|
||||||
.read = grub_loopback_read,
|
|
||||||
.write = grub_loopback_write,
|
|
||||||
.next = 0
|
|
||||||
diff --git a/include/grub/err.h b/include/grub/err.h
|
|
||||||
index 9b830757d..1b5335610 100644
|
|
||||||
--- a/include/grub/err.h
|
|
||||||
+++ b/include/grub/err.h
|
|
||||||
@@ -71,7 +71,8 @@ typedef enum
|
|
||||||
GRUB_ERR_NET_PACKET_TOO_BIG,
|
|
||||||
GRUB_ERR_NET_NO_DOMAIN,
|
|
||||||
GRUB_ERR_EOF,
|
|
||||||
- GRUB_ERR_BAD_SIGNATURE
|
|
||||||
+ GRUB_ERR_BAD_SIGNATURE,
|
|
||||||
+ GRUB_ERR_STILL_REFERENCED
|
|
||||||
}
|
|
||||||
grub_err_t;
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 04:09:24 +0100
|
|
||||||
Subject: [PATCH] kern/disk: Limit recursion depth
|
|
||||||
|
|
||||||
The grub_disk_read() may trigger other disk reads, e.g. via loopbacks.
|
|
||||||
This may lead to very deep recursion which can corrupt the heap. So, fix
|
|
||||||
the issue by limiting reads depth.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/kern/disk.c | 27 ++++++++++++++++++++-------
|
|
||||||
include/grub/err.h | 3 ++-
|
|
||||||
2 files changed, 22 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c
|
|
||||||
index 7f58c5614..62d6a85cc 100644
|
|
||||||
--- a/grub-core/kern/disk.c
|
|
||||||
+++ b/grub-core/kern/disk.c
|
|
||||||
@@ -28,6 +28,10 @@
|
|
||||||
|
|
||||||
#define GRUB_CACHE_TIMEOUT 2
|
|
||||||
|
|
||||||
+/* Disk reads may trigger other disk reads. So, limit recursion depth. */
|
|
||||||
+#define MAX_READ_RECURSION_DEPTH 16
|
|
||||||
+static unsigned int read_recursion_depth = 0;
|
|
||||||
+
|
|
||||||
/* The last time the disk was used. */
|
|
||||||
static grub_uint64_t grub_last_time = 0;
|
|
||||||
|
|
||||||
@@ -417,6 +421,8 @@ grub_err_t
|
|
||||||
grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|
||||||
grub_off_t offset, grub_size_t size, void *buf)
|
|
||||||
{
|
|
||||||
+ grub_err_t err = GRUB_ERR_NONE;
|
|
||||||
+
|
|
||||||
/* First of all, check if the region is within the disk. */
|
|
||||||
if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE)
|
|
||||||
{
|
|
||||||
@@ -427,12 +433,17 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (++read_recursion_depth >= MAX_READ_RECURSION_DEPTH)
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_RECURSION_DEPTH, "grub_disk_read(): Maximum recursion depth exceeded");
|
|
||||||
+ goto error;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* First read until first cache boundary. */
|
|
||||||
if (offset || (sector & (GRUB_DISK_CACHE_SIZE - 1)))
|
|
||||||
{
|
|
||||||
grub_disk_addr_t start_sector;
|
|
||||||
grub_size_t pos;
|
|
||||||
- grub_err_t err;
|
|
||||||
grub_size_t len;
|
|
||||||
|
|
||||||
start_sector = sector & ~((grub_disk_addr_t) GRUB_DISK_CACHE_SIZE - 1);
|
|
||||||
@@ -444,7 +455,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|
||||||
err = grub_disk_read_small (disk, start_sector,
|
|
||||||
offset + pos, len, buf);
|
|
||||||
if (err)
|
|
||||||
- return err;
|
|
||||||
+ goto error;
|
|
||||||
buf = (char *) buf + len;
|
|
||||||
size -= len;
|
|
||||||
offset += len;
|
|
||||||
@@ -457,7 +468,6 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|
||||||
{
|
|
||||||
char *data = NULL;
|
|
||||||
grub_disk_addr_t agglomerate;
|
|
||||||
- grub_err_t err;
|
|
||||||
|
|
||||||
/* agglomerate read until we find a first cached entry. */
|
|
||||||
for (agglomerate = 0; agglomerate
|
|
||||||
@@ -493,7 +503,7 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|
||||||
- disk->log_sector_size),
|
|
||||||
buf);
|
|
||||||
if (err)
|
|
||||||
- return err;
|
|
||||||
+ goto error;
|
|
||||||
|
|
||||||
for (i = 0; i < agglomerate; i ++)
|
|
||||||
grub_disk_cache_store (disk->dev->id, disk->id,
|
|
||||||
@@ -527,13 +537,16 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|
||||||
/* And now read the last part. */
|
|
||||||
if (size)
|
|
||||||
{
|
|
||||||
- grub_err_t err;
|
|
||||||
err = grub_disk_read_small (disk, sector, 0, size, buf);
|
|
||||||
if (err)
|
|
||||||
- return err;
|
|
||||||
+ goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return grub_errno;
|
|
||||||
+ err = grub_errno;
|
|
||||||
+
|
|
||||||
+ error:
|
|
||||||
+ read_recursion_depth--;
|
|
||||||
+ return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_uint64_t
|
|
||||||
diff --git a/include/grub/err.h b/include/grub/err.h
|
|
||||||
index 1b5335610..670d40967 100644
|
|
||||||
--- a/include/grub/err.h
|
|
||||||
+++ b/include/grub/err.h
|
|
||||||
@@ -72,7 +72,8 @@ typedef enum
|
|
||||||
GRUB_ERR_NET_NO_DOMAIN,
|
|
||||||
GRUB_ERR_EOF,
|
|
||||||
GRUB_ERR_BAD_SIGNATURE,
|
|
||||||
- GRUB_ERR_STILL_REFERENCED
|
|
||||||
+ GRUB_ERR_STILL_REFERENCED,
|
|
||||||
+ GRUB_ERR_RECURSION_DEPTH
|
|
||||||
}
|
|
||||||
grub_err_t;
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sat, 16 Nov 2024 21:24:19 +0000
|
|
||||||
Subject: [PATCH] kern/partition: Limit recursion in part_iterate()
|
|
||||||
|
|
||||||
The part_iterate() is used by grub_partition_iterate() as a callback in
|
|
||||||
the partition iterate functions. However, part_iterate() may also call
|
|
||||||
the partition iterate functions which may lead to recursion. Fix potential
|
|
||||||
issue by limiting the recursion depth.
|
|
||||||
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/kern/partition.c | 10 +++++++++-
|
|
||||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c
|
|
||||||
index 3068c4dca..f3f125e75 100644
|
|
||||||
--- a/grub-core/kern/partition.c
|
|
||||||
+++ b/grub-core/kern/partition.c
|
|
||||||
@@ -28,6 +28,9 @@
|
|
||||||
|
|
||||||
grub_partition_map_t grub_partition_map_list;
|
|
||||||
|
|
||||||
+#define MAX_RECURSION_DEPTH 32
|
|
||||||
+static unsigned int recursion_depth = 0;
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Checks that disk->partition contains part. This function assumes that the
|
|
||||||
* start of part is relative to the start of disk->partition. Returns 1 if
|
|
||||||
@@ -208,7 +211,12 @@ part_iterate (grub_disk_t dsk, const grub_partition_t partition, void *data)
|
|
||||||
FOR_PARTITION_MAPS(partmap)
|
|
||||||
{
|
|
||||||
grub_err_t err;
|
|
||||||
- err = partmap->iterate (dsk, part_iterate, ctx);
|
|
||||||
+ recursion_depth++;
|
|
||||||
+ if (recursion_depth <= MAX_RECURSION_DEPTH)
|
|
||||||
+ err = partmap->iterate (dsk, part_iterate, ctx);
|
|
||||||
+ else
|
|
||||||
+ err = grub_error (GRUB_ERR_RECURSION_DEPTH, "maximum recursion depth exceeded");
|
|
||||||
+ recursion_depth--;
|
|
||||||
if (err)
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
if (ctx->ret)
|
|
@ -1,55 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Thu, 18 Apr 2024 19:04:13 +0100
|
|
||||||
Subject: [PATCH] script/execute: Limit the recursion depth
|
|
||||||
|
|
||||||
If unbounded recursion is allowed it becomes possible to collide the
|
|
||||||
stack with the heap. As UEFI firmware often lacks guard pages this
|
|
||||||
becomes an exploitable issue as it is possible in some cases to do
|
|
||||||
a controlled overwrite of a section of this heap region with
|
|
||||||
arbitrary data.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/script/execute.c | 14 ++++++++++++++
|
|
||||||
1 file changed, 14 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
|
|
||||||
index 266d99ed3..ef9a01642 100644
|
|
||||||
--- a/grub-core/script/execute.c
|
|
||||||
+++ b/grub-core/script/execute.c
|
|
||||||
@@ -36,10 +36,18 @@
|
|
||||||
is sizeof (int) * 3, and one extra for a possible -ve sign. */
|
|
||||||
#define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1)
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * A limit on recursion, to avoid colliding with the heap. UEFI defines a baseline
|
|
||||||
+ * stack size of 128 KiB. So, assuming at most 1-2 KiB per iteration this should
|
|
||||||
+ * keep us safe.
|
|
||||||
+ */
|
|
||||||
+#define MAX_RECURSION_DEPTH 64
|
|
||||||
+
|
|
||||||
static unsigned long is_continue;
|
|
||||||
static unsigned long active_loops;
|
|
||||||
static unsigned long active_breaks;
|
|
||||||
static unsigned long function_return;
|
|
||||||
+static unsigned long recursion_depth;
|
|
||||||
|
|
||||||
#define GRUB_SCRIPT_SCOPE_MALLOCED 1
|
|
||||||
#define GRUB_SCRIPT_SCOPE_ARGS_MALLOCED 2
|
|
||||||
@@ -850,7 +858,13 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd)
|
|
||||||
if (cmd == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
+ recursion_depth++;
|
|
||||||
+
|
|
||||||
+ if (recursion_depth >= MAX_RECURSION_DEPTH)
|
|
||||||
+ return grub_error (GRUB_ERR_RECURSION_DEPTH, N_("maximum recursion depth exceeded"));
|
|
||||||
+
|
|
||||||
ret = cmd->exec (cmd);
|
|
||||||
+ recursion_depth--;
|
|
||||||
|
|
||||||
grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret);
|
|
||||||
grub_env_set ("?", errnobuf);
|
|
@ -1,29 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Thu, 28 Nov 2024 04:05:04 +0000
|
|
||||||
Subject: [PATCH] net: Unregister net_default_ip and net_default_mac variables
|
|
||||||
hooks on unload
|
|
||||||
|
|
||||||
The net module is a dependency of normal. So, it shouldn't be possible
|
|
||||||
to unload the net. Though unregister variables hooks as a precaution.
|
|
||||||
It also gets in line with unregistering the other net module hooks.
|
|
||||||
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/net/net.c | 2 ++
|
|
||||||
1 file changed, 2 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
|
|
||||||
index b9e2a4d10..c78c8694b 100644
|
|
||||||
--- a/grub-core/net/net.c
|
|
||||||
+++ b/grub-core/net/net.c
|
|
||||||
@@ -2161,6 +2161,8 @@ GRUB_MOD_FINI(net)
|
|
||||||
|
|
||||||
grub_register_variable_hook ("net_default_server", 0, 0);
|
|
||||||
grub_register_variable_hook ("pxe_default_server", 0, 0);
|
|
||||||
+ grub_register_variable_hook ("net_default_ip", 0, 0);
|
|
||||||
+ grub_register_variable_hook ("net_default_mac", 0, 0);
|
|
||||||
|
|
||||||
grub_bootp_fini ();
|
|
||||||
grub_dns_fini ();
|
|
@ -1,85 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Fri, 1 Nov 2024 23:49:48 +0000
|
|
||||||
Subject: [PATCH] net: Remove variables hooks when interface is unregisted
|
|
||||||
|
|
||||||
The grub_net_network_level_interface_unregister(), previously
|
|
||||||
implemented in a header, did not remove the variables hooks that
|
|
||||||
were registered in grub_net_network_level_interface_register().
|
|
||||||
Fix this by implementing the same logic used to register the
|
|
||||||
variables and move the function into the grub-core/net/net.c.
|
|
||||||
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/net/net.c | 34 ++++++++++++++++++++++++++++++++++
|
|
||||||
include/grub/net.h | 11 +----------
|
|
||||||
2 files changed, 35 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
|
|
||||||
index c78c8694b..69223164d 100644
|
|
||||||
--- a/grub-core/net/net.c
|
|
||||||
+++ b/grub-core/net/net.c
|
|
||||||
@@ -1051,6 +1051,40 @@ grub_net_add_ipv6_local (struct grub_net_network_level_interface *inter,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+void
|
|
||||||
+grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter)
|
|
||||||
+{
|
|
||||||
+ char *name;
|
|
||||||
+
|
|
||||||
+ {
|
|
||||||
+ char buf[GRUB_NET_MAX_STR_HWADDR_LEN];
|
|
||||||
+
|
|
||||||
+ grub_net_hwaddr_to_str (&inter->hwaddress, buf);
|
|
||||||
+ name = grub_xasprintf ("net_%s_mac", inter->name);
|
|
||||||
+ if (name != NULL)
|
|
||||||
+ grub_register_variable_hook (name, NULL, NULL);
|
|
||||||
+ grub_free (name);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ {
|
|
||||||
+ char buf[GRUB_NET_MAX_STR_ADDR_LEN];
|
|
||||||
+
|
|
||||||
+ grub_net_addr_to_str (&inter->address, buf);
|
|
||||||
+ name = grub_xasprintf ("net_%s_ip", inter->name);
|
|
||||||
+ if (name != NULL)
|
|
||||||
+ grub_register_variable_hook (name, NULL, NULL);
|
|
||||||
+ grub_free (name);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ inter->card->num_ifaces--;
|
|
||||||
+ *inter->prev = inter->next;
|
|
||||||
+ if (inter->next)
|
|
||||||
+ inter->next->prev = inter->prev;
|
|
||||||
+ inter->next = 0;
|
|
||||||
+ inter->prev = 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
grub_err_t
|
|
||||||
grub_net_add_ipv4_local (struct grub_net_network_level_interface *inter,
|
|
||||||
int mask)
|
|
||||||
diff --git a/include/grub/net.h b/include/grub/net.h
|
|
||||||
index 0d31f0066..4a815fa91 100644
|
|
||||||
--- a/include/grub/net.h
|
|
||||||
+++ b/include/grub/net.h
|
|
||||||
@@ -607,16 +607,7 @@ void grub_bootp_fini (void);
|
|
||||||
void grub_dns_init (void);
|
|
||||||
void grub_dns_fini (void);
|
|
||||||
|
|
||||||
-static inline void
|
|
||||||
-grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter)
|
|
||||||
-{
|
|
||||||
- inter->card->num_ifaces--;
|
|
||||||
- *inter->prev = inter->next;
|
|
||||||
- if (inter->next)
|
|
||||||
- inter->next->prev = inter->prev;
|
|
||||||
- inter->next = 0;
|
|
||||||
- inter->prev = 0;
|
|
||||||
-}
|
|
||||||
+void grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter);
|
|
||||||
|
|
||||||
void
|
|
||||||
grub_net_tcp_retransmit (void);
|
|
@ -1,80 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Fri, 15 Nov 2024 13:12:09 +0000
|
|
||||||
Subject: [PATCH] net: Fix OOB write in grub_net_search_config_file()
|
|
||||||
|
|
||||||
The function included a call to grub_strcpy() which copied data from an
|
|
||||||
environment variable to a buffer allocated in grub_cmd_normal(). The
|
|
||||||
grub_cmd_normal() didn't consider the length of the environment variable.
|
|
||||||
So, the copy operation could exceed the allocation and lead to an OOB
|
|
||||||
write. Fix the issue by replacing grub_strcpy() with grub_strlcpy() and
|
|
||||||
pass the underlying buffers size to the grub_net_search_config_file().
|
|
||||||
|
|
||||||
Fixes: CVE-2025-0624
|
|
||||||
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/net/net.c | 7 ++++---
|
|
||||||
grub-core/normal/main.c | 2 +-
|
|
||||||
include/grub/net.h | 2 +-
|
|
||||||
3 files changed, 6 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
|
|
||||||
index 69223164d..f0896979d 100644
|
|
||||||
--- a/grub-core/net/net.c
|
|
||||||
+++ b/grub-core/net/net.c
|
|
||||||
@@ -1940,9 +1940,9 @@ grub_net_restore_hw (void)
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_err_t
|
|
||||||
-grub_net_search_configfile (char *config)
|
|
||||||
+grub_net_search_configfile (char *config, grub_size_t config_buf_len)
|
|
||||||
{
|
|
||||||
- grub_size_t config_len;
|
|
||||||
+ grub_size_t config_len, suffix_len;
|
|
||||||
char *suffix;
|
|
||||||
|
|
||||||
auto int search_through (grub_size_t num_tries, grub_size_t slice_size);
|
|
||||||
@@ -1979,6 +1979,7 @@ grub_net_search_configfile (char *config)
|
|
||||||
config_len = grub_strlen (config);
|
|
||||||
config[config_len] = '-';
|
|
||||||
suffix = config + config_len + 1;
|
|
||||||
+ suffix_len = config_buf_len - (config_len + 1);
|
|
||||||
|
|
||||||
struct grub_net_network_level_interface *inf;
|
|
||||||
FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
|
|
||||||
@@ -2004,7 +2005,7 @@ grub_net_search_configfile (char *config)
|
|
||||||
|
|
||||||
if (client_uuid)
|
|
||||||
{
|
|
||||||
- grub_strcpy (suffix, client_uuid);
|
|
||||||
+ grub_strlcpy (suffix, client_uuid, suffix_len);
|
|
||||||
if (search_through (1, 0) == 0) return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
|
||||||
index 93f33c167..f5e9b54f7 100644
|
|
||||||
--- a/grub-core/normal/main.c
|
|
||||||
+++ b/grub-core/normal/main.c
|
|
||||||
@@ -349,7 +349,7 @@ grub_try_normal_prefix (const char *prefix)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
grub_snprintf (config, config_len, "%s/grub.cfg", prefix);
|
|
||||||
- err = grub_net_search_configfile (config);
|
|
||||||
+ err = grub_net_search_configfile (config, config_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != GRUB_ERR_NONE)
|
|
||||||
diff --git a/include/grub/net.h b/include/grub/net.h
|
|
||||||
index 4a815fa91..8c8521944 100644
|
|
||||||
--- a/include/grub/net.h
|
|
||||||
+++ b/include/grub/net.h
|
|
||||||
@@ -646,6 +646,6 @@ extern char *grub_net_default_server;
|
|
||||||
#define VLANTAG_IDENTIFIER 0x8100
|
|
||||||
|
|
||||||
grub_err_t
|
|
||||||
-grub_net_search_configfile (char *config);
|
|
||||||
+grub_net_search_configfile (char *config, grub_size_t config_buf_len);
|
|
||||||
|
|
||||||
#endif /* ! GRUB_NET_HEADER */
|
|
@ -1,114 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Thu, 18 Apr 2024 17:32:34 +0100
|
|
||||||
Subject: [PATCH] net/tftp: Fix stack buffer overflow in tftp_open()
|
|
||||||
|
|
||||||
An overly long filename can be passed to tftp_open() which would cause
|
|
||||||
grub_normalize_filename() to write out of bounds.
|
|
||||||
|
|
||||||
Fixed by adding an extra argument to grub_normalize_filename() for the
|
|
||||||
space available, making it act closer to a strlcpy(). As several fixed
|
|
||||||
strings are strcpy()'d after into the same buffer, their total length is
|
|
||||||
checked to see if they exceed the remaining space in the buffer. If so,
|
|
||||||
return an error.
|
|
||||||
|
|
||||||
On the occasion simplify code a bit by removing unneeded rrqlen zeroing.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/net/tftp.c | 40 +++++++++++++++++++++++++---------------
|
|
||||||
1 file changed, 25 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
|
|
||||||
index 09e1511cc..9bc8a688d 100644
|
|
||||||
--- a/grub-core/net/tftp.c
|
|
||||||
+++ b/grub-core/net/tftp.c
|
|
||||||
@@ -267,17 +267,19 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
|
|
||||||
* forward slashes to a single forward slash.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
-grub_normalize_filename (char *normalized, const char *filename)
|
|
||||||
+grub_normalize_filename (char *normalized, const char *filename, int c)
|
|
||||||
{
|
|
||||||
char *dest = normalized;
|
|
||||||
const char *src = filename;
|
|
||||||
|
|
||||||
- while (*src != '\0')
|
|
||||||
+ while (*src != '\0' && c > 0)
|
|
||||||
{
|
|
||||||
if (src[0] == '/' && src[1] == '/')
|
|
||||||
src++;
|
|
||||||
- else
|
|
||||||
- *dest++ = *src++;
|
|
||||||
+ else {
|
|
||||||
+ c--;
|
|
||||||
+ *dest++ = *src++;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
*dest = '\0';
|
|
||||||
}
|
|
||||||
@@ -288,7 +290,7 @@ tftp_open (struct grub_file *file, const char *filename)
|
|
||||||
struct tftphdr *tftph;
|
|
||||||
char *rrq;
|
|
||||||
int i;
|
|
||||||
- int rrqlen;
|
|
||||||
+ int rrqlen, rrqsize;
|
|
||||||
int hdrlen;
|
|
||||||
grub_uint8_t open_data[1500];
|
|
||||||
struct grub_net_buff nb;
|
|
||||||
@@ -316,35 +318,43 @@ tftp_open (struct grub_file *file, const char *filename)
|
|
||||||
|
|
||||||
tftph = (struct tftphdr *) nb.data;
|
|
||||||
|
|
||||||
- rrq = (char *) tftph->u.rrq;
|
|
||||||
- rrqlen = 0;
|
|
||||||
-
|
|
||||||
tftph->opcode = grub_cpu_to_be16_compile_time (TFTP_RRQ);
|
|
||||||
|
|
||||||
+ rrq = (char *) tftph->u.rrq;
|
|
||||||
+ rrqsize = sizeof (tftph->u.rrq);
|
|
||||||
+
|
|
||||||
/* Copy and normalize the filename to work-around issues on some tftp
|
|
||||||
servers when file names are being matched for remapping. */
|
|
||||||
- grub_normalize_filename (rrq, filename);
|
|
||||||
- rrqlen += grub_strlen (rrq) + 1;
|
|
||||||
+ grub_normalize_filename (rrq, filename, rrqsize);
|
|
||||||
+
|
|
||||||
+ rrqlen = grub_strlen (rrq) + 1;
|
|
||||||
rrq += grub_strlen (rrq) + 1;
|
|
||||||
|
|
||||||
- grub_strcpy (rrq, "octet");
|
|
||||||
+ /* Verify there is enough space for the remaining components. */
|
|
||||||
rrqlen += grub_strlen ("octet") + 1;
|
|
||||||
+ rrqlen += grub_strlen ("blksize") + 1;
|
|
||||||
+ rrqlen += grub_strlen ("1024") + 1;
|
|
||||||
+ rrqlen += grub_strlen ("tsize") + 1;
|
|
||||||
+ rrqlen += grub_strlen ("0") + 1;
|
|
||||||
+
|
|
||||||
+ if (rrqlen >= rrqsize) {
|
|
||||||
+ grub_free (data);
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FILENAME, N_("filename too long"));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ grub_strcpy (rrq, "octet");
|
|
||||||
rrq += grub_strlen ("octet") + 1;
|
|
||||||
|
|
||||||
grub_strcpy (rrq, "blksize");
|
|
||||||
- rrqlen += grub_strlen ("blksize") + 1;
|
|
||||||
rrq += grub_strlen ("blksize") + 1;
|
|
||||||
|
|
||||||
grub_strcpy (rrq, "1024");
|
|
||||||
- rrqlen += grub_strlen ("1024") + 1;
|
|
||||||
rrq += grub_strlen ("1024") + 1;
|
|
||||||
|
|
||||||
grub_strcpy (rrq, "tsize");
|
|
||||||
- rrqlen += grub_strlen ("tsize") + 1;
|
|
||||||
rrq += grub_strlen ("tsize") + 1;
|
|
||||||
|
|
||||||
grub_strcpy (rrq, "0");
|
|
||||||
- rrqlen += grub_strlen ("0") + 1;
|
|
||||||
rrq += grub_strlen ("0") + 1;
|
|
||||||
hdrlen = sizeof (tftph->opcode) + rrqlen;
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Axtens <dja@axtens.net>
|
|
||||||
Date: Fri, 8 Mar 2024 22:47:20 +1100
|
|
||||||
Subject: [PATCH] video/readers/jpeg: Do not permit duplicate SOF0 markers in
|
|
||||||
JPEG
|
|
||||||
|
|
||||||
Otherwise a subsequent header could change the height and width
|
|
||||||
allowing future OOB writes.
|
|
||||||
|
|
||||||
Fixes: CVE-2024-45774
|
|
||||||
|
|
||||||
Reported-by: Nils Langius <nils@langius.de>
|
|
||||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/video/readers/jpeg.c | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
|
|
||||||
index 2da04094b..c7aaac362 100644
|
|
||||||
--- a/grub-core/video/readers/jpeg.c
|
|
||||||
+++ b/grub-core/video/readers/jpeg.c
|
|
||||||
@@ -332,6 +332,10 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
|
|
||||||
if (grub_errno != GRUB_ERR_NONE)
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
+ if (data->image_height != 0 || data->image_width != 0)
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
|
|
||||||
+ "jpeg: cannot have duplicate SOF0 markers");
|
|
||||||
+
|
|
||||||
if (grub_jpeg_get_byte (data) != 8)
|
|
||||||
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
|
|
||||||
"jpeg: only 8-bit precision is supported");
|
|
@ -1,138 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Thu, 18 Apr 2024 15:59:26 +0100
|
|
||||||
Subject: [PATCH] kern/dl: Fix for an integer overflow in grub_dl_ref()
|
|
||||||
|
|
||||||
It was possible to overflow the value of mod->ref_count, a signed
|
|
||||||
integer, by repeatedly invoking insmod on an already loaded module.
|
|
||||||
This led to a use-after-free. As once ref_count was overflowed it became
|
|
||||||
possible to unload the module while there was still references to it.
|
|
||||||
|
|
||||||
This resolves the issue by using grub_add() to check if the ref_count
|
|
||||||
will overflow and then stops further increments. Further changes were
|
|
||||||
also made to grub_dl_unref() to check for the underflow condition and
|
|
||||||
the reference count was changed to an unsigned 64-bit integer.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/commands/minicmd.c | 2 +-
|
|
||||||
grub-core/kern/dl.c | 17 ++++++++++++-----
|
|
||||||
include/grub/dl.h | 8 ++++----
|
|
||||||
util/misc.c | 4 ++--
|
|
||||||
4 files changed, 19 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
|
||||||
index 2bd3ac76f..2001043cf 100644
|
|
||||||
--- a/grub-core/commands/minicmd.c
|
|
||||||
+++ b/grub-core/commands/minicmd.c
|
|
||||||
@@ -167,7 +167,7 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)),
|
|
||||||
{
|
|
||||||
grub_dl_dep_t dep;
|
|
||||||
|
|
||||||
- grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count);
|
|
||||||
+ grub_printf ("%s\t%" PRIuGRUB_UINT64_T "\t\t", mod->name, mod->ref_count);
|
|
||||||
for (dep = mod->dep; dep; dep = dep->next)
|
|
||||||
{
|
|
||||||
if (dep != mod->dep)
|
|
||||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
|
||||||
index 68d3177f5..edbb55d7d 100644
|
|
||||||
--- a/grub-core/kern/dl.c
|
|
||||||
+++ b/grub-core/kern/dl.c
|
|
||||||
@@ -34,6 +34,7 @@
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/efi/sb.h>
|
|
||||||
#include <grub/tpm.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
/* Platforms where modules are in a readonly area of memory. */
|
|
||||||
#if defined(GRUB_MACHINE_QEMU)
|
|
||||||
@@ -595,7 +596,7 @@ grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e)
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int
|
|
||||||
+grub_uint64_t
|
|
||||||
grub_dl_ref (grub_dl_t mod)
|
|
||||||
{
|
|
||||||
grub_dl_dep_t dep;
|
|
||||||
@@ -606,10 +607,13 @@ grub_dl_ref (grub_dl_t mod)
|
|
||||||
for (dep = mod->dep; dep; dep = dep->next)
|
|
||||||
grub_dl_ref (dep->mod);
|
|
||||||
|
|
||||||
- return ++mod->ref_count;
|
|
||||||
+ if (grub_add (mod->ref_count, 1, &mod->ref_count))
|
|
||||||
+ grub_fatal ("Module reference count overflow");
|
|
||||||
+
|
|
||||||
+ return mod->ref_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int
|
|
||||||
+grub_uint64_t
|
|
||||||
grub_dl_unref (grub_dl_t mod)
|
|
||||||
{
|
|
||||||
grub_dl_dep_t dep;
|
|
||||||
@@ -620,10 +624,13 @@ grub_dl_unref (grub_dl_t mod)
|
|
||||||
for (dep = mod->dep; dep; dep = dep->next)
|
|
||||||
grub_dl_unref (dep->mod);
|
|
||||||
|
|
||||||
- return --mod->ref_count;
|
|
||||||
+ if (grub_sub (mod->ref_count, 1, &mod->ref_count))
|
|
||||||
+ grub_fatal ("Module reference count underflow");
|
|
||||||
+
|
|
||||||
+ return mod->ref_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int
|
|
||||||
+grub_uint64_t
|
|
||||||
grub_dl_ref_count (grub_dl_t mod)
|
|
||||||
{
|
|
||||||
if (mod == NULL)
|
|
||||||
diff --git a/include/grub/dl.h b/include/grub/dl.h
|
|
||||||
index 6f46b7e86..2e27ef596 100644
|
|
||||||
--- a/include/grub/dl.h
|
|
||||||
+++ b/include/grub/dl.h
|
|
||||||
@@ -177,7 +177,7 @@ typedef struct grub_dl_dep *grub_dl_dep_t;
|
|
||||||
struct grub_dl
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
- int ref_count;
|
|
||||||
+ grub_uint64_t ref_count;
|
|
||||||
int persistent;
|
|
||||||
grub_dl_dep_t dep;
|
|
||||||
grub_dl_segment_t segment;
|
|
||||||
@@ -207,9 +207,9 @@ grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
|
|
||||||
grub_dl_t EXPORT_FUNC(grub_dl_load_core_noinit) (void *addr, grub_size_t size);
|
|
||||||
int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod);
|
|
||||||
extern void grub_dl_unload_unneeded (void);
|
|
||||||
-extern int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
|
|
||||||
-extern int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod);
|
|
||||||
-extern int EXPORT_FUNC(grub_dl_ref_count) (grub_dl_t mod);
|
|
||||||
+extern grub_uint64_t EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
|
|
||||||
+extern grub_uint64_t EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod);
|
|
||||||
+extern grub_uint64_t EXPORT_FUNC(grub_dl_ref_count) (grub_dl_t mod);
|
|
||||||
|
|
||||||
extern grub_dl_t EXPORT_VAR(grub_dl_head);
|
|
||||||
|
|
||||||
diff --git a/util/misc.c b/util/misc.c
|
|
||||||
index d545212d9..0f928e5b4 100644
|
|
||||||
--- a/util/misc.c
|
|
||||||
+++ b/util/misc.c
|
|
||||||
@@ -190,14 +190,14 @@ grub_xputs_real (const char *str)
|
|
||||||
|
|
||||||
void (*grub_xputs) (const char *str) = grub_xputs_real;
|
|
||||||
|
|
||||||
-int
|
|
||||||
+grub_uint64_t
|
|
||||||
grub_dl_ref (grub_dl_t mod)
|
|
||||||
{
|
|
||||||
(void) mod;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int
|
|
||||||
+grub_uint64_t
|
|
||||||
grub_dl_unref (grub_dl_t mod)
|
|
||||||
{
|
|
||||||
(void) mod;
|
|
@ -1,34 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Thu, 7 Nov 2024 06:00:36 +0000
|
|
||||||
Subject: [PATCH] kern/dl: Check for the SHF_INFO_LINK flag in
|
|
||||||
grub_dl_relocate_symbols()
|
|
||||||
|
|
||||||
The grub_dl_relocate_symbols() iterates through the sections in
|
|
||||||
an ELF looking for relocation sections. According to the spec [1]
|
|
||||||
the SHF_INFO_LINK flag should be set if the sh_info field is meant
|
|
||||||
to be a section index.
|
|
||||||
|
|
||||||
[1] https://refspecs.linuxbase.org/elf/gabi4+/ch4.sheader.html
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/kern/dl.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
|
||||||
index edbb55d7d..e93863196 100644
|
|
||||||
--- a/grub-core/kern/dl.c
|
|
||||||
+++ b/grub-core/kern/dl.c
|
|
||||||
@@ -663,6 +663,9 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
|
||||||
grub_dl_segment_t seg;
|
|
||||||
grub_err_t err;
|
|
||||||
|
|
||||||
+ if (!(s->sh_flags & SHF_INFO_LINK))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
seg = grub_dl_find_segment(mod, s->sh_info);
|
|
||||||
if (!seg)
|
|
||||||
continue;
|
|
@ -1,34 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Fri, 22 Nov 2024 06:27:55 +0000
|
|
||||||
Subject: [PATCH] commands/extcmd: Missing check for failed allocation
|
|
||||||
|
|
||||||
The grub_extcmd_dispatcher() calls grub_arg_list_alloc() to allocate
|
|
||||||
a grub_arg_list struct but it does not verify the allocation was successful.
|
|
||||||
In case of failed allocation the NULL state pointer can be accessed in
|
|
||||||
parse_option() through grub_arg_parse() which may lead to a security issue.
|
|
||||||
|
|
||||||
Fixes: CVE-2024-45775
|
|
||||||
|
|
||||||
Reported-by: Nils Langius <nils@langius.de>
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/commands/extcmd.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c
|
|
||||||
index 90a5ca24a..c236be13a 100644
|
|
||||||
--- a/grub-core/commands/extcmd.c
|
|
||||||
+++ b/grub-core/commands/extcmd.c
|
|
||||||
@@ -49,6 +49,9 @@ grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args,
|
|
||||||
}
|
|
||||||
|
|
||||||
state = grub_arg_list_alloc (ext, argc, args);
|
|
||||||
+ if (state == NULL)
|
|
||||||
+ return grub_errno;
|
|
||||||
+
|
|
||||||
if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc))
|
|
||||||
{
|
|
||||||
context.state = state;
|
|
@ -1,32 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Sun, 12 May 2024 11:08:23 +0100
|
|
||||||
Subject: [PATCH] commands/ls: Fix NULL dereference
|
|
||||||
|
|
||||||
The grub_strrchr() may return NULL when the dirname do not contain "/".
|
|
||||||
This can happen on broken filesystems.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/commands/ls.c | 6 +++++-
|
|
||||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
|
|
||||||
index d4dcffd31..ac6936bc7 100644
|
|
||||||
--- a/grub-core/commands/ls.c
|
|
||||||
+++ b/grub-core/commands/ls.c
|
|
||||||
@@ -241,7 +241,11 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
|
||||||
|
|
||||||
grub_file_close (file);
|
|
||||||
|
|
||||||
- p = grub_strrchr (dirname, '/') + 1;
|
|
||||||
+ p = grub_strrchr (dirname, '/');
|
|
||||||
+ if (p == NULL)
|
|
||||||
+ goto fail;
|
|
||||||
+ ++p;
|
|
||||||
+
|
|
||||||
dirname = grub_strndup (dirname, p - dirname);
|
|
||||||
if (! dirname)
|
|
||||||
goto fail;
|
|
@ -1,31 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Fri, 1 Nov 2024 19:24:29 +0000
|
|
||||||
Subject: [PATCH] commands/pgp: Unregister the "check_signatures" hooks on
|
|
||||||
module unload
|
|
||||||
|
|
||||||
If the hooks are not removed they can be called after the module has
|
|
||||||
been unloaded leading to an use-after-free.
|
|
||||||
|
|
||||||
Fixes: CVE-2025-0622
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/commands/pgp.c | 2 ++
|
|
||||||
1 file changed, 2 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
|
|
||||||
index 55d354be0..15e981304 100644
|
|
||||||
--- a/grub-core/commands/pgp.c
|
|
||||||
+++ b/grub-core/commands/pgp.c
|
|
||||||
@@ -982,6 +982,8 @@ GRUB_MOD_INIT(pgp)
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(pgp)
|
|
||||||
{
|
|
||||||
+ grub_register_variable_hook ("check_signatures", NULL, NULL);
|
|
||||||
+ grub_env_unset ("check_signatures");
|
|
||||||
grub_verifier_unregister (&grub_pubkey_verifier);
|
|
||||||
grub_unregister_extcmd (cmd);
|
|
||||||
grub_unregister_extcmd (cmd_trust);
|
|
@ -1,37 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Fri, 1 Nov 2024 23:46:55 +0000
|
|
||||||
Subject: [PATCH] normal: Remove variables hooks on module unload
|
|
||||||
|
|
||||||
The normal module does not entirely cleanup after itself in
|
|
||||||
its GRUB_MOD_FINI() leaving a few variables hooks in place.
|
|
||||||
It is not possible to unload normal module now but fix the
|
|
||||||
issues for completeness.
|
|
||||||
|
|
||||||
On the occasion replace 0s with NULLs for "pager" variable
|
|
||||||
hooks unregister.
|
|
||||||
|
|
||||||
Fixes: CVE-2025-0622
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/normal/main.c | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
|
||||||
index f5e9b54f7..b61f01ae5 100644
|
|
||||||
--- a/grub-core/normal/main.c
|
|
||||||
+++ b/grub-core/normal/main.c
|
|
||||||
@@ -670,7 +670,9 @@ GRUB_MOD_FINI(normal)
|
|
||||||
grub_xputs = grub_xputs_saved;
|
|
||||||
|
|
||||||
grub_set_history (0);
|
|
||||||
- grub_register_variable_hook ("pager", 0, 0);
|
|
||||||
+ grub_register_variable_hook ("pager", NULL, NULL);
|
|
||||||
+ grub_register_variable_hook ("color_normal", NULL, NULL);
|
|
||||||
+ grub_register_variable_hook ("color_highlight", NULL, NULL);
|
|
||||||
grub_fs_autoload_hook = 0;
|
|
||||||
grub_unregister_command (cmd_clear);
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Fri, 1 Nov 2024 23:52:06 +0000
|
|
||||||
Subject: [PATCH] gettext: Remove variables hooks on module unload
|
|
||||||
|
|
||||||
The gettext module does not entirely cleanup after itself in
|
|
||||||
its GRUB_MOD_FINI() leaving a few variables hooks in place.
|
|
||||||
It is not possible to unload gettext module because normal
|
|
||||||
module depends on it. Though fix the issues for completeness.
|
|
||||||
|
|
||||||
Fixes: CVE-2025-0622
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/gettext/gettext.c | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c
|
|
||||||
index 84d520cd4..1344c7c81 100644
|
|
||||||
--- a/grub-core/gettext/gettext.c
|
|
||||||
+++ b/grub-core/gettext/gettext.c
|
|
||||||
@@ -520,6 +520,10 @@ GRUB_MOD_INIT (gettext)
|
|
||||||
|
|
||||||
GRUB_MOD_FINI (gettext)
|
|
||||||
{
|
|
||||||
+ grub_register_variable_hook ("locale_dir", NULL, NULL);
|
|
||||||
+ grub_register_variable_hook ("secondary_locale_dir", NULL, NULL);
|
|
||||||
+ grub_register_variable_hook ("lang", NULL, NULL);
|
|
||||||
+
|
|
||||||
grub_gettext_delete_list (&main_context);
|
|
||||||
grub_gettext_delete_list (&secondary_context);
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Fri, 22 Nov 2024 06:27:56 +0000
|
|
||||||
Subject: [PATCH] gettext: Integer overflow leads to heap OOB write or read
|
|
||||||
|
|
||||||
Calculation of ctx->grub_gettext_msg_list size in grub_mofile_open() may
|
|
||||||
overflow leading to subsequent OOB write or read. This patch fixes the
|
|
||||||
issue by replacing grub_zalloc() and explicit multiplication with
|
|
||||||
grub_calloc() which does the same thing in safe manner.
|
|
||||||
|
|
||||||
Fixes: CVE-2024-45776
|
|
||||||
|
|
||||||
Reported-by: Nils Langius <nils@langius.de>
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/gettext/gettext.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c
|
|
||||||
index 1344c7c81..cb304ebeb 100644
|
|
||||||
--- a/grub-core/gettext/gettext.c
|
|
||||||
+++ b/grub-core/gettext/gettext.c
|
|
||||||
@@ -323,8 +323,8 @@ grub_mofile_open (struct grub_gettext_context *ctx,
|
|
||||||
for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log;
|
|
||||||
ctx->grub_gettext_max_log++);
|
|
||||||
|
|
||||||
- ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max
|
|
||||||
- * sizeof (ctx->grub_gettext_msg_list[0]));
|
|
||||||
+ ctx->grub_gettext_msg_list = grub_calloc (ctx->grub_gettext_max,
|
|
||||||
+ sizeof (ctx->grub_gettext_msg_list[0]));
|
|
||||||
if (!ctx->grub_gettext_msg_list)
|
|
||||||
{
|
|
||||||
grub_file_close (fd);
|
|
@ -1,53 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Fri, 22 Nov 2024 06:27:57 +0000
|
|
||||||
Subject: [PATCH] gettext: Integer overflow leads to heap OOB write
|
|
||||||
|
|
||||||
The size calculation of the translation buffer in
|
|
||||||
grub_gettext_getstr_from_position() may overflow
|
|
||||||
to 0 leading to heap OOB write. This patch fixes
|
|
||||||
the issue by using grub_add() and checking for
|
|
||||||
an overflow.
|
|
||||||
|
|
||||||
Fixes: CVE-2024-45777
|
|
||||||
|
|
||||||
Reported-by: Nils Langius <nils@langius.de>
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/gettext/gettext.c | 7 ++++++-
|
|
||||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c
|
|
||||||
index cb304ebeb..9654bb3fd 100644
|
|
||||||
--- a/grub-core/gettext/gettext.c
|
|
||||||
+++ b/grub-core/gettext/gettext.c
|
|
||||||
@@ -26,6 +26,7 @@
|
|
||||||
#include <grub/file.h>
|
|
||||||
#include <grub/kernel.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -99,6 +100,7 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx,
|
|
||||||
char *translation;
|
|
||||||
struct string_descriptor desc;
|
|
||||||
grub_err_t err;
|
|
||||||
+ grub_size_t alloc_sz;
|
|
||||||
|
|
||||||
internal_position = (off + position * sizeof (desc));
|
|
||||||
|
|
||||||
@@ -109,7 +111,10 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx,
|
|
||||||
length = grub_cpu_to_le32 (desc.length);
|
|
||||||
offset = grub_cpu_to_le32 (desc.offset);
|
|
||||||
|
|
||||||
- translation = grub_malloc (length + 1);
|
|
||||||
+ if (grub_add (length, 1, &alloc_sz))
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ translation = grub_malloc (alloc_sz);
|
|
||||||
if (!translation)
|
|
||||||
return NULL;
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jonathan Bar Or <jonathanbaror@gmail.com>
|
|
||||||
Date: Thu, 23 Jan 2025 19:17:05 +0100
|
|
||||||
Subject: [PATCH] commands/read: Fix an integer overflow when supplying more
|
|
||||||
than 2^31 characters
|
|
||||||
|
|
||||||
The grub_getline() function currently has a signed integer variable "i"
|
|
||||||
that can be overflown when user supplies more than 2^31 characters.
|
|
||||||
It results in a memory corruption of the allocated line buffer as well
|
|
||||||
as supplying large negative values to grub_realloc().
|
|
||||||
|
|
||||||
Fixes: CVE-2025-0690
|
|
||||||
|
|
||||||
Reported-by: Jonathan Bar Or <jonathanbaror@gmail.com>
|
|
||||||
Signed-off-by: Jonathan Bar Or <jonathanbaror@gmail.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/commands/read.c | 20 ++++++++++++++++----
|
|
||||||
1 file changed, 16 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/commands/read.c b/grub-core/commands/read.c
|
|
||||||
index fe3e88b15..7b6735b79 100644
|
|
||||||
--- a/grub-core/commands/read.c
|
|
||||||
+++ b/grub-core/commands/read.c
|
|
||||||
@@ -25,19 +25,21 @@
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/command.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
static char *
|
|
||||||
grub_getline (void)
|
|
||||||
{
|
|
||||||
- int i;
|
|
||||||
+ grub_size_t i;
|
|
||||||
char *line;
|
|
||||||
char *tmp;
|
|
||||||
char c;
|
|
||||||
+ grub_size_t alloc_size;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
- line = grub_malloc (1 + i + sizeof('\0'));
|
|
||||||
+ line = grub_malloc (1 + sizeof('\0'));
|
|
||||||
if (! line)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
@@ -50,8 +52,18 @@ grub_getline (void)
|
|
||||||
line[i] = c;
|
|
||||||
if (grub_isprint (c))
|
|
||||||
grub_printf ("%c", c);
|
|
||||||
- i++;
|
|
||||||
- tmp = grub_realloc (line, 1 + i + sizeof('\0'));
|
|
||||||
+ if (grub_add (i, 1, &i))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ if (grub_add (i, 1 + sizeof('\0'), &alloc_size))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ tmp = grub_realloc (line, alloc_size);
|
|
||||||
+
|
|
||||||
if (! tmp)
|
|
||||||
{
|
|
||||||
grub_free (line);
|
|
@ -1,83 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Mon, 16 Dec 2024 20:22:41 +0000
|
|
||||||
Subject: [PATCH] commands/test: Stack overflow due to unlimited recursion
|
|
||||||
depth
|
|
||||||
|
|
||||||
The test_parse() evaluates test expression recursively. Due to lack of
|
|
||||||
recursion depth check a specially crafted expression may cause a stack
|
|
||||||
overflow. The recursion is only triggered by the parentheses usage and
|
|
||||||
it can be unlimited. However, sensible expressions are unlikely to
|
|
||||||
contain more than a few parentheses. So, this patch limits the recursion
|
|
||||||
depth to 100, which should be sufficient.
|
|
||||||
|
|
||||||
Reported-by: Nils Langius <nils@langius.de>
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/commands/test.c | 21 ++++++++++++++++++---
|
|
||||||
1 file changed, 18 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/commands/test.c b/grub-core/commands/test.c
|
|
||||||
index 13c6ed953..0a6f51bf3 100644
|
|
||||||
--- a/grub-core/commands/test.c
|
|
||||||
+++ b/grub-core/commands/test.c
|
|
||||||
@@ -29,6 +29,9 @@
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
+/* Set a limit on recursion to avoid stack overflow. */
|
|
||||||
+#define MAX_TEST_RECURSION_DEPTH 100
|
|
||||||
+
|
|
||||||
/* A simple implementation for signed numbers. */
|
|
||||||
static int
|
|
||||||
grub_strtosl (char *arg, char **end, int base)
|
|
||||||
@@ -150,7 +153,7 @@ get_fileinfo (char *path, struct test_parse_ctx *ctx)
|
|
||||||
|
|
||||||
/* Parse a test expression starting from *argn. */
|
|
||||||
static int
|
|
||||||
-test_parse (char **args, int *argn, int argc)
|
|
||||||
+test_parse (char **args, int *argn, int argc, int *depth)
|
|
||||||
{
|
|
||||||
struct test_parse_ctx ctx = {
|
|
||||||
.and = 1,
|
|
||||||
@@ -387,13 +390,24 @@ test_parse (char **args, int *argn, int argc)
|
|
||||||
if (grub_strcmp (args[*argn], ")") == 0)
|
|
||||||
{
|
|
||||||
(*argn)++;
|
|
||||||
+ if (*depth > 0)
|
|
||||||
+ (*depth)--;
|
|
||||||
+
|
|
||||||
return ctx.or || ctx.and;
|
|
||||||
}
|
|
||||||
/* Recursively invoke if parenthesis. */
|
|
||||||
if (grub_strcmp (args[*argn], "(") == 0)
|
|
||||||
{
|
|
||||||
(*argn)++;
|
|
||||||
- update_val (test_parse (args, argn, argc), &ctx);
|
|
||||||
+
|
|
||||||
+ if (++(*depth) > MAX_TEST_RECURSION_DEPTH)
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("max recursion depth exceeded"));
|
|
||||||
+ depth--;
|
|
||||||
+ return ctx.or || ctx.and;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ update_val (test_parse (args, argn, argc, depth), &ctx);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -428,11 +442,12 @@ grub_cmd_test (grub_command_t cmd __attribute__ ((unused)),
|
|
||||||
int argc, char **args)
|
|
||||||
{
|
|
||||||
int argn = 0;
|
|
||||||
+ int depth = 0;
|
|
||||||
|
|
||||||
if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
|
|
||||||
argc--;
|
|
||||||
|
|
||||||
- return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
|
|
||||||
+ return test_parse (args, &argn, argc, &depth) ? GRUB_ERR_NONE
|
|
||||||
: grub_error (GRUB_ERR_TEST_FAILURE, N_("false"));
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Thu, 18 Apr 2024 20:29:39 +0100
|
|
||||||
Subject: [PATCH] commands/minicmd: Block the dump command in lockdown mode
|
|
||||||
|
|
||||||
The dump enables a user to read memory which should not be possible
|
|
||||||
in lockdown mode.
|
|
||||||
|
|
||||||
Fixes: CVE-2025-1118
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Reported-by: Jonathan Bar Or <jonathanbaror@gmail.com>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/commands/minicmd.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
|
||||||
index 2001043cf..9efb7718c 100644
|
|
||||||
--- a/grub-core/commands/minicmd.c
|
|
||||||
+++ b/grub-core/commands/minicmd.c
|
|
||||||
@@ -215,8 +215,8 @@ GRUB_MOD_INIT(minicmd)
|
|
||||||
grub_register_command ("help", grub_mini_cmd_help,
|
|
||||||
0, N_("Show this message."));
|
|
||||||
cmd_dump =
|
|
||||||
- grub_register_command ("dump", grub_mini_cmd_dump,
|
|
||||||
- N_("ADDR [SIZE]"), N_("Show memory contents."));
|
|
||||||
+ grub_register_command_lockdown ("dump", grub_mini_cmd_dump,
|
|
||||||
+ N_("ADDR [SIZE]"), N_("Show memory contents."));
|
|
||||||
cmd_rmmod =
|
|
||||||
grub_register_command ("rmmod", grub_mini_cmd_rmmod,
|
|
||||||
N_("MODULE"), N_("Remove a module."));
|
|
@ -1,50 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Thu, 18 Apr 2024 20:37:10 +0100
|
|
||||||
Subject: [PATCH] commands/memrw: Disable memory reading in lockdown mode
|
|
||||||
|
|
||||||
With the rest of module being blocked in lockdown mode it does not make
|
|
||||||
a lot of sense to leave memory reading enabled. This also goes in par
|
|
||||||
with disabling the dump command.
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/commands/memrw.c | 21 ++++++++++++---------
|
|
||||||
1 file changed, 12 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c
|
|
||||||
index d401a6db0..3542683d1 100644
|
|
||||||
--- a/grub-core/commands/memrw.c
|
|
||||||
+++ b/grub-core/commands/memrw.c
|
|
||||||
@@ -122,17 +122,20 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv)
|
|
||||||
GRUB_MOD_INIT(memrw)
|
|
||||||
{
|
|
||||||
cmd_read_byte =
|
|
||||||
- grub_register_extcmd ("read_byte", grub_cmd_read, 0,
|
|
||||||
- N_("ADDR"), N_("Read 8-bit value from ADDR."),
|
|
||||||
- options);
|
|
||||||
+ grub_register_extcmd_lockdown ("read_byte", grub_cmd_read, 0,
|
|
||||||
+ N_("ADDR"),
|
|
||||||
+ N_("Read 8-bit value from ADDR."),
|
|
||||||
+ options);
|
|
||||||
cmd_read_word =
|
|
||||||
- grub_register_extcmd ("read_word", grub_cmd_read, 0,
|
|
||||||
- N_("ADDR"), N_("Read 16-bit value from ADDR."),
|
|
||||||
- options);
|
|
||||||
+ grub_register_extcmd_lockdown ("read_word", grub_cmd_read, 0,
|
|
||||||
+ N_("ADDR"),
|
|
||||||
+ N_("Read 16-bit value from ADDR."),
|
|
||||||
+ options);
|
|
||||||
cmd_read_dword =
|
|
||||||
- grub_register_extcmd ("read_dword", grub_cmd_read, 0,
|
|
||||||
- N_("ADDR"), N_("Read 32-bit value from ADDR."),
|
|
||||||
- options);
|
|
||||||
+ grub_register_extcmd_lockdown ("read_dword", grub_cmd_read, 0,
|
|
||||||
+ N_("ADDR"),
|
|
||||||
+ N_("Read 32-bit value from ADDR."),
|
|
||||||
+ options);
|
|
||||||
cmd_write_byte =
|
|
||||||
grub_register_command_lockdown ("write_byte", grub_cmd_write,
|
|
||||||
N_("ADDR VALUE [MASK]"),
|
|
@ -1,37 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: B Horn <b@horn.uk>
|
|
||||||
Date: Fri, 19 Apr 2024 22:31:45 +0100
|
|
||||||
Subject: [PATCH] commands/hexdump: Disable memory reading in lockdown mode
|
|
||||||
|
|
||||||
Reported-by: B Horn <b@horn.uk>
|
|
||||||
Signed-off-by: B Horn <b@horn.uk>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/commands/hexdump.c | 7 ++++++-
|
|
||||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/commands/hexdump.c b/grub-core/commands/hexdump.c
|
|
||||||
index eaa12465b..d6f61d98a 100644
|
|
||||||
--- a/grub-core/commands/hexdump.c
|
|
||||||
+++ b/grub-core/commands/hexdump.c
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
#include <grub/lib/hexdump.h>
|
|
||||||
#include <grub/extcmd.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -51,7 +52,11 @@ grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args)
|
|
||||||
length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256;
|
|
||||||
|
|
||||||
if (!grub_strcmp (args[0], "(mem)"))
|
|
||||||
- hexdump (skip, (char *) (grub_addr_t) skip, length);
|
|
||||||
+ {
|
|
||||||
+ if (grub_is_lockdown() == GRUB_LOCKDOWN_ENABLED)
|
|
||||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("memory reading is disabled in lockdown mode"));
|
|
||||||
+ hexdump (skip, (char *) (grub_addr_t) skip, length);
|
|
||||||
+ }
|
|
||||||
else if ((args[0][0] == '(') && (args[0][namelen - 1] == ')'))
|
|
||||||
{
|
|
||||||
grub_disk_t disk;
|
|
@ -1,52 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Axtens <dja@axtens.net>
|
|
||||||
Date: Sat, 23 Mar 2024 15:59:43 +1100
|
|
||||||
Subject: [PATCH] fs/bfs: Disable under lockdown
|
|
||||||
|
|
||||||
The BFS is not fuzz-clean. Don't allow it to be loaded under lockdown.
|
|
||||||
This will also disable the AFS.
|
|
||||||
|
|
||||||
Fixes: CVE-2024-45778
|
|
||||||
Fixes: CVE-2024-45779
|
|
||||||
|
|
||||||
Reported-by: Nils Langius <nils@langius.de>
|
|
||||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/bfs.c | 11 ++++++++---
|
|
||||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c
|
|
||||||
index 6afdfc987..e70aaa448 100644
|
|
||||||
--- a/grub-core/fs/bfs.c
|
|
||||||
+++ b/grub-core/fs/bfs.c
|
|
||||||
@@ -30,6 +30,7 @@
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -1104,8 +1105,11 @@ GRUB_MOD_INIT (bfs)
|
|
||||||
{
|
|
||||||
COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE ==
|
|
||||||
sizeof (struct grub_bfs_extent));
|
|
||||||
- grub_bfs_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_bfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_bfs_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_bfs_fs);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MODE_AFS
|
|
||||||
@@ -1114,5 +1118,6 @@ GRUB_MOD_FINI (afs)
|
|
||||||
GRUB_MOD_FINI (bfs)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_bfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_bfs_fs);
|
|
||||||
}
|
|
@ -1,391 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Axtens <dja@axtens.net>
|
|
||||||
Date: Sat, 23 Mar 2024 16:20:45 +1100
|
|
||||||
Subject: [PATCH] fs: Disable many filesystems under lockdown
|
|
||||||
|
|
||||||
The idea is to permit the following: btrfs, cpio, exfat, ext, f2fs, fat,
|
|
||||||
hfsplus, iso9660, squash4, tar, xfs and zfs.
|
|
||||||
|
|
||||||
The JFS, ReiserFS, romfs, UDF and UFS security vulnerabilities were
|
|
||||||
reported by Jonathan Bar Or <jonathanbaror@gmail.com>.
|
|
||||||
|
|
||||||
Fixes: CVE-2025-0677
|
|
||||||
Fixes: CVE-2025-0684
|
|
||||||
Fixes: CVE-2025-0685
|
|
||||||
Fixes: CVE-2025-0686
|
|
||||||
Fixes: CVE-2025-0689
|
|
||||||
|
|
||||||
Suggested-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/affs.c | 11 ++++++++---
|
|
||||||
grub-core/fs/cbfs.c | 11 ++++++++---
|
|
||||||
grub-core/fs/jfs.c | 11 ++++++++---
|
|
||||||
grub-core/fs/minix.c | 11 ++++++++---
|
|
||||||
grub-core/fs/nilfs2.c | 11 ++++++++---
|
|
||||||
grub-core/fs/ntfs.c | 11 ++++++++---
|
|
||||||
grub-core/fs/reiserfs.c | 11 ++++++++---
|
|
||||||
grub-core/fs/romfs.c | 11 ++++++++---
|
|
||||||
grub-core/fs/sfs.c | 11 ++++++++---
|
|
||||||
grub-core/fs/udf.c | 11 ++++++++---
|
|
||||||
grub-core/fs/ufs.c | 11 ++++++++---
|
|
||||||
11 files changed, 88 insertions(+), 33 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
|
|
||||||
index 6347ca368..2a850632e 100644
|
|
||||||
--- a/grub-core/fs/affs.c
|
|
||||||
+++ b/grub-core/fs/affs.c
|
|
||||||
@@ -26,6 +26,7 @@
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
#include <grub/charset.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -699,12 +700,16 @@ static struct grub_fs grub_affs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(affs)
|
|
||||||
{
|
|
||||||
- grub_affs_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_affs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_affs_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_affs_fs);
|
|
||||||
+ }
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(affs)
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_affs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_affs_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/cbfs.c b/grub-core/fs/cbfs.c
|
|
||||||
index 395edcbbd..c82980375 100644
|
|
||||||
--- a/grub-core/fs/cbfs.c
|
|
||||||
+++ b/grub-core/fs/cbfs.c
|
|
||||||
@@ -26,6 +26,7 @@
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/cbfs_core.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -390,13 +391,17 @@ GRUB_MOD_INIT (cbfs)
|
|
||||||
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
|
|
||||||
init_cbfsdisk ();
|
|
||||||
#endif
|
|
||||||
- grub_cbfs_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_cbfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_cbfs_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_cbfs_fs);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI (cbfs)
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_cbfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_cbfs_fs);
|
|
||||||
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
|
|
||||||
fini_cbfsdisk ();
|
|
||||||
#endif
|
|
||||||
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
|
|
||||||
index 46941248b..e08771b44 100644
|
|
||||||
--- a/grub-core/fs/jfs.c
|
|
||||||
+++ b/grub-core/fs/jfs.c
|
|
||||||
@@ -26,6 +26,7 @@
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/charset.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -998,12 +999,16 @@ static struct grub_fs grub_jfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(jfs)
|
|
||||||
{
|
|
||||||
- grub_jfs_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_jfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_jfs_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_jfs_fs);
|
|
||||||
+ }
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(jfs)
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_jfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_jfs_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c
|
|
||||||
index 28571c49e..38e658763 100644
|
|
||||||
--- a/grub-core/fs/minix.c
|
|
||||||
+++ b/grub-core/fs/minix.c
|
|
||||||
@@ -25,6 +25,7 @@
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -716,8 +717,11 @@ GRUB_MOD_INIT(minix)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
- grub_minix_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_minix_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_minix_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_minix_fs);
|
|
||||||
+ }
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -739,5 +743,6 @@ GRUB_MOD_FINI(minix)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_minix_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_minix_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
|
|
||||||
index 3c1e4d1f6..6d1e25fb6 100644
|
|
||||||
--- a/grub-core/fs/nilfs2.c
|
|
||||||
+++ b/grub-core/fs/nilfs2.c
|
|
||||||
@@ -34,6 +34,7 @@
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -1231,12 +1232,16 @@ GRUB_MOD_INIT (nilfs2)
|
|
||||||
grub_nilfs2_dat_entry));
|
|
||||||
COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE
|
|
||||||
== sizeof (struct grub_nilfs2_inode));
|
|
||||||
- grub_nilfs2_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_nilfs2_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_nilfs2_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_nilfs2_fs);
|
|
||||||
+ }
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI (nilfs2)
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_nilfs2_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_nilfs2_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
|
||||||
index 9244e95dd..1ad3a2715 100644
|
|
||||||
--- a/grub-core/fs/ntfs.c
|
|
||||||
+++ b/grub-core/fs/ntfs.c
|
|
||||||
@@ -27,6 +27,7 @@
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
#include <grub/ntfs.h>
|
|
||||||
#include <grub/charset.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -1537,12 +1538,16 @@ static struct grub_fs grub_ntfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (ntfs)
|
|
||||||
{
|
|
||||||
- grub_ntfs_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_ntfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_ntfs_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_ntfs_fs);
|
|
||||||
+ }
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI (ntfs)
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_ntfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_ntfs_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c
|
|
||||||
index e65b81467..72e724f4c 100644
|
|
||||||
--- a/grub-core/fs/reiserfs.c
|
|
||||||
+++ b/grub-core/fs/reiserfs.c
|
|
||||||
@@ -39,6 +39,7 @@
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -1407,12 +1408,16 @@ static struct grub_fs grub_reiserfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(reiserfs)
|
|
||||||
{
|
|
||||||
- grub_reiserfs_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_reiserfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_reiserfs_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_reiserfs_fs);
|
|
||||||
+ }
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(reiserfs)
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_reiserfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_reiserfs_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c
|
|
||||||
index f282cff86..d7817cdc5 100644
|
|
||||||
--- a/grub-core/fs/romfs.c
|
|
||||||
+++ b/grub-core/fs/romfs.c
|
|
||||||
@@ -23,6 +23,7 @@
|
|
||||||
#include <grub/disk.h>
|
|
||||||
#include <grub/fs.h>
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -475,11 +476,15 @@ static struct grub_fs grub_romfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(romfs)
|
|
||||||
{
|
|
||||||
- grub_romfs_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_romfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_romfs_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_romfs_fs);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(romfs)
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_romfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_romfs_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
|
|
||||||
index c6b9fb49a..a272aea0a 100644
|
|
||||||
--- a/grub-core/fs/sfs.c
|
|
||||||
+++ b/grub-core/fs/sfs.c
|
|
||||||
@@ -26,6 +26,7 @@
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
#include <grub/charset.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
@@ -779,12 +780,16 @@ static struct grub_fs grub_sfs_fs =
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(sfs)
|
|
||||||
{
|
|
||||||
- grub_sfs_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_sfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_sfs_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_sfs_fs);
|
|
||||||
+ }
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(sfs)
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_sfs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_sfs_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
|
|
||||||
index 8db2b5686..406260901 100644
|
|
||||||
--- a/grub-core/fs/udf.c
|
|
||||||
+++ b/grub-core/fs/udf.c
|
|
||||||
@@ -27,6 +27,7 @@
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
#include <grub/charset.h>
|
|
||||||
#include <grub/datetime.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
#include <grub/udf.h>
|
|
||||||
#include <grub/safemath.h>
|
|
||||||
|
|
||||||
@@ -1382,12 +1383,16 @@ static struct grub_fs grub_udf_fs = {
|
|
||||||
|
|
||||||
GRUB_MOD_INIT (udf)
|
|
||||||
{
|
|
||||||
- grub_udf_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_udf_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_udf_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_udf_fs);
|
|
||||||
+ }
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI (udf)
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_udf_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_udf_fs);
|
|
||||||
}
|
|
||||||
diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c
|
|
||||||
index a2c63d646..844a439f8 100644
|
|
||||||
--- a/grub-core/fs/ufs.c
|
|
||||||
+++ b/grub-core/fs/ufs.c
|
|
||||||
@@ -25,6 +25,7 @@
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/lockdown.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -899,8 +900,11 @@ GRUB_MOD_INIT(ufs1)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
- grub_ufs_fs.mod = mod;
|
|
||||||
- grub_fs_register (&grub_ufs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ {
|
|
||||||
+ grub_ufs_fs.mod = mod;
|
|
||||||
+ grub_fs_register (&grub_ufs_fs);
|
|
||||||
+ }
|
|
||||||
my_mod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -914,6 +918,7 @@ GRUB_MOD_FINI(ufs1)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
- grub_fs_unregister (&grub_ufs_fs);
|
|
||||||
+ if (!grub_is_lockdown ())
|
|
||||||
+ grub_fs_unregister (&grub_ufs_fs);
|
|
||||||
}
|
|
||||||
|
|
@ -1,367 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 02:55:09 +0000
|
|
||||||
Subject: [PATCH] disk: Use safe math macros to prevent overflows
|
|
||||||
|
|
||||||
Replace direct arithmetic operations with macros from include/grub/safemath.h
|
|
||||||
to prevent potential overflow issues when calculating the memory sizes.
|
|
||||||
|
|
||||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/disk/cryptodisk.c | 36 ++++++++++++++++++------
|
|
||||||
grub-core/disk/diskfilter.c | 9 ++++--
|
|
||||||
grub-core/disk/ieee1275/ofdisk.c | 60 ++++++++++++++++++++++++++++++++++------
|
|
||||||
grub-core/disk/ldm.c | 37 +++++++++++++++++++++----
|
|
||||||
grub-core/disk/memdisk.c | 7 ++++-
|
|
||||||
5 files changed, 123 insertions(+), 26 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
|
||||||
index 78a902515..871640685 100644
|
|
||||||
--- a/grub-core/disk/cryptodisk.c
|
|
||||||
+++ b/grub-core/disk/cryptodisk.c
|
|
||||||
@@ -26,6 +26,7 @@
|
|
||||||
#include <grub/file.h>
|
|
||||||
#include <grub/procfs.h>
|
|
||||||
#include <grub/partition.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
|
||||||
#include <grub/emu/hostdisk.h>
|
|
||||||
@@ -1039,7 +1040,7 @@ static char *
|
|
||||||
luks_script_get (grub_size_t *sz)
|
|
||||||
{
|
|
||||||
grub_cryptodisk_t i;
|
|
||||||
- grub_size_t size = 0;
|
|
||||||
+ grub_size_t size = 0, mul;
|
|
||||||
char *ptr, *ret;
|
|
||||||
|
|
||||||
*sz = 0;
|
|
||||||
@@ -1047,16 +1048,33 @@ luks_script_get (grub_size_t *sz)
|
|
||||||
for (i = cryptodisk_list; i != NULL; i = i->next)
|
|
||||||
if (grub_strcmp (i->modname, "luks") == 0)
|
|
||||||
{
|
|
||||||
- size += sizeof ("luks_mount ");
|
|
||||||
- size += grub_strlen (i->uuid);
|
|
||||||
- size += grub_strlen (i->cipher->cipher->name);
|
|
||||||
- size += 54;
|
|
||||||
- if (i->essiv_hash)
|
|
||||||
- size += grub_strlen (i->essiv_hash->name);
|
|
||||||
- size += i->keysize * 2;
|
|
||||||
+ if (grub_add (size, grub_strlen (i->modname), &size) ||
|
|
||||||
+ grub_add (size, sizeof ("_mount") + 60, &size) ||
|
|
||||||
+ grub_add (size, grub_strlen (i->uuid), &size) ||
|
|
||||||
+ grub_add (size, grub_strlen (i->cipher->cipher->name), &size) ||
|
|
||||||
+ grub_mul (i->keysize, 2, &mul) ||
|
|
||||||
+ grub_add (size, mul, &size))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining size of luks script");
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ if (i->essiv_hash)
|
|
||||||
+ {
|
|
||||||
+ if (grub_add (size, grub_strlen (i->essiv_hash->name), &size))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining size of luks script");
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = grub_malloc (size + 1);
|
|
||||||
+ if (grub_add (size, 1, &size))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining size of luks script");
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = grub_malloc (size);
|
|
||||||
if (!ret)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
|
||||||
index 2be019269..a881aa2c9 100644
|
|
||||||
--- a/grub-core/disk/diskfilter.c
|
|
||||||
+++ b/grub-core/disk/diskfilter.c
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
#include <grub/misc.h>
|
|
||||||
#include <grub/diskfilter.h>
|
|
||||||
#include <grub/partition.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
#ifdef GRUB_UTIL
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/util/misc.h>
|
|
||||||
@@ -1013,7 +1014,7 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
|
||||||
{
|
|
||||||
struct grub_diskfilter_vg *array;
|
|
||||||
int i;
|
|
||||||
- grub_size_t j;
|
|
||||||
+ grub_size_t j, sz;
|
|
||||||
grub_uint64_t totsize;
|
|
||||||
struct grub_diskfilter_pv *pv;
|
|
||||||
grub_err_t err;
|
|
||||||
@@ -1107,7 +1108,11 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb,
|
|
||||||
}
|
|
||||||
array->lvs->vg = array;
|
|
||||||
|
|
||||||
- array->lvs->idname = grub_malloc (sizeof ("mduuid/") + 2 * uuidlen);
|
|
||||||
+ if (grub_mul (uuidlen, 2, &sz) ||
|
|
||||||
+ grub_add (sz, sizeof ("mduuid/"), &sz))
|
|
||||||
+ goto fail;
|
|
||||||
+
|
|
||||||
+ array->lvs->idname = grub_malloc (sz);
|
|
||||||
if (!array->lvs->idname)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
|
||||||
index 98325ca98..c1b07d087 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/safemath.h>
|
|
||||||
|
|
||||||
static char *last_devpath;
|
|
||||||
static grub_ieee1275_ihandle_t last_ihandle;
|
|
||||||
@@ -80,6 +81,7 @@ ofdisk_hash_add_real (char *devpath)
|
|
||||||
struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
|
|
||||||
const char *iptr;
|
|
||||||
char *optr;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
p = grub_zalloc (sizeof (*p));
|
|
||||||
if (!p)
|
|
||||||
@@ -87,8 +89,14 @@ ofdisk_hash_add_real (char *devpath)
|
|
||||||
|
|
||||||
p->devpath = devpath;
|
|
||||||
|
|
||||||
- p->grub_devpath = grub_malloc (sizeof ("ieee1275/")
|
|
||||||
- + 2 * grub_strlen (p->devpath));
|
|
||||||
+ if (grub_mul (grub_strlen (p->devpath), 2, &sz) ||
|
|
||||||
+ grub_add (sz, sizeof ("ieee1275/"), &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device path"));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ p->grub_devpath = grub_malloc (sz);
|
|
||||||
|
|
||||||
if (!p->grub_devpath)
|
|
||||||
{
|
|
||||||
@@ -98,7 +106,13 @@ ofdisk_hash_add_real (char *devpath)
|
|
||||||
|
|
||||||
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
|
|
||||||
{
|
|
||||||
- p->open_path = grub_malloc (grub_strlen (p->devpath) + 3);
|
|
||||||
+ if (grub_add (grub_strlen (p->devpath), 3, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of an open path"));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ p->open_path = grub_malloc (sz);
|
|
||||||
if (!p->open_path)
|
|
||||||
{
|
|
||||||
grub_free (p->grub_devpath);
|
|
||||||
@@ -224,7 +238,7 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
|
||||||
args;
|
|
||||||
char *buf, *bufptr;
|
|
||||||
unsigned i;
|
|
||||||
-
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
RETRY_IEEE1275_OFDISK_OPEN(alias->path, &ihandle)
|
|
||||||
if (! ihandle)
|
|
||||||
@@ -245,7 +259,14 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
- buf = grub_malloc (grub_strlen (alias->path) + 32);
|
|
||||||
+ if (grub_add (grub_strlen (alias->path), 32, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while creating buffer for vscsi");
|
|
||||||
+ grub_ieee1275_close (ihandle);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ buf = grub_malloc (sz);
|
|
||||||
if (!buf)
|
|
||||||
return;
|
|
||||||
bufptr = grub_stpcpy (buf, alias->path);
|
|
||||||
@@ -289,9 +310,15 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
|
||||||
grub_uint64_t *table;
|
|
||||||
grub_uint16_t table_size;
|
|
||||||
grub_ieee1275_ihandle_t ihandle;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
- buf = grub_malloc (grub_strlen (alias->path) +
|
|
||||||
- sizeof ("/disk@7766554433221100"));
|
|
||||||
+ if (grub_add (grub_strlen (alias->path), sizeof ("/disk@7766554433221100"), &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while creating buffer for sas_ioa");
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ buf = grub_malloc (sz);
|
|
||||||
if (!buf)
|
|
||||||
return;
|
|
||||||
bufptr = grub_stpcpy (buf, alias->path);
|
|
||||||
@@ -431,9 +458,17 @@ grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
|
|
||||||
static char *
|
|
||||||
compute_dev_path (const char *name)
|
|
||||||
{
|
|
||||||
- char *devpath = grub_malloc (grub_strlen (name) + 3);
|
|
||||||
+ char *devpath;
|
|
||||||
char *p, c;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
+ if (grub_add (grub_strlen (name), 3, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining size of device path"));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ devpath = grub_malloc (sz);
|
|
||||||
if (!devpath)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
@@ -660,6 +695,7 @@ insert_bootpath (void)
|
|
||||||
char *bootpath;
|
|
||||||
grub_ssize_t bootpath_size;
|
|
||||||
char *type;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath",
|
|
||||||
&bootpath_size)
|
|
||||||
@@ -670,7 +706,13 @@ insert_bootpath (void)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
- bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
|
|
||||||
+ if (grub_add (bootpath_size, 64, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining bootpath size"));
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ bootpath = (char *) grub_malloc (sz);
|
|
||||||
if (! bootpath)
|
|
||||||
{
|
|
||||||
grub_print_error ();
|
|
||||||
diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
|
|
||||||
index e82e9899f..973fbfdcb 100644
|
|
||||||
--- a/grub-core/disk/ldm.c
|
|
||||||
+++ b/grub-core/disk/ldm.c
|
|
||||||
@@ -220,6 +220,7 @@ make_vg (grub_disk_t disk,
|
|
||||||
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
|
|
||||||
/ sizeof (struct grub_ldm_vblk)];
|
|
||||||
unsigned i;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
err = grub_disk_read (disk, cursec, 0,
|
|
||||||
sizeof(vblk), &vblk);
|
|
||||||
if (err)
|
|
||||||
@@ -251,7 +252,13 @@ make_vg (grub_disk_t disk,
|
|
||||||
grub_free (pv);
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
- pv->internal_id = grub_malloc (ptr[0] + 2);
|
|
||||||
+ if (grub_add (ptr[0], 2, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_free (pv);
|
|
||||||
+ goto fail2;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pv->internal_id = grub_malloc (sz);
|
|
||||||
if (!pv->internal_id)
|
|
||||||
{
|
|
||||||
grub_free (pv);
|
|
||||||
@@ -276,7 +283,15 @@ make_vg (grub_disk_t disk,
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
pv->id.uuidlen = *ptr;
|
|
||||||
- pv->id.uuid = grub_malloc (pv->id.uuidlen + 1);
|
|
||||||
+
|
|
||||||
+ if (grub_add (pv->id.uuidlen, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_free (pv->internal_id);
|
|
||||||
+ grub_free (pv);
|
|
||||||
+ goto fail2;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pv->id.uuid = grub_malloc (sz);
|
|
||||||
grub_memcpy (pv->id.uuid, ptr + 1, pv->id.uuidlen);
|
|
||||||
pv->id.uuid[pv->id.uuidlen] = 0;
|
|
||||||
|
|
||||||
@@ -343,7 +358,13 @@ make_vg (grub_disk_t disk,
|
|
||||||
grub_free (lv);
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
- lv->internal_id = grub_malloc ((grub_size_t) ptr[0] + 2);
|
|
||||||
+ if (grub_add (ptr[0], 2, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_free (lv->segments);
|
|
||||||
+ grub_free (lv);
|
|
||||||
+ goto fail2;
|
|
||||||
+ }
|
|
||||||
+ lv->internal_id = grub_malloc (sz);
|
|
||||||
if (!lv->internal_id)
|
|
||||||
{
|
|
||||||
grub_free (lv);
|
|
||||||
@@ -455,6 +476,7 @@ make_vg (grub_disk_t disk,
|
|
||||||
struct grub_ldm_vblk vblk[GRUB_DISK_SECTOR_SIZE
|
|
||||||
/ sizeof (struct grub_ldm_vblk)];
|
|
||||||
unsigned i;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
err = grub_disk_read (disk, cursec, 0,
|
|
||||||
sizeof(vblk), &vblk);
|
|
||||||
if (err)
|
|
||||||
@@ -489,7 +511,13 @@ make_vg (grub_disk_t disk,
|
|
||||||
{
|
|
||||||
goto fail2;
|
|
||||||
}
|
|
||||||
- comp->internal_id = grub_malloc ((grub_size_t) ptr[0] + 2);
|
|
||||||
+ if (grub_add (ptr[0], 2, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_free (comp);
|
|
||||||
+ goto fail2;
|
|
||||||
+ }
|
|
||||||
+ comp->internal_id = grub_malloc (sz);
|
|
||||||
+
|
|
||||||
if (!comp->internal_id)
|
|
||||||
{
|
|
||||||
grub_free (comp);
|
|
||||||
@@ -639,7 +667,6 @@ make_vg (grub_disk_t disk,
|
|
||||||
if (lv->segments->node_alloc == lv->segments->node_count)
|
|
||||||
{
|
|
||||||
void *t;
|
|
||||||
- grub_size_t sz;
|
|
||||||
|
|
||||||
if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
|
|
||||||
grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz))
|
|
||||||
diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c
|
|
||||||
index e5ffc01bf..18863305e 100644
|
|
||||||
--- a/grub-core/disk/memdisk.c
|
|
||||||
+++ b/grub-core/disk/memdisk.c
|
|
||||||
@@ -23,6 +23,7 @@
|
|
||||||
#include <grub/misc.h>
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -96,7 +97,11 @@ GRUB_MOD_INIT(memdisk)
|
|
||||||
|
|
||||||
grub_dprintf ("memdisk", "Found memdisk image at %p\n", memdisk_orig_addr);
|
|
||||||
|
|
||||||
- memdisk_size = header->size - sizeof (struct grub_module_header);
|
|
||||||
+ if (grub_sub (header->size, sizeof (struct grub_module_header), &memdisk_size))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "underflow detected while obtaining memdisk size");
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
memdisk_addr = grub_malloc (memdisk_size);
|
|
||||||
|
|
||||||
grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n");
|
|
@ -1,38 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 02:55:10 +0000
|
|
||||||
Subject: [PATCH] disk: Prevent overflows when allocating memory for arrays
|
|
||||||
|
|
||||||
Use grub_calloc() when allocating memory for arrays to ensure proper
|
|
||||||
overflow checks are in place.
|
|
||||||
|
|
||||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/disk/lvm.c | 6 ++----
|
|
||||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
|
|
||||||
index 7e86bb7df..47a89e6d0 100644
|
|
||||||
--- a/grub-core/disk/lvm.c
|
|
||||||
+++ b/grub-core/disk/lvm.c
|
|
||||||
@@ -634,8 +634,7 @@ error_parsing_metadata:
|
|
||||||
goto lvs_segment_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
- seg->nodes = grub_zalloc (sizeof (seg->nodes[0])
|
|
||||||
- * seg->node_count);
|
|
||||||
+ seg->nodes = grub_calloc (seg->node_count, sizeof (seg->nodes[0]));
|
|
||||||
|
|
||||||
p = grub_strstr (p, "mirrors = [");
|
|
||||||
if (p == NULL)
|
|
||||||
@@ -723,8 +722,7 @@ error_parsing_metadata:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- seg->nodes = grub_zalloc (sizeof (seg->nodes[0])
|
|
||||||
- * seg->node_count);
|
|
||||||
+ seg->nodes = grub_calloc (seg->node_count, sizeof (seg->nodes[0]));
|
|
||||||
|
|
||||||
p = grub_strstr (p, "raids = [");
|
|
||||||
if (p == NULL)
|
|
@ -1,134 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 02:55:11 +0000
|
|
||||||
Subject: [PATCH] disk: Check if returned pointer for allocated memory is NULL
|
|
||||||
|
|
||||||
When using grub_malloc(), grub_zalloc() or grub_calloc(), these functions can
|
|
||||||
fail if we are out of memory. After allocating memory we should check if these
|
|
||||||
functions returned NULL and handle this error if they did.
|
|
||||||
|
|
||||||
On the occasion make a NULL check in ATA code more obvious.
|
|
||||||
|
|
||||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/disk/ata.c | 4 ++--
|
|
||||||
grub-core/disk/ldm.c | 6 ++++++
|
|
||||||
grub-core/disk/lvm.c | 14 ++++++++++++++
|
|
||||||
grub-core/disk/memdisk.c | 2 ++
|
|
||||||
4 files changed, 24 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/disk/ata.c b/grub-core/disk/ata.c
|
|
||||||
index 8ba4e5c50..65d24103e 100644
|
|
||||||
--- a/grub-core/disk/ata.c
|
|
||||||
+++ b/grub-core/disk/ata.c
|
|
||||||
@@ -112,10 +112,10 @@ grub_ata_identify (struct grub_ata *dev)
|
|
||||||
return grub_atapi_identify (dev);
|
|
||||||
|
|
||||||
info64 = grub_malloc (GRUB_DISK_SECTOR_SIZE);
|
|
||||||
+ if (info64 == NULL)
|
|
||||||
+ return grub_errno;
|
|
||||||
info32 = (grub_uint32_t *) info64;
|
|
||||||
info16 = (grub_uint16_t *) info64;
|
|
||||||
- if (! info16)
|
|
||||||
- return grub_errno;
|
|
||||||
|
|
||||||
grub_memset (&parms, 0, sizeof (parms));
|
|
||||||
parms.buffer = info16;
|
|
||||||
diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
|
|
||||||
index 973fbfdcb..1510fb35a 100644
|
|
||||||
--- a/grub-core/disk/ldm.c
|
|
||||||
+++ b/grub-core/disk/ldm.c
|
|
||||||
@@ -292,6 +292,12 @@ make_vg (grub_disk_t disk,
|
|
||||||
}
|
|
||||||
|
|
||||||
pv->id.uuid = grub_malloc (sz);
|
|
||||||
+ if (pv->id.uuid == NULL)
|
|
||||||
+ {
|
|
||||||
+ grub_free (pv->internal_id);
|
|
||||||
+ grub_free (pv);
|
|
||||||
+ goto fail2;
|
|
||||||
+ }
|
|
||||||
grub_memcpy (pv->id.uuid, ptr + 1, pv->id.uuidlen);
|
|
||||||
pv->id.uuid[pv->id.uuidlen] = 0;
|
|
||||||
|
|
||||||
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
|
|
||||||
index 47a89e6d0..4fce7f226 100644
|
|
||||||
--- a/grub-core/disk/lvm.c
|
|
||||||
+++ b/grub-core/disk/lvm.c
|
|
||||||
@@ -332,6 +332,8 @@ error_parsing_metadata:
|
|
||||||
break;
|
|
||||||
|
|
||||||
pv = grub_zalloc (sizeof (*pv));
|
|
||||||
+ if (pv == NULL)
|
|
||||||
+ goto fail4;
|
|
||||||
q = p;
|
|
||||||
while (*q != ' ' && q < mda_end)
|
|
||||||
q++;
|
|
||||||
@@ -341,6 +343,8 @@ error_parsing_metadata:
|
|
||||||
|
|
||||||
s = q - p;
|
|
||||||
pv->name = grub_malloc (s + 1);
|
|
||||||
+ if (pv->name == NULL)
|
|
||||||
+ goto pvs_fail_noname;
|
|
||||||
grub_memcpy (pv->name, p, s);
|
|
||||||
pv->name[s] = '\0';
|
|
||||||
|
|
||||||
@@ -413,6 +417,8 @@ error_parsing_metadata:
|
|
||||||
break;
|
|
||||||
|
|
||||||
lv = grub_zalloc (sizeof (*lv));
|
|
||||||
+ if (lv == NULL)
|
|
||||||
+ goto fail4;
|
|
||||||
|
|
||||||
q = p;
|
|
||||||
while (*q != ' ' && q < mda_end)
|
|
||||||
@@ -508,6 +514,8 @@ error_parsing_metadata:
|
|
||||||
goto lvs_fail;
|
|
||||||
}
|
|
||||||
lv->segments = grub_calloc (lv->segment_count, sizeof (*seg));
|
|
||||||
+ if (lv->segments == NULL)
|
|
||||||
+ goto lvs_fail;
|
|
||||||
seg = lv->segments;
|
|
||||||
|
|
||||||
for (i = 0; i < lv->segment_count; i++)
|
|
||||||
@@ -575,6 +583,8 @@ error_parsing_metadata:
|
|
||||||
|
|
||||||
seg->nodes = grub_calloc (seg->node_count,
|
|
||||||
sizeof (*stripe));
|
|
||||||
+ if (seg->nodes == NULL)
|
|
||||||
+ goto lvs_segment_fail;
|
|
||||||
stripe = seg->nodes;
|
|
||||||
|
|
||||||
p = grub_strstr (p, "stripes = [");
|
|
||||||
@@ -635,6 +645,8 @@ error_parsing_metadata:
|
|
||||||
}
|
|
||||||
|
|
||||||
seg->nodes = grub_calloc (seg->node_count, sizeof (seg->nodes[0]));
|
|
||||||
+ if (seg->nodes == NULL)
|
|
||||||
+ goto lvs_segment_fail;
|
|
||||||
|
|
||||||
p = grub_strstr (p, "mirrors = [");
|
|
||||||
if (p == NULL)
|
|
||||||
@@ -723,6 +735,8 @@ error_parsing_metadata:
|
|
||||||
}
|
|
||||||
|
|
||||||
seg->nodes = grub_calloc (seg->node_count, sizeof (seg->nodes[0]));
|
|
||||||
+ if (seg->nodes == NULL)
|
|
||||||
+ goto lvs_segment_fail;
|
|
||||||
|
|
||||||
p = grub_strstr (p, "raids = [");
|
|
||||||
if (p == NULL)
|
|
||||||
diff --git a/grub-core/disk/memdisk.c b/grub-core/disk/memdisk.c
|
|
||||||
index 18863305e..63fc8f1a6 100644
|
|
||||||
--- a/grub-core/disk/memdisk.c
|
|
||||||
+++ b/grub-core/disk/memdisk.c
|
|
||||||
@@ -103,6 +103,8 @@ GRUB_MOD_INIT(memdisk)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memdisk_addr = grub_malloc (memdisk_size);
|
|
||||||
+ if (memdisk_addr == NULL)
|
|
||||||
+ return;
|
|
||||||
|
|
||||||
grub_dprintf ("memdisk", "Copying memdisk image to dynamic memory\n");
|
|
||||||
grub_memmove (memdisk_addr, memdisk_orig_addr, memdisk_size);
|
|
@ -1,31 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 02:55:12 +0000
|
|
||||||
Subject: [PATCH] disk/ieee1275/ofdisk: Call grub_ieee1275_close() when
|
|
||||||
grub_malloc() fails
|
|
||||||
|
|
||||||
In the dev_iterate() function a handle is opened but isn't closed when
|
|
||||||
grub_malloc() returns NULL. We should fix this by closing it on error.
|
|
||||||
|
|
||||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/disk/ieee1275/ofdisk.c | 5 ++++-
|
|
||||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
|
||||||
index c1b07d087..c50614f03 100644
|
|
||||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
|
||||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
|
||||||
@@ -268,7 +268,10 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
|
||||||
|
|
||||||
buf = grub_malloc (sz);
|
|
||||||
if (!buf)
|
|
||||||
- return;
|
|
||||||
+ {
|
|
||||||
+ grub_ieee1275_close (ihandle);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
bufptr = grub_stpcpy (buf, alias->path);
|
|
||||||
|
|
||||||
for (i = 0; i < args.nentries; i++)
|
|
@ -1,353 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Tue, 21 Jan 2025 19:02:36 +0000
|
|
||||||
Subject: [PATCH] fs: Use safe math macros to prevent overflows
|
|
||||||
|
|
||||||
Replace direct arithmetic operations with macros from include/grub/safemath.h
|
|
||||||
to prevent potential overflow issues when calculating the memory sizes.
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/archelp.c | 9 ++++++++-
|
|
||||||
grub-core/fs/btrfs.c | 34 ++++++++++++++++++++++++++++------
|
|
||||||
grub-core/fs/cpio_common.c | 16 ++++++++++++++--
|
|
||||||
grub-core/fs/f2fs.c | 17 +++++++++++++++--
|
|
||||||
grub-core/fs/ntfscomp.c | 9 ++++++++-
|
|
||||||
grub-core/fs/squash4.c | 12 +++++++++---
|
|
||||||
grub-core/fs/xfs.c | 17 +++++++++++++++--
|
|
||||||
7 files changed, 97 insertions(+), 17 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/archelp.c b/grub-core/fs/archelp.c
|
|
||||||
index 0cf544f6f..6491f74f9 100644
|
|
||||||
--- a/grub-core/fs/archelp.c
|
|
||||||
+++ b/grub-core/fs/archelp.c
|
|
||||||
@@ -21,6 +21,7 @@
|
|
||||||
#include <grub/fs.h>
|
|
||||||
#include <grub/disk.h>
|
|
||||||
#include <grub/dl.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ handle_symlink (struct grub_archelp_data *data,
|
|
||||||
char *rest;
|
|
||||||
char *linktarget;
|
|
||||||
grub_size_t linktarget_len;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
*restart = 0;
|
|
||||||
|
|
||||||
@@ -98,7 +100,12 @@ handle_symlink (struct grub_archelp_data *data,
|
|
||||||
if (linktarget[0] == '\0')
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
linktarget_len = grub_strlen (linktarget);
|
|
||||||
- target = grub_malloc (linktarget_len + grub_strlen (*name) + 2);
|
|
||||||
+
|
|
||||||
+ if (grub_add (linktarget_len, grub_strlen (*name), &sz) ||
|
|
||||||
+ grub_add (sz, 2, &sz))
|
|
||||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("link target length overflow"));
|
|
||||||
+
|
|
||||||
+ target = grub_malloc (sz);
|
|
||||||
if (!target)
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
|
|
||||||
index 65213549e..646543f5d 100644
|
|
||||||
--- a/grub-core/fs/btrfs.c
|
|
||||||
+++ b/grub-core/fs/btrfs.c
|
|
||||||
@@ -1500,6 +1500,7 @@ find_path (struct grub_btrfs_data *data,
|
|
||||||
char *origpath = NULL;
|
|
||||||
unsigned symlinks_max = 32;
|
|
||||||
const char *relpath = grub_env_get ("btrfs_relative_path");
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
follow_default = 0;
|
|
||||||
origpath = grub_strdup (path);
|
|
||||||
@@ -1626,9 +1627,15 @@ find_path (struct grub_btrfs_data *data,
|
|
||||||
struct grub_btrfs_dir_item *cdirel;
|
|
||||||
if (elemsize > allocated)
|
|
||||||
{
|
|
||||||
- allocated = 2 * elemsize;
|
|
||||||
+ if (grub_mul (2, elemsize, &allocated) ||
|
|
||||||
+ grub_add (allocated, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_free (path_alloc);
|
|
||||||
+ grub_free (origpath);
|
|
||||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory item size overflow"));
|
|
||||||
+ }
|
|
||||||
grub_free (direl);
|
|
||||||
- direl = grub_malloc (allocated + 1);
|
|
||||||
+ direl = grub_malloc (sz);
|
|
||||||
if (!direl)
|
|
||||||
{
|
|
||||||
grub_free (path_alloc);
|
|
||||||
@@ -1692,8 +1699,16 @@ find_path (struct grub_btrfs_data *data,
|
|
||||||
grub_free (origpath);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
- tmp = grub_malloc (grub_le_to_cpu64 (inode.size)
|
|
||||||
- + grub_strlen (path) + 1);
|
|
||||||
+
|
|
||||||
+ if (grub_add (grub_le_to_cpu64 (inode.size), grub_strlen (path), &sz) ||
|
|
||||||
+ grub_add (sz, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_free (direl);
|
|
||||||
+ grub_free (path_alloc);
|
|
||||||
+ grub_free (origpath);
|
|
||||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("buffer size overflow"));
|
|
||||||
+ }
|
|
||||||
+ tmp = grub_malloc (sz);
|
|
||||||
if (!tmp)
|
|
||||||
{
|
|
||||||
grub_free (direl);
|
|
||||||
@@ -1835,6 +1850,7 @@ grub_btrfs_dir (grub_device_t device, const char *path,
|
|
||||||
grub_uint8_t type;
|
|
||||||
char *new_path = NULL;
|
|
||||||
grub_size_t est_size = 0;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return grub_errno;
|
|
||||||
@@ -1884,9 +1900,15 @@ grub_btrfs_dir (grub_device_t device, const char *path,
|
|
||||||
}
|
|
||||||
if (elemsize > allocated)
|
|
||||||
{
|
|
||||||
- allocated = 2 * elemsize;
|
|
||||||
+ if (grub_mul (2, elemsize, &allocated) ||
|
|
||||||
+ grub_add (allocated, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory element size overflow"));
|
|
||||||
+ r = -grub_errno;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
grub_free (direl);
|
|
||||||
- direl = grub_malloc (allocated + 1);
|
|
||||||
+ direl = grub_malloc (sz);
|
|
||||||
if (!direl)
|
|
||||||
{
|
|
||||||
r = -grub_errno;
|
|
||||||
diff --git a/grub-core/fs/cpio_common.c b/grub-core/fs/cpio_common.c
|
|
||||||
index 50fea47d1..5760072c5 100644
|
|
||||||
--- a/grub-core/fs/cpio_common.c
|
|
||||||
+++ b/grub-core/fs/cpio_common.c
|
|
||||||
@@ -24,6 +24,7 @@
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
#include <grub/archelp.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
struct head hd;
|
|
||||||
grub_size_t namesize;
|
|
||||||
grub_uint32_t modeval;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
data->hofs = data->next_hofs;
|
|
||||||
|
|
||||||
@@ -71,7 +73,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
|
|
||||||
*mode = modeval;
|
|
||||||
|
|
||||||
- *name = grub_malloc (namesize + 1);
|
|
||||||
+ if (grub_add (namesize, 1, &sz))
|
|
||||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("file name size overflow"));
|
|
||||||
+
|
|
||||||
+ *name = grub_malloc (sz);
|
|
||||||
if (*name == NULL)
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
@@ -101,10 +106,17 @@ grub_cpio_get_link_target (struct grub_archelp_data *data)
|
|
||||||
{
|
|
||||||
char *ret;
|
|
||||||
grub_err_t err;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
if (data->size == 0)
|
|
||||||
return grub_strdup ("");
|
|
||||||
- ret = grub_malloc (data->size + 1);
|
|
||||||
+
|
|
||||||
+ if (grub_add (data->size, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("target data size overflow"));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ ret = grub_malloc (sz);
|
|
||||||
if (!ret)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
|
|
||||||
index 149f33695..0af62f1a1 100644
|
|
||||||
--- a/grub-core/fs/f2fs.c
|
|
||||||
+++ b/grub-core/fs/f2fs.c
|
|
||||||
@@ -28,6 +28,7 @@
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/charset.h>
|
|
||||||
#include <grub/fshelp.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -953,6 +954,7 @@ grub_f2fs_read_symlink (grub_fshelp_node_t node)
|
|
||||||
char *symlink;
|
|
||||||
struct grub_fshelp_node *diro = node;
|
|
||||||
grub_uint64_t filesize;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
if (!diro->inode_read)
|
|
||||||
{
|
|
||||||
@@ -963,7 +965,12 @@ grub_f2fs_read_symlink (grub_fshelp_node_t node)
|
|
||||||
|
|
||||||
filesize = grub_f2fs_file_size(&diro->inode.i);
|
|
||||||
|
|
||||||
- symlink = grub_malloc (filesize + 1);
|
|
||||||
+ if (grub_add (filesize, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow"));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ symlink = grub_malloc (sz);
|
|
||||||
if (!symlink)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
@@ -992,6 +999,7 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx)
|
|
||||||
enum FILE_TYPE ftype;
|
|
||||||
int name_len;
|
|
||||||
int ret;
|
|
||||||
+ int sz;
|
|
||||||
|
|
||||||
if (grub_f2fs_test_bit_le (i, ctx->bitmap) == 0)
|
|
||||||
{
|
|
||||||
@@ -1005,7 +1013,12 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx)
|
|
||||||
if (name_len >= F2FS_NAME_LEN)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- filename = grub_malloc (name_len + 1);
|
|
||||||
+ if (grub_add (name_len, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory entry name length overflow"));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ filename = grub_malloc (sz);
|
|
||||||
if (!filename)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c
|
|
||||||
index 3cd97d337..4bf95c85d 100644
|
|
||||||
--- a/grub-core/fs/ntfscomp.c
|
|
||||||
+++ b/grub-core/fs/ntfscomp.c
|
|
||||||
@@ -22,6 +22,7 @@
|
|
||||||
#include <grub/disk.h>
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/ntfs.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -310,6 +311,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
|
|
||||||
{
|
|
||||||
grub_err_t ret;
|
|
||||||
grub_disk_addr_t vcn;
|
|
||||||
+ int log_sz;
|
|
||||||
|
|
||||||
if (ctx->attr->sbuf)
|
|
||||||
{
|
|
||||||
@@ -349,7 +351,12 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->comp.comp_head = ctx->comp.comp_tail = 0;
|
|
||||||
- ctx->comp.cbuf = grub_malloc (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR));
|
|
||||||
+ if (grub_add (ctx->comp.log_spc, GRUB_NTFS_BLK_SHR, &log_sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("compression buffer size overflow"));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ ctx->comp.cbuf = grub_malloc (1 << log_sz);
|
|
||||||
if (!ctx->comp.cbuf)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
|
|
||||||
index 1505832d5..4fe843935 100644
|
|
||||||
--- a/grub-core/fs/squash4.c
|
|
||||||
+++ b/grub-core/fs/squash4.c
|
|
||||||
@@ -460,11 +460,11 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
|
|
||||||
{
|
|
||||||
char *ret;
|
|
||||||
grub_err_t err;
|
|
||||||
- grub_size_t sz;
|
|
||||||
+ grub_uint32_t sz;
|
|
||||||
|
|
||||||
if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz))
|
|
||||||
{
|
|
||||||
- grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink name length overflow"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -577,6 +577,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
struct grub_squash_dirent di;
|
|
||||||
struct grub_squash_inode ino;
|
|
||||||
grub_size_t sz;
|
|
||||||
+ grub_uint16_t nlen;
|
|
||||||
|
|
||||||
err = read_chunk (dir->data, &di, sizeof (di),
|
|
||||||
grub_le_to_cpu64 (dir->data->sb.diroffset)
|
|
||||||
@@ -592,7 +593,12 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
|
|
||||||
if (err)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2);
|
|
||||||
+ if (grub_add (grub_le_to_cpu16 (di.namelen), 2, &nlen))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow"));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ buf = grub_malloc (nlen);
|
|
||||||
if (!buf)
|
|
||||||
return 0;
|
|
||||||
err = read_chunk (dir->data, buf,
|
|
||||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
|
||||||
index 5b7643eb1..b0d371ee1 100644
|
|
||||||
--- a/grub-core/fs/xfs.c
|
|
||||||
+++ b/grub-core/fs/xfs.c
|
|
||||||
@@ -647,6 +647,7 @@ static char *
|
|
||||||
grub_xfs_read_symlink (grub_fshelp_node_t node)
|
|
||||||
{
|
|
||||||
grub_ssize_t size = grub_be_to_cpu64 (node->inode.size);
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
if (size < 0)
|
|
||||||
{
|
|
||||||
@@ -668,7 +669,12 @@ grub_xfs_read_symlink (grub_fshelp_node_t node)
|
|
||||||
if (node->data->hascrc)
|
|
||||||
off = 56;
|
|
||||||
|
|
||||||
- symlink = grub_malloc (size + 1);
|
|
||||||
+ if (grub_add (size, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow"));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ symlink = grub_malloc (sz);
|
|
||||||
if (!symlink)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
@@ -718,8 +724,15 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
|
|
||||||
{
|
|
||||||
struct grub_fshelp_node *fdiro;
|
|
||||||
grub_err_t err;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
- fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1);
|
|
||||||
+ if (grub_add (grub_xfs_fshelp_size(ctx->diro->data), 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory data size overflow"));
|
|
||||||
+ grub_print_error ();
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ fdiro = grub_malloc (sz);
|
|
||||||
if (!fdiro)
|
|
||||||
{
|
|
||||||
grub_print_error ();
|
|
@ -1,82 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Tue, 21 Jan 2025 19:02:37 +0000
|
|
||||||
Subject: [PATCH] fs: Prevent overflows when allocating memory for arrays
|
|
||||||
|
|
||||||
Use grub_calloc() when allocating memory for arrays to ensure proper
|
|
||||||
overflow checks are in place.
|
|
||||||
|
|
||||||
The HFS+ and squash4 security vulnerabilities were reported by
|
|
||||||
Jonathan Bar Or <jonathanbaror@gmail.com>.
|
|
||||||
|
|
||||||
Fixes: CVE-2025-0678
|
|
||||||
Fixes: CVE-2025-1125
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/btrfs.c | 4 ++--
|
|
||||||
grub-core/fs/hfspluscomp.c | 9 +++++++--
|
|
||||||
grub-core/fs/squash4.c | 8 ++++----
|
|
||||||
3 files changed, 13 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
|
|
||||||
index 646543f5d..83336f606 100644
|
|
||||||
--- a/grub-core/fs/btrfs.c
|
|
||||||
+++ b/grub-core/fs/btrfs.c
|
|
||||||
@@ -1015,8 +1015,8 @@ grub_btrfs_mount (grub_device_t dev)
|
|
||||||
}
|
|
||||||
|
|
||||||
data->n_devices_allocated = 16;
|
|
||||||
- data->devices_attached = grub_malloc (sizeof (data->devices_attached[0])
|
|
||||||
- * data->n_devices_allocated);
|
|
||||||
+ data->devices_attached = grub_calloc (data->n_devices_allocated,
|
|
||||||
+ sizeof (data->devices_attached[0]));
|
|
||||||
if (!data->devices_attached)
|
|
||||||
{
|
|
||||||
grub_free (data);
|
|
||||||
diff --git a/grub-core/fs/hfspluscomp.c b/grub-core/fs/hfspluscomp.c
|
|
||||||
index d76f3f137..4965ef19a 100644
|
|
||||||
--- a/grub-core/fs/hfspluscomp.c
|
|
||||||
+++ b/grub-core/fs/hfspluscomp.c
|
|
||||||
@@ -244,14 +244,19 @@ hfsplus_open_compressed_real (struct grub_hfsplus_file *node)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
node->compress_index_size = grub_le_to_cpu32 (index_size);
|
|
||||||
- node->compress_index = grub_malloc (node->compress_index_size
|
|
||||||
- * sizeof (node->compress_index[0]));
|
|
||||||
+ node->compress_index = grub_calloc (node->compress_index_size,
|
|
||||||
+ sizeof (node->compress_index[0]));
|
|
||||||
if (!node->compress_index)
|
|
||||||
{
|
|
||||||
node->compressed = 0;
|
|
||||||
grub_free (attr_node);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * The node->compress_index_size * sizeof (node->compress_index[0]) is safe here
|
|
||||||
+ * due to relevant checks done in grub_calloc() above.
|
|
||||||
+ */
|
|
||||||
if (grub_hfsplus_read_file (node, 0, 0,
|
|
||||||
0x104 + sizeof (index_size),
|
|
||||||
node->compress_index_size
|
|
||||||
diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
|
|
||||||
index 4fe843935..b145bb9cd 100644
|
|
||||||
--- a/grub-core/fs/squash4.c
|
|
||||||
+++ b/grub-core/fs/squash4.c
|
|
||||||
@@ -810,10 +810,10 @@ direct_read (struct grub_squash_data *data,
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
total_blocks = ((total_size + data->blksz - 1) >> data->log2_blksz);
|
|
||||||
- ino->block_sizes = grub_malloc (total_blocks
|
|
||||||
- * sizeof (ino->block_sizes[0]));
|
|
||||||
- ino->cumulated_block_sizes = grub_malloc (total_blocks
|
|
||||||
- * sizeof (ino->cumulated_block_sizes[0]));
|
|
||||||
+ ino->block_sizes = grub_calloc (total_blocks,
|
|
||||||
+ sizeof (ino->block_sizes[0]));
|
|
||||||
+ ino->cumulated_block_sizes = grub_calloc (total_blocks,
|
|
||||||
+ sizeof (ino->cumulated_block_sizes[0]));
|
|
||||||
if (!ino->block_sizes || !ino->cumulated_block_sizes)
|
|
||||||
{
|
|
||||||
grub_free (ino->block_sizes);
|
|
@ -1,105 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Tue, 21 Jan 2025 19:02:38 +0000
|
|
||||||
Subject: [PATCH] fs: Prevent overflows when assigning returned values from
|
|
||||||
read_number()
|
|
||||||
|
|
||||||
The direct assignment of the unsigned long long value returned by
|
|
||||||
read_number() can potentially lead to an overflow on a 32-bit systems.
|
|
||||||
The fix replaces the direct assignments with calls to grub_cast()
|
|
||||||
which detects the overflows and safely assigns the values if no
|
|
||||||
overflow is detected.
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/cpio_common.c | 18 ++++++++++++++----
|
|
||||||
grub-core/fs/tar.c | 23 ++++++++++++++++-------
|
|
||||||
2 files changed, 30 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/cpio_common.c b/grub-core/fs/cpio_common.c
|
|
||||||
index 5760072c5..bcb038025 100644
|
|
||||||
--- a/grub-core/fs/cpio_common.c
|
|
||||||
+++ b/grub-core/fs/cpio_common.c
|
|
||||||
@@ -57,11 +57,21 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
|
|
||||||
- data->size = read_number (hd.filesize, ARRAY_SIZE (hd.filesize));
|
|
||||||
+
|
|
||||||
+ if (grub_cast (read_number (hd.filesize, ARRAY_SIZE (hd.filesize)), &data->size))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("data size overflow"));
|
|
||||||
+
|
|
||||||
if (mtime)
|
|
||||||
- *mtime = read_number (hd.mtime, ARRAY_SIZE (hd.mtime));
|
|
||||||
- modeval = read_number (hd.mode, ARRAY_SIZE (hd.mode));
|
|
||||||
- namesize = read_number (hd.namesize, ARRAY_SIZE (hd.namesize));
|
|
||||||
+ {
|
|
||||||
+ if (grub_cast (read_number (hd.mtime, ARRAY_SIZE (hd.mtime)), mtime))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("mtime overflow"));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (grub_cast (read_number (hd.mode, ARRAY_SIZE (hd.mode)), &modeval))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("mode overflow"));
|
|
||||||
+
|
|
||||||
+ if (grub_cast (read_number (hd.namesize, ARRAY_SIZE (hd.namesize)), &namesize))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("namesize overflow"));
|
|
||||||
|
|
||||||
/* Don't allow negative numbers. */
|
|
||||||
if (namesize >= 0x80000000)
|
|
||||||
diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
|
|
||||||
index 01738ec55..b8f121828 100644
|
|
||||||
--- a/grub-core/fs/tar.c
|
|
||||||
+++ b/grub-core/fs/tar.c
|
|
||||||
@@ -99,9 +99,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
if (hd.typeflag == 'L')
|
|
||||||
{
|
|
||||||
grub_err_t err;
|
|
||||||
- grub_size_t namesize = read_number (hd.size, sizeof (hd.size));
|
|
||||||
+ grub_size_t namesize;
|
|
||||||
|
|
||||||
- if (grub_add (namesize, 1, &sz))
|
|
||||||
+ if (grub_cast (read_number (hd.size, sizeof (hd.size)), &namesize) ||
|
|
||||||
+ grub_add (namesize, 1, &sz))
|
|
||||||
return grub_error (GRUB_ERR_BAD_FS, N_("name size overflow"));
|
|
||||||
|
|
||||||
*name = grub_malloc (sz);
|
|
||||||
@@ -123,9 +124,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
if (hd.typeflag == 'K')
|
|
||||||
{
|
|
||||||
grub_err_t err;
|
|
||||||
- grub_size_t linksize = read_number (hd.size, sizeof (hd.size));
|
|
||||||
+ grub_size_t linksize;
|
|
||||||
|
|
||||||
- if (grub_add (linksize, 1, &sz))
|
|
||||||
+ if (grub_cast (read_number (hd.size, sizeof (hd.size)), &linksize) ||
|
|
||||||
+ grub_add (linksize, 1, &sz))
|
|
||||||
return grub_error (GRUB_ERR_BAD_FS, N_("link size overflow"));
|
|
||||||
|
|
||||||
if (data->linkname_alloc < sz)
|
|
||||||
@@ -174,15 +176,22 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
|
|
||||||
(*name)[extra_size + sizeof (hd.name)] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- data->size = read_number (hd.size, sizeof (hd.size));
|
|
||||||
+ if (grub_cast (read_number (hd.size, sizeof (hd.size)), &data->size))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("data size overflow"));
|
|
||||||
+
|
|
||||||
data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
|
|
||||||
data->next_hofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
|
|
||||||
~(GRUB_DISK_SECTOR_SIZE - 1));
|
|
||||||
if (mtime)
|
|
||||||
- *mtime = read_number (hd.mtime, sizeof (hd.mtime));
|
|
||||||
+ {
|
|
||||||
+ if (grub_cast (read_number (hd.mtime, sizeof (hd.mtime)), mtime))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("mtime overflow"));
|
|
||||||
+ }
|
|
||||||
if (mode)
|
|
||||||
{
|
|
||||||
- *mode = read_number (hd.mode, sizeof (hd.mode));
|
|
||||||
+ if (grub_cast (read_number (hd.mode, sizeof (hd.mode)), mode))
|
|
||||||
+ return grub_error (GRUB_ERR_BAD_FS, N_("mode overflow"));
|
|
||||||
+
|
|
||||||
switch (hd.typeflag)
|
|
||||||
{
|
|
||||||
/* Hardlink. */
|
|
@ -1,139 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 07:17:02 +0000
|
|
||||||
Subject: [PATCH] fs/zfs: Use safe math macros to prevent overflows
|
|
||||||
|
|
||||||
Replace direct arithmetic operations with macros from include/grub/safemath.h
|
|
||||||
to prevent potential overflow issues when calculating the memory sizes.
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/zfs/zfs.c | 51 +++++++++++++++++++++++++++++++++++++++++++-------
|
|
||||||
1 file changed, 44 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
|
|
||||||
index 0c4b15f08..4384d6aae 100644
|
|
||||||
--- a/grub-core/fs/zfs/zfs.c
|
|
||||||
+++ b/grub-core/fs/zfs/zfs.c
|
|
||||||
@@ -2380,6 +2380,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
|
|
||||||
zap_dnode->endian) << DNODE_SHIFT);
|
|
||||||
grub_err_t err;
|
|
||||||
grub_zfs_endian_t endian;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
if (zap_verify (zap, zap_dnode->endian))
|
|
||||||
return 0;
|
|
||||||
@@ -2441,8 +2442,14 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
|
|
||||||
if (le->le_type != ZAP_CHUNK_ENTRY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
- buf = grub_malloc (grub_zfs_to_cpu16 (le->le_name_length, endian)
|
|
||||||
- * name_elem_length + 1);
|
|
||||||
+ if (grub_mul (grub_zfs_to_cpu16 (le->le_name_length, endian), name_elem_length, &sz) ||
|
|
||||||
+ grub_add (sz, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("buffer size overflow"));
|
|
||||||
+ grub_free (l);
|
|
||||||
+ return grub_errno;
|
|
||||||
+ }
|
|
||||||
+ buf = grub_malloc (sz);
|
|
||||||
if (zap_leaf_array_get (l, endian, blksft,
|
|
||||||
grub_zfs_to_cpu16 (le->le_name_chunk,
|
|
||||||
endian),
|
|
||||||
@@ -2863,6 +2870,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
|
|
||||||
&& ((grub_zfs_to_cpu64(((znode_phys_t *) DN_BONUS (&dnode_path->dn.dn))->zp_mode, dnode_path->dn.endian) >> 12) & 0xf) == 0xa)
|
|
||||||
{
|
|
||||||
char *sym_value;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
grub_size_t sym_sz;
|
|
||||||
int free_symval = 0;
|
|
||||||
char *oldpath = path, *oldpathbuf = path_buf;
|
|
||||||
@@ -2914,7 +2922,17 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
|
|
||||||
break;
|
|
||||||
free_symval = 1;
|
|
||||||
}
|
|
||||||
- path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1);
|
|
||||||
+ if (grub_add (sym_sz, grub_strlen (oldpath), &sz) ||
|
|
||||||
+ grub_add (sz, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("path buffer size overflow"));
|
|
||||||
+ grub_free (oldpathbuf);
|
|
||||||
+ if (free_symval)
|
|
||||||
+ grub_free (sym_value);
|
|
||||||
+ err = grub_errno;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ path = path_buf = grub_malloc (sz);
|
|
||||||
if (!path_buf)
|
|
||||||
{
|
|
||||||
grub_free (oldpathbuf);
|
|
||||||
@@ -2948,7 +2966,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
|
|
||||||
{
|
|
||||||
void *sahdrp;
|
|
||||||
int hdrsize;
|
|
||||||
-
|
|
||||||
+ grub_size_t sz;
|
|
||||||
+
|
|
||||||
if (dnode_path->dn.dn.dn_bonuslen != 0)
|
|
||||||
{
|
|
||||||
sahdrp = DN_BONUS (&dnode_path->dn.dn);
|
|
||||||
@@ -2981,7 +3000,15 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
|
|
||||||
+ SA_SIZE_OFFSET),
|
|
||||||
dnode_path->dn.endian);
|
|
||||||
char *oldpath = path, *oldpathbuf = path_buf;
|
|
||||||
- path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1);
|
|
||||||
+ if (grub_add (sym_sz, grub_strlen (oldpath), &sz) ||
|
|
||||||
+ grub_add (sz, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("path buffer size overflow"));
|
|
||||||
+ grub_free (oldpathbuf);
|
|
||||||
+ err = grub_errno;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ path = path_buf = grub_malloc (sz);
|
|
||||||
if (!path_buf)
|
|
||||||
{
|
|
||||||
grub_free (oldpathbuf);
|
|
||||||
@@ -3550,6 +3577,7 @@ grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name,
|
|
||||||
unsigned i;
|
|
||||||
grub_size_t nelm;
|
|
||||||
int elemsize = 0;
|
|
||||||
+ int sz;
|
|
||||||
|
|
||||||
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair,
|
|
||||||
&size, &nelm);
|
|
||||||
@@ -3584,7 +3612,12 @@ grub_zfs_nvlist_lookup_nvlist_array (const char *nvlist, const char *name,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = grub_zalloc (elemsize + sizeof (grub_uint32_t));
|
|
||||||
+ if (grub_add (elemsize, sizeof (grub_uint32_t), &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("elemsize overflow"));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ ret = grub_zalloc (sz);
|
|
||||||
if (!ret)
|
|
||||||
return 0;
|
|
||||||
grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
|
|
||||||
@@ -4163,6 +4196,7 @@ iterate_zap_snap (const char *name, grub_uint64_t val,
|
|
||||||
struct grub_dirhook_info info;
|
|
||||||
char *name2;
|
|
||||||
int ret;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
dnode_end_t mdn;
|
|
||||||
|
|
||||||
@@ -4183,7 +4217,10 @@ iterate_zap_snap (const char *name, grub_uint64_t val,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- name2 = grub_malloc (grub_strlen (name) + 2);
|
|
||||||
+ if (grub_add (grub_strlen (name), 2, &sz))
|
|
||||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow"));
|
|
||||||
+
|
|
||||||
+ name2 = grub_malloc (sz);
|
|
||||||
name2[0] = '@';
|
|
||||||
grub_memcpy (name2 + 1, name, grub_strlen (name) + 1);
|
|
||||||
ret = ctx->hook (name2, &info, ctx->hook_data);
|
|
@ -1,42 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 07:17:03 +0000
|
|
||||||
Subject: [PATCH] fs/zfs: Prevent overflows when allocating memory for arrays
|
|
||||||
|
|
||||||
Use grub_calloc() when allocating memory for arrays to ensure proper
|
|
||||||
overflow checks are in place.
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/zfs/zfs.c | 10 +++++-----
|
|
||||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
|
|
||||||
index 4384d6aae..23fe50211 100644
|
|
||||||
--- a/grub-core/fs/zfs/zfs.c
|
|
||||||
+++ b/grub-core/fs/zfs/zfs.c
|
|
||||||
@@ -717,9 +717,9 @@ fill_vdev_info_real (struct grub_zfs_data *data,
|
|
||||||
if (!fill->children)
|
|
||||||
{
|
|
||||||
fill->n_children = nelm;
|
|
||||||
-
|
|
||||||
- fill->children = grub_zalloc (fill->n_children
|
|
||||||
- * sizeof (fill->children[0]));
|
|
||||||
+
|
|
||||||
+ fill->children = grub_calloc (fill->n_children,
|
|
||||||
+ sizeof (fill->children[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nelm; i++)
|
|
||||||
@@ -3693,8 +3693,8 @@ zfs_mount (grub_device_t dev)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
data->n_devices_allocated = 16;
|
|
||||||
- data->devices_attached = grub_malloc (sizeof (data->devices_attached[0])
|
|
||||||
- * data->n_devices_allocated);
|
|
||||||
+ data->devices_attached = grub_calloc (data->n_devices_allocated,
|
|
||||||
+ sizeof (data->devices_attached[0]));
|
|
||||||
data->n_devices_attached = 0;
|
|
||||||
err = scan_disk (dev, data, 1, &inserted);
|
|
||||||
if (err)
|
|
@ -1,88 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 07:17:01 +0000
|
|
||||||
Subject: [PATCH] fs/zfs: Check if returned pointer for allocated memory is
|
|
||||||
NULL
|
|
||||||
|
|
||||||
When using grub_malloc() or grub_zalloc(), these functions can fail if
|
|
||||||
we are out of memory. After allocating memory we should check if these
|
|
||||||
functions returned NULL and handle this error if they did.
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/zfs/zfs.c | 26 ++++++++++++++++++++++++++
|
|
||||||
1 file changed, 26 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
|
|
||||||
index 23fe50211..434c3bd11 100644
|
|
||||||
--- a/grub-core/fs/zfs/zfs.c
|
|
||||||
+++ b/grub-core/fs/zfs/zfs.c
|
|
||||||
@@ -609,6 +609,8 @@ zfs_fetch_nvlist (struct grub_zfs_device_desc *diskdesc, char **nvlist)
|
|
||||||
return grub_error (GRUB_ERR_BUG, "member drive unknown");
|
|
||||||
|
|
||||||
*nvlist = grub_malloc (VDEV_PHYS_SIZE);
|
|
||||||
+ if (!*nvlist)
|
|
||||||
+ return grub_errno;
|
|
||||||
|
|
||||||
/* Read in the vdev name-value pair list (112K). */
|
|
||||||
err = grub_disk_read (diskdesc->dev->disk, diskdesc->vdev_phys_sector, 0,
|
|
||||||
@@ -721,6 +723,11 @@ fill_vdev_info_real (struct grub_zfs_data *data,
|
|
||||||
fill->children = grub_calloc (fill->n_children,
|
|
||||||
sizeof (fill->children[0]));
|
|
||||||
}
|
|
||||||
+ if (!fill->children)
|
|
||||||
+ {
|
|
||||||
+ grub_free (type);
|
|
||||||
+ return grub_errno;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
for (i = 0; i < nelm; i++)
|
|
||||||
{
|
|
||||||
@@ -2450,6 +2457,11 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
buf = grub_malloc (sz);
|
|
||||||
+ if (!buf)
|
|
||||||
+ {
|
|
||||||
+ grub_free (l);
|
|
||||||
+ return grub_errno;
|
|
||||||
+ }
|
|
||||||
if (zap_leaf_array_get (l, endian, blksft,
|
|
||||||
grub_zfs_to_cpu16 (le->le_name_chunk,
|
|
||||||
endian),
|
|
||||||
@@ -2465,6 +2477,12 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
|
|
||||||
val_length = ((int) le->le_value_length
|
|
||||||
* (int) le->le_int_size);
|
|
||||||
val = grub_malloc (grub_zfs_to_cpu16 (val_length, endian));
|
|
||||||
+ if (!val)
|
|
||||||
+ {
|
|
||||||
+ grub_free (l);
|
|
||||||
+ grub_free (buf);
|
|
||||||
+ return grub_errno;
|
|
||||||
+ }
|
|
||||||
if (zap_leaf_array_get (l, endian, blksft,
|
|
||||||
grub_zfs_to_cpu16 (le->le_value_chunk,
|
|
||||||
endian),
|
|
||||||
@@ -3695,6 +3713,11 @@ zfs_mount (grub_device_t dev)
|
|
||||||
data->n_devices_allocated = 16;
|
|
||||||
data->devices_attached = grub_calloc (data->n_devices_allocated,
|
|
||||||
sizeof (data->devices_attached[0]));
|
|
||||||
+ if (!data->devices_attached)
|
|
||||||
+ {
|
|
||||||
+ grub_free (data);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
data->n_devices_attached = 0;
|
|
||||||
err = scan_disk (dev, data, 1, &inserted);
|
|
||||||
if (err)
|
|
||||||
@@ -4221,6 +4244,9 @@ iterate_zap_snap (const char *name, grub_uint64_t val,
|
|
||||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow"));
|
|
||||||
|
|
||||||
name2 = grub_malloc (sz);
|
|
||||||
+ if (!name2)
|
|
||||||
+ return grub_errno;
|
|
||||||
+
|
|
||||||
name2[0] = '@';
|
|
||||||
grub_memcpy (name2 + 1, name, grub_strlen (name) + 1);
|
|
||||||
ret = ctx->hook (name2, &info, ctx->hook_data);
|
|
@ -1,24 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 07:17:04 +0000
|
|
||||||
Subject: [PATCH] fs/zfs: Add missing NULL check after grub_strdup() call
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/zfs/zfs.c | 2 ++
|
|
||||||
1 file changed, 2 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
|
|
||||||
index 434c3bd11..5254e75e1 100644
|
|
||||||
--- a/grub-core/fs/zfs/zfs.c
|
|
||||||
+++ b/grub-core/fs/zfs/zfs.c
|
|
||||||
@@ -3293,6 +3293,8 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
|
|
||||||
filename = 0;
|
|
||||||
snapname = 0;
|
|
||||||
fsname = grub_strdup (fullpath);
|
|
||||||
+ if (!fsname)
|
|
||||||
+ return grub_errno;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
@ -1,239 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 18:04:42 +0000
|
|
||||||
Subject: [PATCH] net: Use safe math macros to prevent overflows
|
|
||||||
|
|
||||||
Replace direct arithmetic operations with macros from include/grub/safemath.h
|
|
||||||
to prevent potential overflow issues when calculating the memory sizes.
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/net/bootp.c | 16 +++++++++++--
|
|
||||||
grub-core/net/dns.c | 9 ++++++-
|
|
||||||
grub-core/net/drivers/ieee1275/ofnet.c | 20 ++++++++++++++--
|
|
||||||
grub-core/net/net.c | 43 +++++++++++++++++++++++++++-------
|
|
||||||
4 files changed, 75 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
|
|
||||||
index adf36fa4a..786340bf0 100644
|
|
||||||
--- a/grub-core/net/bootp.c
|
|
||||||
+++ b/grub-core/net/bootp.c
|
|
||||||
@@ -28,6 +28,7 @@
|
|
||||||
#include <grub/datetime.h>
|
|
||||||
#include <grub/time.h>
|
|
||||||
#include <grub/list.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
static int
|
|
||||||
dissect_url (const char *url, char **proto, char **host, char **path)
|
|
||||||
@@ -1190,6 +1191,7 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
|
|
||||||
int num;
|
|
||||||
grub_uint8_t *ptr;
|
|
||||||
grub_uint8_t taglength;
|
|
||||||
+ grub_uint8_t len;
|
|
||||||
|
|
||||||
if (argc < 4)
|
|
||||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
|
||||||
@@ -1248,7 +1250,12 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
|
|
||||||
if (grub_strcmp (args[3], "string") == 0)
|
|
||||||
{
|
|
||||||
grub_err_t err = GRUB_ERR_NONE;
|
|
||||||
- char *val = grub_malloc (taglength + 1);
|
|
||||||
+ char *val;
|
|
||||||
+
|
|
||||||
+ if (grub_add (taglength, 1, &len))
|
|
||||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("tag length overflow"));
|
|
||||||
+
|
|
||||||
+ val = grub_malloc (len);
|
|
||||||
if (!val)
|
|
||||||
return grub_errno;
|
|
||||||
grub_memcpy (val, ptr, taglength);
|
|
||||||
@@ -1281,7 +1288,12 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
|
|
||||||
if (grub_strcmp (args[3], "hex") == 0)
|
|
||||||
{
|
|
||||||
grub_err_t err = GRUB_ERR_NONE;
|
|
||||||
- char *val = grub_malloc (2 * taglength + 1);
|
|
||||||
+ char *val;
|
|
||||||
+
|
|
||||||
+ if (grub_mul (taglength, 2, &len) || grub_add (len, 1, &len))
|
|
||||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("tag length overflow"));
|
|
||||||
+
|
|
||||||
+ val = grub_malloc (len);
|
|
||||||
int i;
|
|
||||||
if (!val)
|
|
||||||
return grub_errno;
|
|
||||||
diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
|
|
||||||
index 17961a9f1..64b48a31c 100644
|
|
||||||
--- a/grub-core/net/dns.c
|
|
||||||
+++ b/grub-core/net/dns.c
|
|
||||||
@@ -224,10 +224,17 @@ get_name (const grub_uint8_t *name_at, const grub_uint8_t *head,
|
|
||||||
{
|
|
||||||
int length;
|
|
||||||
char *ret;
|
|
||||||
+ int len;
|
|
||||||
|
|
||||||
if (!check_name_real (name_at, head, tail, NULL, &length, NULL))
|
|
||||||
return NULL;
|
|
||||||
- ret = grub_malloc (length + 1);
|
|
||||||
+
|
|
||||||
+ if (grub_add (length, 1, &len))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow"));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ ret = grub_malloc (len);
|
|
||||||
if (!ret)
|
|
||||||
return NULL;
|
|
||||||
if (!check_name_real (name_at, head, tail, NULL, NULL, ret))
|
|
||||||
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c
|
|
||||||
index ba50415f5..753d54e43 100644
|
|
||||||
--- a/grub-core/net/drivers/ieee1275/ofnet.c
|
|
||||||
+++ b/grub-core/net/drivers/ieee1275/ofnet.c
|
|
||||||
@@ -22,6 +22,7 @@
|
|
||||||
#include <grub/net.h>
|
|
||||||
#include <grub/time.h>
|
|
||||||
#include <grub/i18n.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
|
||||||
|
|
||||||
@@ -404,6 +405,7 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
|
|
||||||
grub_uint8_t *pprop;
|
|
||||||
char *shortname;
|
|
||||||
char need_suffix = 1;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
if (grub_strcmp (alias->type, "network") != 0)
|
|
||||||
return 0;
|
|
||||||
@@ -461,9 +463,23 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_suffix)
|
|
||||||
- ofdata->path = grub_malloc (grub_strlen (alias->path) + sizeof (SUFFIX));
|
|
||||||
+ {
|
|
||||||
+ if (grub_add (grub_strlen (alias->path), sizeof (SUFFIX), &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obatining size of ofdata path"));
|
|
||||||
+ grub_print_error ();
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
else
|
|
||||||
- ofdata->path = grub_malloc (grub_strlen (alias->path) + 1);
|
|
||||||
+ {
|
|
||||||
+ if (grub_add (grub_strlen (alias->path), 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obatining size of ofdata path"));
|
|
||||||
+ grub_print_error ();
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
if (!ofdata->path)
|
|
||||||
{
|
|
||||||
grub_print_error ();
|
|
||||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
|
|
||||||
index f0896979d..10ea4ae71 100644
|
|
||||||
--- a/grub-core/net/net.c
|
|
||||||
+++ b/grub-core/net/net.c
|
|
||||||
@@ -32,6 +32,7 @@
|
|
||||||
#include <grub/loader.h>
|
|
||||||
#include <grub/bufio.h>
|
|
||||||
#include <grub/kernel.h>
|
|
||||||
+#include <grub/safemath.h>
|
|
||||||
#ifdef GRUB_MACHINE_EFI
|
|
||||||
#include <grub/net/efi.h>
|
|
||||||
#endif
|
|
||||||
@@ -211,6 +212,7 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card,
|
|
||||||
{
|
|
||||||
struct grub_net_slaac_mac_list *slaac;
|
|
||||||
char *ptr;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
for (slaac = card->slaac_list; slaac; slaac = slaac->next)
|
|
||||||
if (grub_net_hwaddr_cmp (&slaac->address, hwaddr) == 0)
|
|
||||||
@@ -220,9 +222,16 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card,
|
|
||||||
if (!slaac)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- slaac->name = grub_malloc (grub_strlen (card->name)
|
|
||||||
- + GRUB_NET_MAX_STR_HWADDR_LEN
|
|
||||||
- + sizeof (":slaac"));
|
|
||||||
+ if (grub_add (grub_strlen (card->name),
|
|
||||||
+ (GRUB_NET_MAX_STR_HWADDR_LEN + sizeof (":slaac")), &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_free (slaac);
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
|
|
||||||
+ "overflow detected while obtaining size of slaac name");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ slaac->name = grub_malloc (sz);
|
|
||||||
ptr = grub_stpcpy (slaac->name, card->name);
|
|
||||||
if (grub_net_hwaddr_cmp (&card->default_address, hwaddr) != 0)
|
|
||||||
{
|
|
||||||
@@ -293,6 +302,7 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card,
|
|
||||||
char *name;
|
|
||||||
char *ptr;
|
|
||||||
grub_net_network_level_address_t addr;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
|
|
||||||
addr.ipv6[0] = grub_cpu_to_be64_compile_time (0xfe80ULL << 48);
|
|
||||||
@@ -306,9 +316,14 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card,
|
|
||||||
return inf;
|
|
||||||
}
|
|
||||||
|
|
||||||
- name = grub_malloc (grub_strlen (card->name)
|
|
||||||
- + GRUB_NET_MAX_STR_HWADDR_LEN
|
|
||||||
- + sizeof (":link"));
|
|
||||||
+ if (grub_add (grub_strlen (card->name),
|
|
||||||
+ (GRUB_NET_MAX_STR_HWADDR_LEN + sizeof (":link")), &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
|
|
||||||
+ "overflow detected while obtaining size of link name");
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ name = grub_malloc (sz);
|
|
||||||
if (!name)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
@@ -1462,8 +1477,14 @@ grub_net_open_real (const char *name)
|
|
||||||
if (grub_strchr (port_start + 1, ':'))
|
|
||||||
{
|
|
||||||
int iplen = grub_strlen (server);
|
|
||||||
+ grub_size_t sz;
|
|
||||||
/* bracket bare ipv6 addrs */
|
|
||||||
- host = grub_malloc (iplen + 3);
|
|
||||||
+ if (grub_add (iplen, 3, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining length of host"));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ host = grub_malloc (sz);
|
|
||||||
if(!host)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
@@ -1723,6 +1744,7 @@ grub_env_set_net_property (const char *intername, const char *suffix,
|
|
||||||
{
|
|
||||||
char *varname, *varvalue;
|
|
||||||
char *ptr;
|
|
||||||
+ grub_size_t sz;
|
|
||||||
|
|
||||||
varname = grub_xasprintf ("net_%s_%s", intername, suffix);
|
|
||||||
if (!varname)
|
|
||||||
@@ -1730,7 +1752,12 @@ grub_env_set_net_property (const char *intername, const char *suffix,
|
|
||||||
for (ptr = varname; *ptr; ptr++)
|
|
||||||
if (*ptr == ':')
|
|
||||||
*ptr = '_';
|
|
||||||
- varvalue = grub_malloc (len + 1);
|
|
||||||
+ if (grub_add (len, 1, &sz))
|
|
||||||
+ {
|
|
||||||
+ grub_free (varname);
|
|
||||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining the size of an env variable");
|
|
||||||
+ }
|
|
||||||
+ varvalue = grub_malloc (sz);
|
|
||||||
if (!varvalue)
|
|
||||||
{
|
|
||||||
grub_free (varname);
|
|
@ -1,45 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 18:04:43 +0000
|
|
||||||
Subject: [PATCH] net: Prevent overflows when allocating memory for arrays
|
|
||||||
|
|
||||||
Use grub_calloc() when allocating memory for arrays to ensure proper
|
|
||||||
overflow checks are in place.
|
|
||||||
|
|
||||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/net/dns.c | 4 ++--
|
|
||||||
grub-core/net/net.c | 4 ++--
|
|
||||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
|
|
||||||
index 64b48a31c..aafd92902 100644
|
|
||||||
--- a/grub-core/net/dns.c
|
|
||||||
+++ b/grub-core/net/dns.c
|
|
||||||
@@ -494,8 +494,8 @@ grub_net_dns_lookup (const char *name,
|
|
||||||
&& grub_get_time_ms () < dns_cache[h].limit_time)
|
|
||||||
{
|
|
||||||
grub_dprintf ("dns", "retrieved from cache\n");
|
|
||||||
- *addresses = grub_malloc (dns_cache[h].naddresses
|
|
||||||
- * sizeof ((*addresses)[0]));
|
|
||||||
+ *addresses = grub_calloc (dns_cache[h].naddresses,
|
|
||||||
+ sizeof ((*addresses)[0]));
|
|
||||||
if (!*addresses)
|
|
||||||
return grub_errno;
|
|
||||||
*naddresses = dns_cache[h].naddresses;
|
|
||||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
|
|
||||||
index 10ea4ae71..06f4b1c9f 100644
|
|
||||||
--- a/grub-core/net/net.c
|
|
||||||
+++ b/grub-core/net/net.c
|
|
||||||
@@ -91,8 +91,8 @@ grub_net_link_layer_add_address (struct grub_net_card *card,
|
|
||||||
/* Add sender to cache table. */
|
|
||||||
if (card->link_layer_table == NULL)
|
|
||||||
{
|
|
||||||
- card->link_layer_table = grub_zalloc (LINK_LAYER_CACHE_SIZE
|
|
||||||
- * sizeof (card->link_layer_table[0]));
|
|
||||||
+ card->link_layer_table = grub_calloc (LINK_LAYER_CACHE_SIZE,
|
|
||||||
+ sizeof (card->link_layer_table[0]));
|
|
||||||
if (card->link_layer_table == NULL)
|
|
||||||
return;
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Date: Wed, 22 Jan 2025 18:04:44 +0000
|
|
||||||
Subject: [PATCH] net: Check if returned pointer for allocated memory is NULL
|
|
||||||
|
|
||||||
When using grub_malloc(), the function can fail if we are out of memory.
|
|
||||||
After allocating memory we should check if this function returned NULL
|
|
||||||
and handle this error if it did.
|
|
||||||
|
|
||||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/net/net.c | 5 +++++
|
|
||||||
1 file changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
|
|
||||||
index 06f4b1c9f..6fcbe6fd6 100644
|
|
||||||
--- a/grub-core/net/net.c
|
|
||||||
+++ b/grub-core/net/net.c
|
|
||||||
@@ -232,6 +232,11 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card,
|
|
||||||
}
|
|
||||||
|
|
||||||
slaac->name = grub_malloc (sz);
|
|
||||||
+ if (slaac->name == NULL)
|
|
||||||
+ {
|
|
||||||
+ grub_free (slaac);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
ptr = grub_stpcpy (slaac->name, card->name);
|
|
||||||
if (grub_net_hwaddr_cmp (&card->default_address, hwaddr) != 0)
|
|
||||||
{
|
|
@ -1,32 +0,0 @@
|
|||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Date: Tue, 28 Jan 2025 05:15:50 +0000
|
|
||||||
Subject: [PATCH] fs/sfs: Check if allocated memory is NULL
|
|
||||||
|
|
||||||
When using grub_zalloc(), if we are out of memory, this function can fail.
|
|
||||||
After allocating memory, we should check if grub_zalloc() returns NULL.
|
|
||||||
If so, we should handle this error.
|
|
||||||
|
|
||||||
Fixes: CID 473856
|
|
||||||
|
|
||||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
|
||||||
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
|
|
||||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
|
||||||
---
|
|
||||||
grub-core/fs/sfs.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
|
|
||||||
index a272aea0a..36c5fd656 100644
|
|
||||||
--- a/grub-core/fs/sfs.c
|
|
||||||
+++ b/grub-core/fs/sfs.c
|
|
||||||
@@ -429,6 +429,9 @@ grub_sfs_mount (grub_disk_t disk)
|
|
||||||
- 24 /* offsetof (struct grub_sfs_objc, objects) */
|
|
||||||
- 25); /* offsetof (struct grub_sfs_obj, filename) */
|
|
||||||
data->label = grub_zalloc (max_len + 1);
|
|
||||||
+ if (data->label == NULL)
|
|
||||||
+ goto fail;
|
|
||||||
+
|
|
||||||
grub_strncpy (data->label, (char *) rootobjc->objects[0].filename, max_len);
|
|
||||||
|
|
||||||
grub_free (rootobjc_data);
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user