[PATCH 3/3] tune2fs: Add bounds checking for extended attribute processing
Josh Hunt <[email protected]> Thu, 30 Jul 2026 20:37:01 -0700
| Newsgroups | org.kernel.vger.linux-ext4 |
|---|---|
| Message-ID | <[email protected]> |
From: Kit Knox <[email protected]> Add validation to prevent buffer overflow when processing extended attributes: - Check ea_inode size against maximum (64KB) before reading - Validate xattr entry bounds before accessing next entry This prevents malformed filesystem images from causing out-of-bounds memory access during UUID or checksum updates. Signed-off-by: Kit Knox <[email protected]> --- misc/tune2fs.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 3db57632..8c292686 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -744,18 +744,25 @@ struct rewrite_context { exit(1); \ } while (0); +#define EA_INODE_SIZE_MAX (64 * 1024) + static void update_ea_inode_hash(struct rewrite_context *ctx, ext2_ino_t ino, struct ext2_inode *inode) { errcode_t retval; ext2_file_t file; __u32 hash; + __u64 ea_size = EXT2_I_SIZE(inode); + + if (ea_size > EA_INODE_SIZE_MAX) + fatal_err(EXT2_ET_EA_BAD_VALUE_SIZE, + "ea_inode %u has invalid size %llu", ino, + (unsigned long long) ea_size); retval = ext2fs_file_open(ctx->fs, ino, 0, &file); if (retval) fatal_err(retval, "open ea_inode"); - retval = ext2fs_file_read(file, ctx->ea_buf, inode->i_size, - NULL); + retval = ext2fs_file_read(file, ctx->ea_buf, ea_size, NULL); if (retval) fatal_err(retval, "read ea_inode"); retval = ext2fs_file_close(file); @@ -763,7 +770,7 @@ static void update_ea_inode_hash(struct rewrite_context *ctx, ext2_ino_t ino, fatal_err(retval, "close ea_inode"); hash = ext2fs_crc32c_le(ctx->fs->csum_seed, - (unsigned char *) ctx->ea_buf, inode->i_size); + (unsigned char *) ctx->ea_buf, ea_size); ext2fs_set_ea_inode_hash(inode, hash); } @@ -775,6 +782,9 @@ static int update_xattr_entry_hashes(ext2_filsys fs, errcode_t retval; while (entry < end && !EXT2_EXT_IS_LAST_ENTRY(entry)) { + if ((char *)end < (char *)entry + sizeof(*entry)) + fatal_err(EXT2_ET_EA_BAD_NAME_LEN, + "xattr entry exceeds buffer bounds"); if (entry->e_value_inum) { retval = ext2fs_ext_attr_hash_entry2(fs, entry, NULL, &entry->e_hash); @@ -784,6 +794,9 @@ static int update_xattr_entry_hashes(ext2_filsys fs, } entry = EXT2_EXT_ATTR_NEXT(entry); } + if (entry > end) + fatal_err(EXT2_ET_EA_BAD_NAME_LEN, + "xattr entry exceeds buffer bounds"); return modified; } -- 2.34.1