Compare commits

...

No commits in common. "c8" and "a8-beta" have entirely different histories.
c8 ... a8-beta

95 changed files with 55 additions and 8702 deletions

6
.gitignore vendored
View File

@ -1,9 +1,3 @@
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/unifont-5.1.20080820.pcf.gz

View File

@ -1,9 +1,3 @@
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
87f8600ba24e521b5d20bdf6c4b71af8ae861e3a SOURCES/unifont-5.1.20080820.pcf.gz

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;
}

View File

@ -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])

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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));

View File

@ -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)
{

View File

@ -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;

View File

@ -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)

View File

@ -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;
};

View File

@ -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,

View File

@ -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++)
{

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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, &sector, &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;

View File

@ -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)

View File

@ -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);

View File

@ -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 ();

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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"));
}

View File

@ -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."));

View File

@ -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]"),

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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");

View File

@ -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)

View File

@ -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);

View File

@ -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++)

View File

@ -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 ();

View File

@ -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);

View File

@ -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. */

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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
{

View File

@ -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);

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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);

View File

@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lidong Chen <lidong.chen@oracle.com>
Date: Wed, 29 Jan 2025 06:48:37 +0000
Subject: [PATCH] script/execute: Fix potential underflow and NULL dereference
The result is initialized to 0 in grub_script_arglist_to_argv().
If the for loop condition is not met both result.args and result.argc
remain 0 causing result.argc - 1 to underflow and/or result.args NULL
dereference. Fix the issues by adding relevant checks.
Fixes: CID 473880
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/script/execute.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index ef9a01642..961e9722c 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -794,6 +794,9 @@ cleanup:
}
}
+ if (result.args == NULL || result.argc == 0)
+ goto fail;
+
if (! result.args[result.argc - 1])
result.argc--;

View File

