summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-01-16 13:04:47 -0600
committerTom Rini <[email protected]>2026-01-16 13:04:47 -0600
commitadccdb22ebd799a7d964892d4a7e7454ed3c239c (patch)
tree04fa8942c4cbe7aeca90b1f30a66b4a8891bd25b /fs
parent8241bd6a82e181bbb3b7f4440a52205a40e2e617 (diff)
parentfc16c847a1c9c6e0ee1f605849cc500a04c21602 (diff)
Merge patch series "fix integer overflows in filesystem code"
This series from Timo tp Preißl <[email protected]> fixes some (potential) interger overflows in some filesystems by using __builtin_XXX_overflow helps to catch issues. Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/ext4_write.c8
-rw-r--r--fs/fs.c16
-rw-r--r--fs/squashfs/sqfs.c6
-rw-r--r--fs/zfs/zfs.c6
4 files changed, 30 insertions, 6 deletions
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index 2b8ed1cd110..1abedcede72 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -108,7 +108,13 @@ int ext4fs_get_bgdtable(void)
{
int status;
struct ext_filesystem *fs = get_fs();
- int gdsize_total = ROUND(fs->no_blkgrp * fs->gdsize, fs->blksz);
+ size_t alloc;
+ size_t gdsize_total;
+
+ if (__builtin_mul_overflow(fs->no_blkgrp, fs->gdsize, &alloc))
+ return -1;
+
+ gdsize_total = ROUND(alloc, fs->blksz);
fs->no_blk_pergdt = gdsize_total / fs->blksz;
/* allocate memory for gdtable */
diff --git a/fs/fs.c b/fs/fs.c
index c7706d9af85..319c55c440a 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -1059,15 +1059,25 @@ int do_mv(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[],
*/
if (dirs) {
char *src_name = strrchr(src, '/');
- int dst_len;
if (src_name)
src_name += 1;
else
src_name = src;
- dst_len = strlen(dst);
- new_dst = calloc(1, dst_len + strlen(src_name) + 2);
+ size_t dst_len = strlen(dst);
+ size_t src_len = strlen(src_name);
+ size_t total;
+
+ if (__builtin_add_overflow(dst_len, src_len, &total) ||
+ __builtin_add_overflow(total, 2, &total)) {
+ return 0;
+ }
+
+ new_dst = calloc(1, total);
+ if (!new_dst)
+ return 0;
+
strcpy(new_dst, dst);
/* If there is already a trailing slash, don't add another */
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index 4d3d83b7587..f668c26472e 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -255,10 +255,14 @@ static char *sqfs_concat_tokens(char **token_list, int token_count)
{
char *result;
int i, length = 0, offset = 0;
+ size_t alloc;
length = sqfs_get_tokens_length(token_list, token_count);
- result = malloc(length + 1);
+ if (__builtin_add_overflow(length, 1, &alloc))
+ return 0;
+
+ result = malloc(alloc);
if (!result)
return NULL;
diff --git a/fs/zfs/zfs.c b/fs/zfs/zfs.c
index 410a61aa611..c7502c344ff 100644
--- a/fs/zfs/zfs.c
+++ b/fs/zfs/zfs.c
@@ -1617,6 +1617,7 @@ zfs_nvlist_lookup_nvlist(char *nvlist, char *name)
char *ret;
size_t size;
int found;
+ size_t alloc;
found = nvlist_find_value(nvlist, name, DATA_TYPE_NVLIST, &nvpair,
&size, 0);
@@ -1627,7 +1628,10 @@ zfs_nvlist_lookup_nvlist(char *nvlist, char *name)
* nvlist to hold the encoding method, and two zero uint32's after the
* nvlist as the NULL terminator.
*/
- ret = calloc(1, size + 3 * sizeof(uint32_t));
+ if (__builtin_add_overflow(size, 3 * sizeof(uint32_t), &alloc))
+ return 0;
+
+ ret = calloc(1, alloc);
if (!ret)
return 0;
memcpy(ret, nvlist, sizeof(uint32_t));