- Resolves: CVE-2024-45779 CVE-2024-45778 CVE-2025-1118 - Resolves: CVE-2025-0677 CVE-2024-45782 CVE-2025-0690 - Resolves: CVE-2024-45783 CVE-2025-0624 CVE-2024-45776 - Resolves: CVE-2025-0622 CVE-2024-45774 CVE-2024-45775 - Resolves: CVE-2024-45781 CVE-2024-45780 - Resolves: #RHEL-79700 - Resolves: #RHEL-79341 - Resolves: #RHEL-79875 - Resolves: #RHEL-79849 - Resolves: #RHEL-79707 - Resolves: #RHEL-79857 - Resolves: #RHEL-79709 - Resolves: #RHEL-79846 - Resolves: #RHEL-75737 - Resolves: #RHEL-79713 - Resolves: #RHEL-73785 - Resolves: #RHEL-73787 - Resolves: #RHEL-79704 - Resolves: #RHEL-79702 Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
354 lines
10 KiB
Diff
354 lines
10 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Lidong Chen <lidong.chen@oracle.com>
|
|
Date: Wed, 12 Feb 2025 10:33:31 -0600
|
|
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 3ed37a4db..0d45f09d3 100644
|
|
--- a/grub-core/fs/btrfs.c
|
|
+++ b/grub-core/fs/btrfs.c
|
|
@@ -1999,6 +1999,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);
|
|
@@ -2125,9 +2126,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);
|
|
@@ -2191,8 +2198,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);
|
|
@@ -2334,6 +2349,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;
|
|
@@ -2383,9 +2399,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 4e885d623..ce49aa0b1 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+");
|
|
|
|
@@ -48,6 +49,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;
|
|
|
|
@@ -76,7 +78,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;
|
|
|
|
@@ -110,10 +115,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 e5dcbc470..a3182a3e5 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+");
|
|
|
|
@@ -958,6 +959,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)
|
|
{
|
|
@@ -968,7 +970,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;
|
|
|
|
@@ -997,6 +1004,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)
|
|
{
|
|
@@ -1010,7 +1018,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 ccfa3eea5..0ee9bb2e8 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 7b0ea577e..ff6fe3d83 100644
|
|
--- a/grub-core/fs/xfs.c
|
|
+++ b/grub-core/fs/xfs.c
|
|
@@ -676,6 +676,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)
|
|
{
|
|
@@ -697,7 +698,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;
|
|
|
|
@@ -747,8 +753,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 ();
|