@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lidong Chen <lidong.chen@oracle.com>
Date: Wed, 29 Jan 2025 06:48:38 +0000
Subject: [PATCH] osdep/unix/getroot: Fix potential underflow
The entry_len is initialized in grub_find_root_devices_from_mountinfo()
to 0 before the while loop iterates through /proc/self/mountinfo. If the
file is empty or contains only invalid entries entry_len remains
0 causing entry_len - 1 in the subsequent for loop initialization
to underflow. To prevent this add a check to ensure entry_len > 0 before
entering the for loop.
Fixes: CID 473877
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Ross Philipson <ross.philipson@oracle.com>
---
grub-core/osdep/linux/getroot.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c
index e450f5f0a..27a4d7c81 100644
--- a/grub-core/osdep/linux/getroot.c
+++ b/grub-core/osdep/linux/getroot.c
@@ -599,6 +599,9 @@ again:
}
}
+ if (!entry_len)
+ goto out;
+
/* Now scan visible mounts for the ones we're interested in. */
for (i = entry_len - 1; i >= 0; i--)
{

View File

@ -1,55 +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:39 +0000
Subject: [PATCH] misc: Ensure consistent overflow error messages
Update the overflow error messages to make them consistent
across the GRUB code.
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 2 +-
grub-core/fs/ntfscomp.c | 2 +-
grub-core/video/readers/png.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index 1ad3a2715..f241c5237 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -574,7 +574,7 @@ retry:
goto retry;
}
}
- return grub_error (GRUB_ERR_BAD_FS, "run list overflown");
+ return grub_error (GRUB_ERR_BAD_FS, "run list overflow");
}
ctx->curr_vcn = ctx->next_vcn;
ctx->next_vcn += read_run_data (run, c1, 0); /* length of current VCN */
diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c
index 4bf95c85d..88594702e 100644
--- a/grub-core/fs/ntfscomp.c
+++ b/grub-core/fs/ntfscomp.c
@@ -30,7 +30,7 @@ static grub_err_t
decomp_nextvcn (struct grub_ntfs_comp *cc)
{
if (cc->comp_head >= cc->comp_tail)
- return grub_error (GRUB_ERR_BAD_FS, "compression block overflown");
+ return grub_error (GRUB_ERR_BAD_FS, "compression block overflow");
if (grub_disk_read
(cc->disk,
(cc->comp_table[cc->comp_head].next_lcn -
diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c
index 7f2ba7849..3ff215dd6 100644
--- a/grub-core/video/readers/png.c
+++ b/grub-core/video/readers/png.c
@@ -622,7 +622,7 @@ static grub_err_t
grub_png_output_byte (struct grub_png_data *data, grub_uint8_t n)
{
if (--data->raw_bytes < 0)
- return grub_error (GRUB_ERR_BAD_FILE_TYPE, "image size overflown");
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "image size overflow");
if (data->cur_column == 0)
{

View File

@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alec Brown <alec.r.brown@oracle.com>
Date: Tue, 4 Feb 2025 15:11:10 +0000
Subject: [PATCH] bus/usb/ehci: Define GRUB_EHCI_TOGGLE as grub_uint32_t
The Coverity indicates that GRUB_EHCI_TOGGLE is an int that contains
a negative value and we are using it for the variable token which is
grub_uint32_t. To remedy this we can cast the definition to grub_uint32_t.
Fixes: CID 473851
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/bus/usb/ehci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c
index d966fc210..d1e8a01ca 100644
--- a/grub-core/bus/usb/ehci.c
+++ b/grub-core/bus/usb/ehci.c
@@ -218,7 +218,7 @@ enum
#define GRUB_EHCI_TERMINATE (1<<0)
-#define GRUB_EHCI_TOGGLE (1<<31)
+#define GRUB_EHCI_TOGGLE ((grub_uint32_t) 1<<31)
enum
{

View File

@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alec Brown <alec.r.brown@oracle.com>
Date: Tue, 4 Feb 2025 15:11:11 +0000
Subject: [PATCH] normal/menu: Use safe math to avoid an integer overflow
The Coverity indicates that the variable current_entry might overflow.
To prevent this use safe math when adding GRUB_MENU_PAGE_SIZE to current_entry.
On the occasion fix limiting condition which was broken.
Fixes: CID 473853
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/normal/menu.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 7e32c498a..ff2bebe82 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -32,6 +32,7 @@
#include <grub/script_sh.h>
#include <grub/gfxterm.h>
#include <grub/dl.h>
+#include <grub/safemath.h>
/* Time to delay after displaying an error message about a default/fallback
entry failing to boot. */
@@ -780,9 +781,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
case GRUB_TERM_CTRL | 'c':
case GRUB_TERM_KEY_NPAGE:
- if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size)
- current_entry += GRUB_MENU_PAGE_SIZE;
- else
+ if (grub_add (current_entry, GRUB_MENU_PAGE_SIZE, &current_entry) || current_entry >= menu->size)
current_entry = menu->size - 1;
menu_set_chosen_entry (current_entry);
break;

View File

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lidong Chen <lidong.chen@oracle.com>
Date: Thu, 6 Feb 2025 18:16:56 +0000
Subject: [PATCH] kern/partition: Add sanity check after grub_strtoul() call
The current code incorrectly assumes that both the input and the values
returned by grub_strtoul() are always valid which can lead to potential
errors. This fix ensures proper validation to prevent any unintended issues.
Fixes: CID 473843
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/partition.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c
index f3f125e75..f95efe8ce 100644
--- a/grub-core/kern/partition.c
+++ b/grub-core/kern/partition.c
@@ -125,14 +125,21 @@ grub_partition_probe (struct grub_disk *disk, const char *str)
for (ptr = str; *ptr;)
{
grub_partition_map_t partmap;
- int num;
+ unsigned long num;
const char *partname, *partname_end;
partname = ptr;
while (*ptr && grub_isalpha (*ptr))
ptr++;
partname_end = ptr;
- num = grub_strtoul (ptr, &ptr, 0) - 1;
+ num = grub_strtoul (ptr, &ptr, 0);
+ if (*ptr != '\0' || num == 0 || num > GRUB_INT_MAX)
+ {
+ grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid partition number"));
+ return 0;
+ }
+
+ num -= 1;
curpart = 0;
/* Use the first partition map type found. */

View File

@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lidong Chen <lidong.chen@oracle.com>
Date: Thu, 6 Feb 2025 18:16:57 +0000
Subject: [PATCH] kern/misc: Add sanity check after grub_strtoul() call
When the format string, fmt0, includes a positional argument
grub_strtoul() or grub_strtoull() is called to extract the argument
position. However, the returned argument position isn't fully validated.
If the format is something like "%0$x" then these functions return
0 which leads to an underflow in the calculation of the args index, curn.
The fix is to add a check to ensure the extracted argument position is
greater than 0 before computing curn. Additionally, replace one
grub_strtoull() with grub_strtoul() and change curn type to make code
more correct.
Fixes: CID 473841
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/misc.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index b375e486a..8f211e4c7 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -830,7 +830,7 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args,
while ((c = *fmt++) != 0)
{
int longfmt = 0;
- grub_size_t curn;
+ unsigned long curn;
const char *p;
if (c != '%')
@@ -848,7 +848,10 @@ parse_printf_arg_fmt (const char *fmt0, struct printf_args *args,
if (*fmt == '$')
{
- curn = grub_strtoull (p, 0, 10) - 1;
+ curn = grub_strtoul (p, 0, 10);
+ if (curn == 0)
+ continue;
+ curn--;
fmt++;
}
@@ -1007,6 +1010,8 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
if (*fmt == '$')
{
+ if (format1 == 0)
+ continue;
curn = format1 - 1;
fmt++;
format1 = 0;

View File

@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alec Brown <alec.r.brown@oracle.com>
Date: Fri, 7 Feb 2025 01:47:57 +0000
Subject: [PATCH] loader/i386/linux: Cast left shift to grub_uint32_t
The Coverity complains that we might overflow into a negative value when
setting linux_params.kernel_alignment to (1 << align). We can remedy
this by casting it to grub_uint32_t.
Fixes: CID 473876
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/loader/i386/linux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index c160ddb0e..b72b7d591 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -837,7 +837,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W, GRUB_MEM_ATTR_X);
linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
- linux_params.kernel_alignment = (1 << align);
+ linux_params.kernel_alignment = ((grub_uint32_t) 1 << align);
linux_params.ps_mouse = linux_params.padding10 = 0;
len = sizeof (linux_params) - sizeof (lh);

View File

@ -1,56 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alec Brown <alec.r.brown@oracle.com>
Date: Wed, 5 Feb 2025 22:04:08 +0000
Subject: [PATCH] loader/i386/bsd: Use safe math to avoid underflow
The operation kern_end - kern_start may underflow when we input it into
grub_relocator_alloc_chunk_addr() call. To avoid this we can use safe
math for this subtraction.
Fixes: CID 73845
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/loader/i386/bsd.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
index b5ab848ee..ff1658503 100644
--- a/grub-core/loader/i386/bsd.c
+++ b/grub-core/loader/i386/bsd.c
@@ -1341,6 +1341,7 @@ static grub_err_t
grub_bsd_load_elf (grub_elf_t elf, const char *filename)
{
grub_err_t err;
+ grub_size_t sz;
kern_end = 0;
kern_start = ~0;
@@ -1371,8 +1372,11 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename)
if (grub_errno)
return grub_errno;
- err = grub_relocator_alloc_chunk_addr (relocator, &ch,
- kern_start, kern_end - kern_start);
+
+ if (grub_sub (kern_end, kern_start, &sz))
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "underflow detected while determining size of kernel for relocator");
+
+ err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start, sz);
if (err)
return err;
@@ -1432,8 +1436,10 @@ grub_bsd_load_elf (grub_elf_t elf, const char *filename)
{
grub_relocator_chunk_t ch;
- err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start,
- kern_end - kern_start);
+ if (grub_sub (kern_end, kern_start, &sz))
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "underflow detected while determining size of kernel for relocator");
+
+ err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start, sz);
if (err)
return err;
kern_chunk_src = get_virtual_current_address (ch);

View File

@ -1,78 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 4 Nov 2022 12:13:34 -0400
Subject: [PATCH] types: Make bool generally available
Add an include on stdbool.h, making the bool type generally available
within the GRUB without needing to add a file-specific include every
time it would be used.
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/parttool.c | 2 +-
grub-core/parttool/msdospart.c | 4 ++--
include/grub/parttool.h | 2 +-
include/grub/types.h | 1 +
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c
index 051e31320..ff45c65e6 100644
--- a/grub-core/commands/parttool.c
+++ b/grub-core/commands/parttool.c
@@ -315,7 +315,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
switch (curarg->type)
{
case GRUB_PARTTOOL_ARG_BOOL:
- pargs[curarg - ptool->args].bool
+ pargs[curarg - ptool->args].b
= (args[j][grub_strlen (curarg->name)] != '-');
break;
diff --git a/grub-core/parttool/msdospart.c b/grub-core/parttool/msdospart.c
index dcbf74e3b..a92669e5a 100644
--- a/grub-core/parttool/msdospart.c
+++ b/grub-core/parttool/msdospart.c
@@ -61,7 +61,7 @@ static grub_err_t grub_pcpart_boot (const grub_device_t dev,
return grub_errno;
}
- if (args[0].set && args[0].bool)
+ if (args[0].set && args[0].b)
{
for (i = 0; i < 4; i++)
mbr.entries[i].flag = 0x0;
@@ -116,7 +116,7 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev,
if (args[1].set)
{
- if (args[1].bool)
+ if (args[1].b)
type |= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
else
type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
diff --git a/include/grub/parttool.h b/include/grub/parttool.h
index 4e8f8d5e5..4799a22c5 100644
--- a/include/grub/parttool.h
+++ b/include/grub/parttool.h
@@ -32,7 +32,7 @@ struct grub_parttool_args
int set;
union
{
- int bool;
+ int b;
char *str;
};
};
diff --git a/include/grub/types.h b/include/grub/types.h
index f6a972397..7a66af768 100644
--- a/include/grub/types.h
+++ b/include/grub/types.h
@@ -20,6 +20,7 @@
#define GRUB_TYPES_HEADER 1
#include <config.h>
+#include <stdbool.h>
#ifndef GRUB_UTIL
#include <grub/cpu/types.h>
#endif

View File

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
Date: Sat, 15 Feb 2025 20:11:42 -0600
Subject: [PATCH] Remove exttra bool definitions
Previous commit 'types: Make bool generally available' make this type available
so no need to redefined it.
Signed-off-by: Leo Sandoval <lsandova@redhat.com>
---
grub-core/lib/posix_wrap/sys/types.h | 5 -----
grub-core/lib/xzembed/xz.h | 4 ----
2 files changed, 9 deletions(-)
diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h
index f63412c8d..2cd36d081 100644
--- a/grub-core/lib/posix_wrap/sys/types.h
+++ b/grub-core/lib/posix_wrap/sys/types.h
@@ -24,11 +24,6 @@
#include <stddef.h>
typedef grub_ssize_t ssize_t;
-#ifndef GRUB_POSIX_BOOL_DEFINED
-typedef enum { false = 0, true = 1 } bool;
-#define GRUB_POSIX_BOOL_DEFINED 1
-#endif
-
typedef grub_uint8_t uint8_t;
typedef grub_uint16_t uint16_t;
typedef grub_uint32_t uint32_t;
diff --git a/grub-core/lib/xzembed/xz.h b/grub-core/lib/xzembed/xz.h
index fe7158bb2..0265c4a6d 100644
--- a/grub-core/lib/xzembed/xz.h
+++ b/grub-core/lib/xzembed/xz.h
@@ -29,10 +29,6 @@
#include <string.h>
#include <grub/misc.h>
-#ifndef GRUB_POSIX_BOOL_DEFINED
-typedef enum { false = 0, true = 1 } bool;
-#endif
-
/**
* enum xz_ret - Return codes
* @XZ_OK: Everything is OK so far. More input or more output

View File

@ -1,106 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 2 Jun 2023 18:08:44 +0000
Subject: [PATCH] fs/xfs: Fix issues found while fuzzing the XFS filesystem
While performing fuzz testing with XFS filesystem images with ASAN
enabled, several issues were found where the memory accesses are made
beyond the data that is allocated into the struct grub_xfs_data
structure's data field.
The existing structure didn't store the size of the memory allocated into
the buffer in the data field and had no way to check it. To resolve these
issues, the data size is stored to enable checks into the data buffer.
With these checks in place, the fuzzing corpus no longer cause any crashes.
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/xfs.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index b0d371ee1..7076192c1 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -221,6 +221,7 @@ struct grub_fshelp_node
struct grub_xfs_data
{
+ grub_size_t data_size;
struct grub_xfs_sblock sblock;
grub_disk_t disk;
int pos;
@@ -592,8 +593,20 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
}
else if (node->inode.format == XFS_INODE_FORMAT_EXT)
{
+ grub_addr_t exts_end = 0;
+ grub_addr_t data_end = 0;
+
nrec = grub_be_to_cpu32 (node->inode.nextents);
exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
+
+ if (grub_mul (sizeof (struct grub_xfs_extent), nrec, &exts_end) ||
+ grub_add ((grub_addr_t) node->data, exts_end, &exts_end) ||
+ grub_add ((grub_addr_t) node->data, node->data->data_size, &data_end) ||
+ exts_end > data_end)
+ {
+ grub_error (GRUB_ERR_BAD_FS, "invalid number of XFS extents");
+ return 0;
+ }
}
else
{
@@ -796,6 +809,9 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
grub_uint8_t c;
+ if ((inopos + (smallino ? 4 : 8)) > (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
+ return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode");
+
/* inopos might be unaligned. */
if (smallino)
ino = (((grub_uint32_t) inopos[0]) << 24)
@@ -822,6 +838,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
de->name[de->len] = c;
de = grub_xfs_inline_next_de(dir->data, head, de);
+
+ if ((grub_uint8_t *) de >= (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
+ return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
+
}
break;
}
@@ -887,6 +907,9 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
}
filename = (char *)(direntry + 1);
+ if (filename + direntry->len - 1 > (char *) tail)
+ return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
+
/* The byte after the filename is for the filetype, padding, or
tag, which is not used by GRUB. So it can be overwritten. */
filename[direntry->len] = '\0';
@@ -931,6 +954,8 @@ grub_xfs_mount (grub_disk_t disk)
if (!data)
return 0;
+ data->data_size = sizeof (struct grub_xfs_data);
+
grub_dprintf("xfs", "Reading sb\n");
/* Read the superblock. */
if (grub_disk_read (disk, 0, 0,
@@ -949,6 +974,7 @@ grub_xfs_mount (grub_disk_t disk)
if (! data)
goto fail;
+ data->data_size = sz;
data->diropen.data = data;
data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino);
data->diropen.inode_read = 1;

View File

@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nicolas Frayer <nfrayer@redhat.com>
Date: Wed, 19 Mar 2025 17:39:41 +0100
Subject: [PATCH] ieee1275/ofnet: Fix grub_malloc() removed after added safe
math functions
grub_malloc() has been inadvertently removed from the ieee1275/ofnet
code after it has been modified to use safe match function.
Fixes: 4beeff8a (net: Use safe math macros to prevent overflows)
Tested-by: Marta Lewandowska <mlewando@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
---
grub-core/net/drivers/ieee1275/ofnet.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c
index 3e1b9094e2ab..37bc82467f60 100644
--- a/grub-core/net/drivers/ieee1275/ofnet.c
+++ b/grub-core/net/drivers/ieee1275/ofnet.c
@@ -463,6 +463,9 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
return 0;
}
}
+
+ ofdata->path = grub_malloc(sz);
+
if (!ofdata->path)
{
grub_print_error ();

View File

@ -1,156 +0,0 @@
From 631bfec4c070c220e86d2e2d8e6d6aa38c130ef1 Mon Sep 17 00:00:00 2001
From: Carlos Maiolino <cmaiolino@redhat.com>
Date: Mon, 24 May 2021 19:40:06 +0200
Subject: [PATCH 667/668] fs/xfs: Add bigtime incompat feature support
The XFS filesystem supports a bigtime feature to overcome y2038 problem.
This patch makes the GRUB able to support the XFS filesystems with this
feature enabled.
The XFS counter for the bigtime enabled timestamps starts at 0, which
translates to GRUB_INT32_MIN (Dec 31 20:45:52 UTC 1901) in the legacy
timestamps. The conversion to Unix timestamps is made before passing the
value to other GRUB functions.
For this to work properly, GRUB requires an access to flags2 field in the
XFS ondisk inode. So, the grub_xfs_inode structure has been updated to
cover full ondisk inode.
Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/xfs.c | 49 ++++++++++++++++++++++++++++++++++++---------
include/grub/time.h | 2 ++
2 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 887392c..8c23944 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -23,6 +23,7 @@
#include <grub/misc.h>
#include <grub/disk.h>
#include <grub/dl.h>
+#include <grub/time.h>
#include <grub/types.h>
#include <grub/fshelp.h>
#include <grub/safemath.h>
@@ -75,10 +76,15 @@ GRUB_MOD_LICENSE ("GPLv3+");
XFS_SB_VERSION2_PROJID32BIT | \
XFS_SB_VERSION2_FTYPE)
+/* Inode flags2 flags */
+#define XFS_DIFLAG2_BIGTIME_BIT 3
+#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT)
+
/* incompat feature flags */
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
+#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
/*
* Directory entries with ftype are explicitly handled by GRUB code.
@@ -92,7 +98,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define XFS_SB_FEAT_INCOMPAT_SUPPORTED \
(XFS_SB_FEAT_INCOMPAT_FTYPE | \
XFS_SB_FEAT_INCOMPAT_SPINODES | \
- XFS_SB_FEAT_INCOMPAT_META_UUID)
+ XFS_SB_FEAT_INCOMPAT_META_UUID | \
+ XFS_SB_FEAT_INCOMPAT_BIGTIME)
struct grub_xfs_sblock
{
@@ -177,7 +184,7 @@ struct grub_xfs_btree_root
grub_uint64_t keys[1];
} GRUB_PACKED;
-struct grub_xfs_time
+struct grub_xfs_time_legacy
{
grub_uint32_t sec;
grub_uint32_t nanosec;
@@ -190,20 +197,23 @@ struct grub_xfs_inode
grub_uint8_t version;
grub_uint8_t format;
grub_uint8_t unused2[26];
- struct grub_xfs_time atime;
- struct grub_xfs_time mtime;
- struct grub_xfs_time ctime;
+ grub_uint64_t atime;
+ grub_uint64_t mtime;
+ grub_uint64_t ctime;
grub_uint64_t size;
grub_uint64_t nblocks;
grub_uint32_t extsize;
grub_uint32_t nextents;
grub_uint16_t unused3;
grub_uint8_t fork_offset;
- grub_uint8_t unused4[17];
+ grub_uint8_t unused4[37];
+ grub_uint64_t flags2;
+ grub_uint8_t unused5[48];
} GRUB_PACKED;
-#define XFS_V2_INODE_SIZE sizeof(struct grub_xfs_inode)
-#define XFS_V3_INODE_SIZE (XFS_V2_INODE_SIZE + 76)
+#define XFS_V3_INODE_SIZE sizeof(struct grub_xfs_inode)
+/* Size of struct grub_xfs_inode until fork_offset (included). */
+#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 92)
struct grub_xfs_dirblock_tail
{
@@ -1009,6 +1019,27 @@ struct grub_xfs_dir_ctx
void *hook_data;
};
+/* Bigtime inodes helpers. */
+#define XFS_BIGTIME_EPOCH_OFFSET (-(grub_int64_t) GRUB_INT32_MIN)
+
+static int grub_xfs_inode_has_bigtime (const struct grub_xfs_inode *inode)
+{
+ return inode->version >= 3 &&
+ (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_BIGTIME));
+}
+
+static grub_int64_t
+grub_xfs_get_inode_time (struct grub_xfs_inode *inode)
+{
+ struct grub_xfs_time_legacy *lts;
+
+ if (grub_xfs_inode_has_bigtime (inode))
+ return grub_divmod64 (grub_be_to_cpu64 (inode->mtime), NSEC_PER_SEC, NULL) - XFS_BIGTIME_EPOCH_OFFSET;
+
+ lts = (struct grub_xfs_time_legacy *) &inode->mtime;
+ return grub_be_to_cpu32 (lts->sec);
+}
+
/* Helper for grub_xfs_dir. */
static int
grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
@@ -1021,7 +1052,7 @@ grub_xfs_dir_iter (const char *filename, enum grub_fshelp_filetype filetype,
if (node->inode_read)
{
info.mtimeset = 1;
- info.mtime = grub_be_to_cpu32 (node->inode.mtime.sec);
+ info.mtime = grub_xfs_get_inode_time (&node->inode);
}
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
grub_free (node);
diff --git a/include/grub/time.h b/include/grub/time.h
index c919c1f..32f0afa 100644
--- a/include/grub/time.h
+++ b/include/grub/time.h
@@ -30,6 +30,8 @@ grub_cpu_idle(void)
}
#endif
+#define NSEC_PER_SEC ((grub_int64_t) 1000000000)
+
void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms);
grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void);
--
2.43.5

View File

@ -1,81 +0,0 @@
From b03ffdb85eca0a5a632c6c5bbeea52373d2fea69 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Mon, 24 May 2021 19:40:07 +0200
Subject: [PATCH 668/668] fs/xfs: Add needsrepair incompat feature support
The XFS now has an incompat feature flag to indicate that a filesystem
needs to be repaired. The Linux kernel refuses to mount the filesystem
that has it set and only the xfs_repair tool is able to clear that flag.
The GRUB doesn't have the concept of mounting filesystems and just
attempts to read the files. But it does some sanity checking before
attempting to read from the filesystem. Among the things which are tested,
is if the super block only has set of incompatible features flags that
are supported by GRUB. If it contains any flags that are not listed as
supported, reading the XFS filesystem fails.
Since the GRUB doesn't attempt to detect if the filesystem is inconsistent
nor replays the journal, the filesystem access is a best effort. For this
reason, ignore if the filesystem needs to be repaired and just print a debug
message. That way, if reading or booting fails later, the user is able to
figure out that the failures can be related to broken XFS filesystem.
Suggested-by: Eric Sandeen <esandeen@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/xfs.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 8c23944..f113216 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -85,6 +85,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
+#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */
/*
* Directory entries with ftype are explicitly handled by GRUB code.
@@ -99,7 +100,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
(XFS_SB_FEAT_INCOMPAT_FTYPE | \
XFS_SB_FEAT_INCOMPAT_SPINODES | \
XFS_SB_FEAT_INCOMPAT_META_UUID | \
- XFS_SB_FEAT_INCOMPAT_BIGTIME)
+ XFS_SB_FEAT_INCOMPAT_BIGTIME | \
+ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
struct grub_xfs_sblock
{
@@ -313,6 +315,16 @@ static int grub_xfs_sb_valid(struct grub_xfs_data *data)
return 0;
}
+static int
+grub_xfs_sb_needs_repair (struct grub_xfs_data *data)
+{
+ return ((data->sblock.version &
+ grub_cpu_to_be16_compile_time (XFS_SB_VERSION_NUMBITS)) ==
+ grub_cpu_to_be16_compile_time (XFS_SB_VERSION_5) &&
+ (data->sblock.sb_features_incompat &
+ grub_cpu_to_be32_compile_time (XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)));
+}
+
/* Filetype information as used in inodes. */
#define FILETYPE_INO_MASK 0170000
#define FILETYPE_INO_REG 0100000
@@ -975,6 +987,9 @@ grub_xfs_mount (grub_disk_t disk)
if (!grub_xfs_sb_valid(data))
goto fail;
+ if (grub_xfs_sb_needs_repair (data))
+ grub_dprintf ("xfs", "XFS filesystem needs repair, boot may fail\n");
+
if (grub_add (grub_xfs_inode_size (data),
sizeof (struct grub_xfs_data) - sizeof (struct grub_xfs_inode) + 1, &sz))
goto fail;
--
2.43.5

View File

@ -1,121 +0,0 @@
From e89ae8eac88f240d757f812bebac1b46e62222bc Mon Sep 17 00:00:00 2001
From: Erwan Velu <erwanaliasr1@gmail.com>
Date: Wed, 25 Aug 2021 15:31:52 +0200
Subject: [PATCH 669/676] fs/xfs: Fix unreadable filesystem with v4 superblock
The commit 8b1e5d193 (fs/xfs: Add bigtime incompat feature support)
introduced the bigtime support by adding some features in v3 inodes.
This change extended grub_xfs_inode struct by 76 bytes but also changed
the computation of XFS_V2_INODE_SIZE and XFS_V3_INODE_SIZE. Prior this
commit, XFS_V2_INODE_SIZE was 100 bytes. After the commit it's 84 bytes
XFS_V2_INODE_SIZE becomes 16 bytes too small.
As a result, the data structures aren't properly aligned and the GRUB
generates "attempt to read or write outside of partition" errors when
trying to read the XFS filesystem:
GNU GRUB version 2.11
....
grub> set debug=efi,gpt,xfs
grub> insmod part_gpt
grub> ls (hd0,gpt1)/
partmap/gpt.c:93: Read a valid GPT header
partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125
fs/xfs.c:931: Reading sb
fs/xfs.c:270: Validating superblock
fs/xfs.c:295: XFS v4 superblock detected
fs/xfs.c:962: Reading root ino 128
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (739521961424144223) - 344365866970255880, 3840
error: attempt to read or write outside of partition.
This commit change the XFS_V2_INODE_SIZE computation by subtracting 76
bytes instead of 92 bytes from the actual size of grub_xfs_inode struct.
This 76 bytes value comes from added members:
20 grub_uint8_t unused5
1 grub_uint64_t flags2
48 grub_uint8_t unused6
This patch explicitly splits the v2 and v3 parts of the structure.
The unused4 is still ending of the v2 structures and the v3 starts
at unused5. Thanks to this we will avoid future corruptions of v2
or v3 inodes.
The XFS_V2_INODE_SIZE is returning to its expected size and the
filesystem is back to a readable state:
GNU GRUB version 2.11
....
grub> set debug=efi,gpt,xfs
grub> insmod part_gpt
grub> ls (hd0,gpt1)/
partmap/gpt.c:93: Read a valid GPT header
partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125
fs/xfs.c:931: Reading sb
fs/xfs.c:270: Validating superblock
fs/xfs.c:295: XFS v4 superblock detected
fs/xfs.c:962: Reading root ino 128
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:931: Reading sb
fs/xfs.c:270: Validating superblock
fs/xfs.c:295: XFS v4 superblock detected
fs/xfs.c:962: Reading root ino 128
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (128) - 64, 0
fs/xfs.c:515: Reading inode (131) - 64, 768
efi/ fs/xfs.c:515: Reading inode (3145856) - 1464904, 0
grub2/ fs/xfs.c:515: Reading inode (132) - 64, 1024
grub/ fs/xfs.c:515: Reading inode (139) - 64, 2816
grub>
Fixes: 8b1e5d193 (fs/xfs: Add bigtime incompat feature support)
Signed-off-by: Erwan Velu <e.velu@criteo.com>
Tested-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
(cherry picked from commit a4b495520e4dc41a896a8b916a64eda9970c50ea)
---
grub-core/fs/xfs.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 7d4e632..7d15add 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -192,6 +192,11 @@ struct grub_xfs_time_legacy
grub_uint32_t nanosec;
} GRUB_PACKED;
+/*
+ * The struct grub_xfs_inode layout was taken from the
+ * struct xfs_dinode_core which is described here:
+ * https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf
+ */
struct grub_xfs_inode
{
grub_uint8_t magic[2];
@@ -208,14 +213,15 @@ struct grub_xfs_inode
grub_uint32_t nextents;
grub_uint16_t unused3;
grub_uint8_t fork_offset;
- grub_uint8_t unused4[37];
+ grub_uint8_t unused4[17]; /* Last member of inode v2. */
+ grub_uint8_t unused5[20]; /* First member of inode v3. */
grub_uint64_t flags2;
- grub_uint8_t unused5[48];
+ grub_uint8_t unused6[48]; /* Last member of inode v3. */
} GRUB_PACKED;
#define XFS_V3_INODE_SIZE sizeof(struct grub_xfs_inode)
-/* Size of struct grub_xfs_inode until fork_offset (included). */
-#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 92)
+/* Size of struct grub_xfs_inode v2, up to unused4 member included. */
+#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76)
struct grub_xfs_dirblock_tail
{
--
2.43.5

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +0,0 @@
From a6405bff7be8359a790f536a3fe2b84b96cfeccd Mon Sep 17 00:00:00 2001
From: "t.feng" <fengtao40@huawei.com>
Date: Tue, 29 Nov 2022 17:14:15 +0800
Subject: [PATCH 671/676] fs/xfs: Fix memory leaks in XFS module
Signed-off-by: t.feng <fengtao40@huawei.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/xfs.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 4caf29f..171417d 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -598,7 +598,10 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
if (grub_disk_read (node->data->disk,
GRUB_XFS_FSB_TO_BLOCK (node->data, get_fsb (keys, i - 1 + recoffset)) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS),
0, node->data->bsize, leaf))
- return 0;
+ {
+ grub_free (leaf);
+ return 0;
+ }
if ((!node->data->hascrc &&
grub_strncmp ((char *) leaf->magic, "BMAP", 4)) ||
@@ -789,6 +792,7 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
if (err)
{
grub_print_error ();
+ grub_free (fdiro);
return 0;
}
@@ -906,7 +910,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
blk << dirblk_log2,
dirblk_size, dirblock, 0);
if (numread != dirblk_size)
- return 0;
+ {
+ grub_free (dirblock);
+ return 0;
+ }
entries = (grub_be_to_cpu32 (tail->leaf_count)
- grub_be_to_cpu32 (tail->leaf_stale));
--
2.43.5

