123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- From 005280a4b3ba41ab0b4fea5e1d2a874646e6e12d 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>
- Conflicts:
- grub-core/fs/erofs.c
- Upstream: 6608163b08a7a8be4b0ab2a5cd4593bba07fe2b7
- Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.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 c1dcc6285..0816b28de 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 aae81482b..0625b1166 100644
- --- a/grub-core/fs/btrfs.c
- +++ b/grub-core/fs/btrfs.c
- @@ -1801,6 +1801,7 @@ find_path (struct grub_btrfs_data *data,
- char *path_alloc = NULL;
- char *origpath = NULL;
- unsigned symlinks_max = 32;
- + grub_size_t sz;
-
- err = get_root (data, key, tree, type);
- if (err)
- @@ -1891,9 +1892,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);
- @@ -1955,8 +1962,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);
- @@ -2078,6 +2093,7 @@ grub_btrfs_dir (grub_device_t device, const char *path,
- grub_uint64_t tree;
- grub_uint8_t type;
- grub_size_t est_size = 0;
- + grub_size_t sz;
-
- if (!data)
- return grub_errno;
- @@ -2119,9 +2135,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 5d41b6fdb..6ba58b354 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 f6d6beaa5..72b4aa1e6 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 a009f2c2d..f168a318e 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 6e9d63874..f91ff3bfa 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;
- }
-
- @@ -580,6 +580,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)
- @@ -595,7 +596,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 74feeb86a..70c9f449b 100644
- --- a/grub-core/fs/xfs.c
- +++ b/grub-core/fs/xfs.c
- @@ -718,6 +718,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)
- {
- @@ -739,7 +740,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;
-
- @@ -789,8 +795,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 ();
- --
- 2.50.1
|