View File

@ -1,51 +0,0 @@
From df644ea62c0c0c029ee05d298dc1c61b967bc9c9 Mon Sep 17 00:00:00 2001
From: Lidong Chen <lidong.chen@oracle.com>
Date: Thu, 28 Sep 2023 22:33:44 +0000
Subject: [PATCH 672/676] fs/xfs: Incorrect short form directory data boundary
check
After parsing of the current entry, the entry pointer is advanced
to the next entry at the end of the "for" loop. In case where the
last entry is at the end of the data boundary, the advanced entry
pointer can point off the data boundary. The subsequent boundary
check for the advanced entry pointer can cause a failure.
The fix is to include the boundary check into the "for" loop
condition.
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Tested-by: Marta Lewandowska <mlewando@redhat.com>
---
grub-core/fs/xfs.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 171417d..a79d805 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -835,7 +835,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
if (iterate_dir_call_hook (parent, "..", &ctx))
return 1;
- for (i = 0; i < head->count; i++)
+ for (i = 0; i < head->count &&
+ (grub_uint8_t *) de < ((grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)); i++)
{
grub_uint64_t ino;
grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
@@ -870,10 +871,6 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
de->name[de->len] = c;
de = grub_xfs_inline_next_de(dir->data, head, de);
-
- if ((grub_uint8_t *) de >= (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
- return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
-
}
break;
}
--
2.43.5

View File

@ -1,171 +0,0 @@
From e6845e0ad12d7f0a584e2a34da47a9d836efb0ad Mon Sep 17 00:00:00 2001
From: Jon DeVree <nuxi@vault24.org>
Date: Tue, 17 Oct 2023 23:03:47 -0400
Subject: [PATCH 673/676] fs/xfs: Fix XFS directory extent parsing
The XFS directory entry parsing code has never been completely correct
for extent based directories. The parser correctly handles the case
where the directory is contained in a single extent, but then mistakenly
assumes the data blocks for the multiple extent case are each identical
to the single extent case. The difference in the format of the data
blocks between the two cases is tiny enough that its gone unnoticed for
a very long time.
A recent change introduced some additional bounds checking into the XFS
parser. Like GRUB's existing parser, it is correct for the single extent
case but incorrect for the multiple extent case. When parsing a directory
with multiple extents, this new bounds checking is sometimes (but not
always) tripped and triggers an "invalid XFS directory entry" error. This
probably would have continued to go unnoticed but the /boot/grub/<arch>
directory is large enough that it often has multiple extents.
The difference between the two cases is that when there are multiple
extents, the data blocks do not contain a trailer nor do they contain
any leaf information. That information is stored in a separate set of
extents dedicated to just the leaf information. These extents come after
the directory entry extents and are not included in the inode size. So
the existing parser already ignores the leaf extents.
The only reason to read the trailer/leaf information at all is so that
the parser can avoid misinterpreting that data as directory entries. So
this updates the parser as follows:
For the single extent case the parser doesn't change much:
1. Read the size of the leaf information from the trailer
2. Set the end pointer for the parser to the start of the leaf
information. (The previous bounds checking set the end pointer to the
start of the trailer, so this is actually a small improvement.)
3. Set the entries variable to the expected number of directory entries.
For the multiple extent case:
1. Set the end pointer to the end of the block.
2. Do not set up the entries variable. Figuring out how many entries are
in each individual block is complex and does not seem worth it when
it appears to be safe to just iterate over the entire block.
The bounds check itself was also dependent upon the faulty XFS parser
because it accidentally used "filename + length - 1". Presumably this
was able to pass the fuzzer because in the old parser there was always
8 bytes of slack space between the tail pointer and the actual end of
the block. Since this is no longer the case the bounds check needs to be
updated to "filename + length + 1" in order to prevent a regression in
the handling of corrupt fliesystems.
Notes:
* When there is only one extent there will only ever be one block. If
more than one block is required then XFS will always switch to holding
leaf information in a separate extent.
* B-tree based directories seems to be parsed properly by the same code
that handles multiple extents. This is unlikely to ever occur within
/boot though because its only used when there are an extremely large
number of directory entries.
Fixes: ef7850c75 (fs/xfs: Fix issues found while fuzzing the XFS filesystem)
Fixes: b2499b29c (Adds support for the XFS filesystem.)
Fixes: https://savannah.gnu.org/bugs/?64376
Signed-off-by: Jon DeVree <nuxi@vault24.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Tested-by: Marta Lewandowska <mlewando@redhat.com>
---
grub-core/fs/xfs.c | 52 +++++++++++++++++++++++++++++++++-------------
1 file changed, 38 insertions(+), 14 deletions(-)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index a79d805..5beda40 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -223,6 +223,12 @@ struct grub_xfs_inode
/* Size of struct grub_xfs_inode v2, up to unused4 member included. */
#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76)
+struct grub_xfs_dir_leaf_entry
+{
+ grub_uint32_t hashval;
+ grub_uint32_t address;
+} GRUB_PACKED;
+
struct grub_xfs_dirblock_tail
{
grub_uint32_t leaf_count;
@@ -899,9 +905,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
{
struct grub_xfs_dir2_entry *direntry =
grub_xfs_first_de(dir->data, dirblock);
- int entries;
- struct grub_xfs_dirblock_tail *tail =
- grub_xfs_dir_tail(dir->data, dirblock);
+ int entries = -1;
+ char *end = dirblock + dirblk_size;
numread = grub_xfs_read_file (dir, 0, 0,
blk << dirblk_log2,
@@ -912,14 +917,27 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
return 0;
}
- entries = (grub_be_to_cpu32 (tail->leaf_count)
- - grub_be_to_cpu32 (tail->leaf_stale));
+ /*
+ * Leaf and tail information are only in the data block if the number
+ * of extents is 1.
+ */
+ if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
+ {
+ struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock);
+
+ end = (char *) tail;
+
+ /* Subtract the space used by leaf nodes. */
+ end -= grub_be_to_cpu32 (tail->leaf_count) * sizeof (struct grub_xfs_dir_leaf_entry);
- if (!entries)
- continue;
+ entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale);
+
+ if (!entries)
+ continue;
+ }
/* Iterate over all entries within this block. */
- while ((char *)direntry < (char *)tail)
+ while ((char *) direntry < (char *) end)
{
grub_uint8_t *freetag;
char *filename;
@@ -939,7 +957,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
}
filename = (char *)(direntry + 1);
- if (filename + direntry->len - 1 > (char *) tail)
+ if (filename + direntry->len + 1 > (char *) end)
return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
/* The byte after the filename is for the filetype, padding, or
@@ -953,11 +971,17 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
return 1;
}
- /* Check if last direntry in this block is
- reached. */
- entries--;
- if (!entries)
- break;
+ /*
+ * The expected number of directory entries is only tracked for the
+ * single extent case.
+ */
+ if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
+ {
+ /* Check if last direntry in this block is reached. */
+ entries--;
+ if (!entries)
+ break;
+ }
/* Select the next directory entry. */
direntry = grub_xfs_next_de(dir->data, direntry);
--
2.43.5

View File

@ -1,119 +0,0 @@
From 8aa1ebc1a094c7ae8eb6d2b11412bff99eda66b0 Mon Sep 17 00:00:00 2001
From: Anthony Iliopoulos <ailiop@suse.com>
Date: Thu, 26 Oct 2023 11:53:39 +0200
Subject: [PATCH 674/676] fs/xfs: Add large extent counters incompat feature
support
XFS introduced 64-bit extent counters for inodes via a series of
upstream commits and the feature was marked as stable in v6.5 via
commit 61d7e8274cd8 (xfs: drop EXPERIMENTAL tag for large extent
counts).
Further, xfsprogs release v6.5.0 switched this feature on by default
in mkfs.xfs via commit e5b18d7d1d96 (mkfs: enable large extent counts
by default).
Filesystems formatted with large extent count support, nrext64=1, are
thus currently not recognizable by GRUB, since this is an incompat
feature. Add the required support so that those filesystems and inodes
with large extent counters can be read by GRUB.
Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
Reviewed-by: Andrey Albershteyn <aalbersh@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Tested-by: Marta Lewandowska <mlewando@redhat.com>
Tested-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
grub-core/fs/xfs.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
index 5beda40..f74b316 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -79,6 +79,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
/* Inode flags2 flags */
#define XFS_DIFLAG2_BIGTIME_BIT 3
#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT)
+#define XFS_DIFLAG2_NREXT64_BIT 4
+#define XFS_DIFLAG2_NREXT64 (1 << XFS_DIFLAG2_NREXT64_BIT)
/* incompat feature flags */
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
@@ -86,6 +88,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */
+#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */
/*
* Directory entries with ftype are explicitly handled by GRUB code.
@@ -101,7 +104,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
XFS_SB_FEAT_INCOMPAT_SPINODES | \
XFS_SB_FEAT_INCOMPAT_META_UUID | \
XFS_SB_FEAT_INCOMPAT_BIGTIME | \
- XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
+ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \
+ XFS_SB_FEAT_INCOMPAT_NREXT64)
struct grub_xfs_sblock
{
@@ -203,7 +207,8 @@ struct grub_xfs_inode
grub_uint16_t mode;
grub_uint8_t version;
grub_uint8_t format;
- grub_uint8_t unused2[26];
+ grub_uint8_t unused2[18];
+ grub_uint64_t nextents_big;
grub_uint64_t atime;
grub_uint64_t mtime;
grub_uint64_t ctime;
@@ -547,11 +552,26 @@ get_fsb (const void *keys, int idx)
return grub_be_to_cpu64 (grub_get_unaligned64 (p));
}
+static int
+grub_xfs_inode_has_large_extent_counts (const struct grub_xfs_inode *inode)
+{
+ return inode->version >= 3 &&
+ (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_NREXT64));
+}
+
+static grub_uint64_t
+grub_xfs_get_inode_nextents (struct grub_xfs_inode *inode)
+{
+ return (grub_xfs_inode_has_large_extent_counts (inode)) ?
+ grub_be_to_cpu64 (inode->nextents_big) :
+ grub_be_to_cpu32 (inode->nextents);
+}
+
static grub_disk_addr_t
grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
{
struct grub_xfs_btree_node *leaf = 0;
- int ex, nrec;
+ grub_uint64_t ex, nrec;
struct grub_xfs_extent *exts;
grub_uint64_t ret = 0;
@@ -576,7 +596,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
/ (2 * sizeof (grub_uint64_t));
do
{
- int i;
+ grub_uint64_t i;
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) ||
@@ -633,7 +653,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
grub_addr_t exts_end = 0;
grub_addr_t data_end = 0;
- nrec = grub_be_to_cpu32 (node->inode.nextents);
+ nrec = grub_xfs_get_inode_nextents (&node->inode);
exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
if (grub_mul (sizeof (struct grub_xfs_extent), nrec, &exts_end) ||
--
2.43.5

View File

@ -1,57 +0,0 @@
From 4011de1eec2ccd61246cffe7bb96822ed97942eb Mon Sep 17 00:00:00 2001
From: Jon DeVree <nuxi@vault24.org>
Date: Sun, 11 Feb 2024 10:34:58 -0500
Subject: [PATCH 675/676] fs/xfs: Handle non-continuous data blocks in
directory extents
The directory extent list does not have to be a continuous list of data
blocks. When GRUB tries to read a non-existant member of the list,
grub_xfs_read_file() will return a block of zero'ed memory. Checking for
a zero'ed magic number is sufficient to skip this non-existant data block.
Prior to commit 07318ee7e (fs/xfs: Fix XFS directory extent parsing)
this was handled as a subtle side effect of reading the (non-existant)
tail data structure. Since the block was zero'ed the computation of the
number of directory entries in the block would return 0 as well.
Fixes: 07318ee7e (fs/xfs: Fix XFS directory extent parsing)
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2254370
Signed-off-by: Jon DeVree <nuxi@vault24.org>
Reviewed-By: Vladimir Serbinenko <phcoder@gmail.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 f74b316..a5ab311 100644
--- a/grub-core/fs/xfs.c
+++ b/grub-core/fs/xfs.c
@@ -927,6 +927,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
grub_xfs_first_de(dir->data, dirblock);
int entries = -1;
char *end = dirblock + dirblk_size;
+ grub_uint32_t magic;
numread = grub_xfs_read_file (dir, 0, 0,
blk << dirblk_log2,
@@ -937,6 +938,15 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
return 0;
}
+ /*
+ * If this data block isn't actually part of the extent list then
+ * grub_xfs_read_file() returns a block of zeros. So, if the magic
+ * number field is all zeros then this block should be skipped.
+ */
+ magic = *(grub_uint32_t *)(void *) dirblock;
+ if (!magic)
+ continue;
+
/*
* Leaf and tail information are only in the data block if the number
* of extents is 1.
--
2.43.5

View File

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

View File

@ -1,65 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Fri, 21 Feb 2025 09:06:12 +0800
Subject: [PATCH] fs/ext2: Rework out-of-bounds read for inline and external
extents
Previously, the number of extent entries was not properly capped based
on the actual available space. This could lead to insufficient reads for
external extents since the computation was based solely on the inline
extent layout.
In this patch, when processing the extent header we determine whether
the header is stored inline, i.e. at inode->blocks.dir_blocks, or in an
external extent block. We then clamp the number of entries accordingly
(using max_inline_ext for inline extents and max_external_ext for
external extent blocks).
This change ensures that only the valid number of extent entries is
processed preventing out-of-bound reads and potential filesystem
corruption.
Fixes: 7e2f750f0a (fs/ext2: Fix out-of-bounds read for inline extents)
Signed-off-by: Michael Chang <mchang@suse.com>
Tested-by: Christian Hesse <mail@eworm.de>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ext2.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c
index dc62a6c..b144549 100644
--- a/grub-core/fs/ext2.c
+++ b/grub-core/fs/ext2.c
@@ -474,7 +474,10 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
int i;
grub_disk_addr_t ret;
grub_uint16_t nent;
+ /* Maximum number of extent entries in the inode's inline extent area. */
const grub_uint16_t max_inline_ext = sizeof (inode->blocks) / sizeof (*ext) - 1; /* Minus 1 extent header. */
+ /* Maximum number of extent entries in the external extent block. */
+ const grub_uint16_t max_external_ext = EXT2_BLOCK_SIZE (data) / 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)
@@ -487,8 +490,18 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
nent = grub_le_to_cpu16 (leaf->entries);
- if (leaf->depth == 0)
+ /*
+ * Determine the effective number of extent entries (nent) to process.
+ * If the extent header (leaf) is stored inline in the inodes block
+ * area, i.e. at inode->blocks.dir_blocks, then only max_inline_ext
+ * entries can fit. Otherwise, if the header was read from an external
+ * extent block use the larger limit, max_external_ext, based on the
+ * full block size.
+ */
+ if (leaf == (struct grub_ext4_extent_header *) inode->blocks.dir_blocks)
nent = grub_min (nent, max_inline_ext);
+ else
+ nent = grub_min (nent, max_external_ext);
for (i = 0; i < nent; i++)
{

View File

@ -90,10 +90,13 @@ case "$COMMAND" in
[[ -d "$BLS_DIR" ]] || mkdir -m 0700 -p "$BLS_DIR"
BLS_ID="${MACHINE_ID}-${KERNEL_VERSION}"
BLS_TARGET="${BLS_DIR}/${BLS_ID}.conf"
mkbls "${KERNEL_VERSION}" \
"$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${KERNEL_DIR}")")" \
>"${BLS_TARGET}"
command -v restorecon &>/dev/null && restorecon -R "${BLS_TARGET}"
if [[ -f "${KERNEL_DIR}/bls.conf" ]]; then
cp -aT "${KERNEL_DIR}/bls.conf" "${BLS_TARGET}" || exit $?
else
mkbls "${KERNEL_VERSION}" \
"$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${KERNEL_DIR}")")" \
>"${BLS_TARGET}"
fi
LINUX="$(grep '^linux[ \t]' "${BLS_TARGET}" | sed -e 's,^linux[ \t]*,,')"
INITRD="$(grep '^initrd[ \t]' "${BLS_TARGET}" | sed -e 's,^initrd[ \t]*,,')"
@ -155,9 +158,8 @@ case "$COMMAND" in
if [[ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]] || [[ ! -f /sbin/new-kernel-pkg ]]; then
ARCH="$(uname -m)"
BLS_TARGET="${BLS_DIR}/${MACHINE_ID}-${KERNEL_VERSION}.conf"
BLS_FAKE_TARGET="${BLS_DIR}/ffffffffffffffffffffffffffffffff-${KERNEL_VERSION}.conf"
BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e "s/${KERNEL_VERSION}/${KERNEL_VERSION}~debug/")"
rm -f "${BLS_TARGET}" "${BLS_DEBUG}" "${BLS_FAKE_TARGET}"
rm -f "${BLS_TARGET}" "${BLS_DEBUG}"
for i in vmlinuz System.map config zImage.stub dtb; do
rm -rf "/boot/${i}-${KERNEL_VERSION}"

10
SOURCES/99-grub-mkconfig.install Executable file → Normal file
View File

@ -9,22 +9,16 @@ ARCH=$(uname -m)
[[ -f /etc/default/grub ]] && . /etc/default/grub
# Can't assume a BLS capable bootloader on ppc64
if [[ x$GRUB_ENABLE_BLSCFG = xtrue &&
if [[ x$GRUB_ENABLE_BLSCFG != xfalse &&
$ARCH != "ppc64" && $ARCH != "ppc64le" ]]; then
exit 0
fi
COMMAND="$1"
grub_cfg=/boot/grub2/grub.cfg
if mountpoint -q /boot/efi; then
os_name=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g')
grub_cfg=/boot/efi/EFI/$os_name/grub.cfg
fi
case "$COMMAND" in
add|remove)
grub2-mkconfig --no-grubenv-update -o $grub_cfg >& /dev/null
grub2-mkconfig --no-grubenv-update -o /boot/grub2/grub.cfg >& /dev/null
;;
*)
;;

Binary file not shown.

View File

@ -285,7 +285,13 @@ Requires: %{name}-common = %{evr} \
Requires: %{name}-tools-minimal >= %{evr} \
Requires: %{name}-tools-extra = %{evr} \
Requires: %{name}-tools = %{evr} \
Requires: %{efi_esp_dir}/shim%%(echo %{1} | cut -d- -f2).efi \
Provides: %{name}-efi = %{evr} \
Provides: almalinux(grub2-sig-key) = 202303 \
%{expand:%%ifarch x86_64 \
Conflicts: shim-x64 <= 15.6-1.el8.alma \
Conflicts: shim-ia32 <= 15.6-1.el8.alma \
%%endif} \
%{?legacy_provides:Provides: %{name} = %{evr}} \
%{-o:Obsoletes: %{name}-efi < %{evr}} \
\
@ -540,7 +546,7 @@ install -D -m 700 unicode.pf2 \\\
$RPM_BUILD_ROOT%{efi_esp_dir}/fonts/unicode.pf2 \
${RPM_BUILD_ROOT}/%{_bindir}/%{name}-editenv \\\
${RPM_BUILD_ROOT}%{efi_esp_dir}/grubenv create \
ln -sf ../efi/EFI/%{efi_vendor}/grubenv \\\
ln -sf ../efi/EFI/%{efidir}/grubenv \\\
$RPM_BUILD_ROOT/boot/grub2/grubenv \
cd .. \
%{nil}
@ -589,15 +595,14 @@ install -d -m 0700 ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig \
touch ${RPM_BUILD_ROOT}%{_sysconfdir}/default/grub \
ln -sf ../default/grub \\\
${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/grub \
touch grub.cfg \
install -m 0600 grub.cfg ${RPM_BUILD_ROOT}/boot/%{name}/ \
touch ${RPM_BUILD_ROOT}/boot/%{name}/grub.cfg \
%{nil}
%define define_legacy_variant_files() \
%{expand:%%files %{1}} \
%defattr(-,root,root,-) \
%config(noreplace) %{_sysconfdir}/%{name}.cfg \
%ghost %config(noreplace) %attr(0600,root,root)/boot/%{name}/grub.cfg \
%ghost %config(noreplace) %attr(0700,root,root)/boot/%{name}/grub.cfg \
%dir %attr(0700,root,root)/boot/loader/entries \
%ifarch ppc64le \
%dir %{_libdir}/grub/%{2}/ \

View File

@ -588,89 +588,3 @@ Patch0587: 0587-fs-ntfs-Fix-an-OOB-read-when-parsing-directory-entri.patch
Patch0588: 0588-fs-ntfs-Fix-an-OOB-read-when-parsing-bitmaps-for-ind.patch
Patch0589: 0589-fs-ntfs-Fix-an-OOB-read-when-parsing-a-volume-label.patch
Patch0590: 0590-fs-ntfs-Make-code-more-readable.patch
Patch0591: 0591-grub-mkconfig.in-turn-off-executable-owner-bit.patch
Patch0592: 0592-misc-Implement-grub_strlcpy.patch
Patch0593: 0593-fs-ufs-Fix-a-heap-OOB-write.patch
Patch0594: 0594-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch
Patch0595: 0595-fs-tar-Initialize-name-in-grub_cpio_find_file.patch
Patch0596: 0596-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch
Patch0597: 0597-fs-f2fs-Set-a-grub_errno-if-mount-fails.patch
Patch0598: 0598-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch
Patch0599: 0599-fs-iso9660-Set-a-grub_errno-if-mount-fails.patch
Patch0600: 0600-fs-iso9660-Fix-invalid-free.patch
Patch0601: 0601-fs-jfs-Fix-OOB-read-in-jfs_getent.patch
Patch0602: 0602-fs-jfs-Fix-OOB-read-caused-by-invalid-dir-slot-index.patch
Patch0603: 0603-fs-jfs-Use-full-40-bits-offset-and-address-for-a-dat.patch
Patch0604: 0604-fs-jfs-Inconsistent-signed-unsigned-types-usage-in-r.patch
Patch0605: 0605-fs-ext2-Fix-out-of-bounds-read-for-inline-extents.patch
Patch0606: 0606-fs-ntfs-Fix-out-of-bounds-read.patch
Patch0607: 0607-fs-ntfs-Track-the-end-of-the-MFT-attribute-buffer.patch
Patch0608: 0608-fs-ntfs-Use-a-helper-function-to-access-attributes.patch
Patch0610: 0610-fs-xfs-Fix-out-of-bounds-read.patch
Patch0611: 0611-fs-xfs-Ensuring-failing-to-mount-sets-a-grub_errno.patch
Patch0612: 0612-kern-file-Ensure-file-data-is-set.patch
Patch0613: 0613-kern-file-Implement-filesystem-reference-counting.patch
Patch0614: 0614-disk-loopback-Reference-tracking-for-the-loopback.patch
Patch0615: 0615-kern-disk-Limit-recursion-depth.patch
Patch0616: 0616-kern-partition-Limit-recursion-in-part_iterate.patch
Patch0617: 0617-script-execute-Limit-the-recursion-depth.patch
Patch0618: 0618-net-Unregister-net_default_ip-and-net_default_mac-va.patch
Patch0619: 0619-net-Remove-variables-hooks-when-interface-is-unregis.patch
Patch0620: 0620-net-Fix-OOB-write-in-grub_net_search_config_file.patch
Patch0621: 0621-net-tftp-Fix-stack-buffer-overflow-in-tftp_open.patch
Patch0622: 0622-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch
Patch0623: 0623-kern-dl-Fix-for-an-integer-overflow-in-grub_dl_ref.patch
Patch0624: 0624-kern-dl-Check-for-the-SHF_INFO_LINK-flag-in-grub_dl_.patch
Patch0625: 0625-commands-extcmd-Missing-check-for-failed-allocation.patch
Patch0626: 0626-commands-ls-Fix-NULL-dereference.patch
Patch0627: 0627-commands-pgp-Unregister-the-check_signatures-hooks-o.patch
Patch0628: 0628-normal-Remove-variables-hooks-on-module-unload.patch
Patch0629: 0629-gettext-Remove-variables-hooks-on-module-unload.patch
Patch0630: 0630-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch
Patch0631: 0631-gettext-Integer-overflow-leads-to-heap-OOB-write.patch
Patch0632: 0632-commands-read-Fix-an-integer-overflow-when-supplying.patch
Patch0633: 0633-commands-test-Stack-overflow-due-to-unlimited-recurs.patch
Patch0634: 0634-commands-minicmd-Block-the-dump-command-in-lockdown-.patch
Patch0635: 0635-commands-memrw-Disable-memory-reading-in-lockdown-mo.patch
Patch0636: 0636-commands-hexdump-Disable-memory-reading-in-lockdown-.patch
Patch0637: 0637-fs-bfs-Disable-under-lockdown.patch
Patch0638: 0638-fs-Disable-many-filesystems-under-lockdown.patch
Patch0639: 0639-disk-Use-safe-math-macros-to-prevent-overflows.patch
Patch0640: 0640-disk-Prevent-overflows-when-allocating-memory-for-ar.patch
Patch0641: 0641-disk-Check-if-returned-pointer-for-allocated-memory-.patch
Patch0642: 0642-disk-ieee1275-ofdisk-Call-grub_ieee1275_close-when-g.patch
Patch0643: 0643-fs-Use-safe-math-macros-to-prevent-overflows.patch
Patch0644: 0644-fs-Prevent-overflows-when-allocating-memory-for-arra.patch
Patch0645: 0645-fs-Prevent-overflows-when-assigning-returned-values-.patch
Patch0646: 0646-fs-zfs-Use-safe-math-macros-to-prevent-overflows.patch
Patch0647: 0647-fs-zfs-Prevent-overflows-when-allocating-memory-for-.patch
Patch0648: 0648-fs-zfs-Check-if-returned-pointer-for-allocated-memor.patch
Patch0649: 0649-fs-zfs-Add-missing-NULL-check-after-grub_strdup-call.patch
Patch0650: 0650-net-Use-safe-math-macros-to-prevent-overflows.patch
Patch0651: 0651-net-Prevent-overflows-when-allocating-memory-for-arr.patch
Patch0652: 0652-net-Check-if-returned-pointer-for-allocated-memory-i.patch
Patch0653: 0653-fs-sfs-Check-if-allocated-memory-is-NULL.patch
Patch0654: 0654-script-execute-Fix-potential-underflow-and-NULL-dere.patch
Patch0655: 0655-osdep-unix-getroot-Fix-potential-underflow.patch
Patch0656: 0656-misc-Ensure-consistent-overflow-error-messages.patch
Patch0657: 0657-bus-usb-ehci-Define-GRUB_EHCI_TOGGLE-as-grub_uint32_.patch
Patch0658: 0658-normal-menu-Use-safe-math-to-avoid-an-integer-overfl.patch
Patch0659: 0659-kern-partition-Add-sanity-check-after-grub_strtoul-c.patch
Patch0660: 0660-kern-misc-Add-sanity-check-after-grub_strtoul-call.patch
Patch0661: 0661-loader-i386-linux-Cast-left-shift-to-grub_uint32_t.patch
Patch0662: 0662-loader-i386-bsd-Use-safe-math-to-avoid-underflow.patch
Patch0663: 0663-types-Make-bool-generally-available.patch
Patch0664: 0664-Remove-exttra-bool-definitions.patch
Patch0665: 0665-fs-xfs-Fix-issues-found-while-fuzzing-the-XFS-filesy.patch
Patch0666: 0666-ieee1275-ofnet-Fix-grub_malloc-removed-after-added-s.patch
Patch0667: 0667-fs-xfs-Add-bigtime-incompat-feature-support.patch
Patch0668: 0668-fs-xfs-Add-needsrepair-incompat-feature-support.patch
Patch0669: 0669-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch
Patch0670: 0670-fs-Remove-trailing-whitespaces.patch
Patch0671: 0671-fs-xfs-Fix-memory-leaks-in-XFS-module.patch
Patch0672: 0672-fs-xfs-Incorrect-short-form-directory-data-boundary-.patch
Patch0673: 0673-fs-xfs-Fix-XFS-directory-extent-parsing.patch
Patch0674: 0674-fs-xfs-Add-large-extent-counters-incompat-feature-su.patch
Patch0675: 0675-fs-xfs-Handle-non-continuous-data-blocks-in-director.patch
Patch0676: 0676-fs-xfs-fix-large-extent-counters-incompat-feature-su.patch
Patch0677: 0677-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch

View File

@ -1,3 +1,4 @@
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
grub,3,Free Software Foundation,grub,@@VERSION@@,https//www.gnu.org/software/grub/
grub.rh,2,Red Hat,grub2,@@VERSION_RELEASE@@,mailto:secalert@redhat.com
grub.rh,2,Red Hat,grub2,@@RHEL_VERSION_RELEASE@@,mailto:secalert@redhat.com
grub.almalinux,2,AlmaLinux,grub2,@@VERSION_RELEASE@@,mail:security@almalinux.org

View File

@ -1,3 +1,7 @@
%global efi_vendor almalinux
%global efidir almalinux
%global efi_esp_dir /boot/efi/EFI/%{efidir}
%undefine _hardened_build
%global tarversion 2.02
@ -7,7 +11,7 @@
Name: grub2
Epoch: 1
Version: 2.02
Release: 165%{?dist}
Release: 156%{?dist}.alma.1
Summary: Bootloader with support for Linux, Multiboot and more
Group: System Environment/Base
License: GPLv3+
@ -24,31 +28,29 @@ Source6: gitignore
Source8: strtoull_test.c
Source9: 20-grub.install
Source12: 99-grub-mkconfig.install
Source13: redhatsecurebootca3.cer
Source14: redhatsecureboot301.cer
Source15: redhatsecurebootca5.cer
Source16: redhatsecureboot502.cer
Source17: redhatsecureboot601.cer
Source18: redhatsecureboot701.cer
Source13: almalinuxsecurebootca0.cer
Source19: sbat.csv.in
%include %{SOURCE1}
%if 0%{with_efi_arch}
%define old_sb_ca %{SOURCE13}
%define old_sb_cer %{SOURCE14}
%define old_sb_key redhatsecureboot301
%define sb_ca %{SOURCE15}
%define sb_cer %{SOURCE16}
%define sb_key redhatsecureboot502
%define old_sb_cer %{SOURCE13}
%define old_sb_key almalinuxsecurebootca0
%define sb_ca %{SOURCE13}
%define sb_cer %{SOURCE13}
%define sb_key almalinuxsecurebootca0
%endif
%ifarch ppc64le
%define old_sb_cer %{SOURCE17}
%define sb_cer %{SOURCE18}
%define sb_key redhatsecureboot702
%define old_sb_cer %{SOURCE13}
%define sb_cer %{SOURCE13}
%define sb_key almalinuxsecurebootca0
%endif
# AlmaLinux: keep upstream EVR for RHEL SBAT entry
%define rhel_version_release $(echo %{version}-%{release} | sed 's/\.alma.*//')
# generate with do-rebase
%include %{SOURCE2}
@ -166,7 +168,7 @@ This subpackage provides tools for support of all platforms.
mkdir grub-%{grubefiarch}-%{tarversion}
grep -A100000 '# stuff "make" creates' .gitignore > grub-%{grubefiarch}-%{tarversion}/.gitignore
cp %{SOURCE4} grub-%{grubefiarch}-%{tarversion}/unifont.pcf.gz
sed -e "s,@@VERSION@@,%{version},g" -e "s,@@VERSION_RELEASE@@,%{version}-%{release},g" \
sed -e "s,@@VERSION@@,%{version},g" -e "s,@@VERSION_RELEASE@@,%{version}-%{release},g" -e "s,@@RHEL_VERSION_RELEASE@@,%{rhel_version_release},g" \
%{SOURCE19} > grub-%{grubefiarch}-%{tarversion}/sbat.csv
git add grub-%{grubefiarch}-%{tarversion}
%endif
@ -310,19 +312,6 @@ if [ "$1" = 2 ]; then
/sbin/grub2-switch-to-blscfg --backup-suffix=.rpmsave &>/dev/null || :
fi
%posttrans common
set -eu
GRUB_HOME=/boot/%{name}
if test -f ${GRUB_HOME}/grub.cfg; then
# make sure GRUB_HOME/grub.cfg has 600 permissions
GRUB_CFG_MODE=$(stat --format="%a" ${GRUB_HOME}/grub.cfg)
if ! test "${GRUB_CFG_MODE}" = "600"; then
chmod 0600 ${GRUB_HOME}/grub.cfg
fi
fi
%triggerun -- grub2 < 1:1.99-4
# grub2 < 1.99-4 removed a number of essential files in postun. To fix upgrades
# from the affected grub2 packages, we first back up the files in triggerun and
@ -354,6 +343,20 @@ if [ "$1" = 0 ]; then
/sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/%{name}-dev.info.gz || :
fi
%if 0%{with_efi_arch}
%posttrans %{package_arch}
if [ -d /sys/firmware/efi ] && [ ! -f %{efi_esp_dir}/grub.cfg ]; then
grub2-mkconfig -o %{efi_esp_dir}/grub.cfg || :
fi
%endif
%if 0%{with_alt_efi_arch}
%posttrans %{alt_package_arch}
if [ -d /sys/firmware/efi ] && [ ! -f %{efi_esp_dir}/grub.cfg ]; then
grub2-mkconfig -o %{efi_esp_dir}/grub.cfg || :
fi
%endif
%files common -f grub.lang
%dir %{_libdir}/grub/
%dir %{_datarootdir}/grub/
@ -523,44 +526,8 @@ fi
%endif
%changelog
* Thu Apr 17 2025 Nicolas Frayer <nfrayer@redhat.com> - 2.02-165
- fs/ext2: Rework of OOB read patch
- Resolves: #RHEL-86553
* Fri Apr 4 2025 Leo Sandoval <lsandova@redhat.com> - 2.02-164
- Bump NVR to sign the build
- Resolves: #RHEL-85627
* Thu Apr 3 2025 Nicolas Frayer <nfrayer@redhat.com> - 2.02-163
- fs/xfs: Synced xfs to latest
- Resolves: #RHEL-85627
* Tue Mar 25 2025 Nicolas Frayer <nfrayer@redhat.com> - 2.02-162
- ieee1275/ofnet: Fix grub_malloc() removed after added safe
- Remove 'fs/ntfs: Implement attribute verification' patch
- Related: #RHEL-79837
* Tue Feb 18 2025 Leo Sandoval <lsandova@redhat.com> - 2.02-161
- Add Several CVE fixes
- Resolves CVE-2024-45775 CVE-2025-0624
- Resolves: #RHEL-75735
- Resolves: #RHEL-79837
* Wed Nov 13 2024 Leo Sandoval <lsandova@redhat.com> - 2.02-160
- Remove BLS fake config in case of kernel removal
- Resolves: #RHEL-4316
* Tue Nov 12 2024 Leo Sandoval <lsandova@redhat.com> - 2.02-159
- Fix default behavior when GRUB_ENABLE_BLSCFG is not present
- Resolves: #RHEL-4319
* Thu Sep 19 2024 Leo Sandoval <lsandova@redhat.com> - 2.02-158
- grub-mkconfig.in: turn off executable owner bit
- Resolves: #RHEL-58835
* Wed Aug 14 2024 Leo Sandoval <lsandova@redhat.com> - 2.02-157
- 20-grub-install: fix SELinux security type context for BLS
- Resolves: #RHEL-4395
* Wed Apr 10 2024 Andrew Lukoshko <alukoshko@almalinux.org> - 2.02-156.alma.1
- Debrand for AlmaLinux
* Tue Feb 20 2024 Nicolas Frayer <nfrayer@redhat.com> - 2.02-156
- fs/ntfs: OOB write fix