[PATCH v3] erofs-utils: lib: validate h_shared_count in erofs_init_inode_xattrs()

Utkal Singh singhutkal015 at gmail.com
Tue Mar 17 22:30:21 AEDT 2026


h_shared_count is read from the on-disk xattr ibody header and used
to size a heap allocation and drive a loop reading shared xattr IDs.
If the value is corrupted to exceed the space available in xattr_isize,
the loop reads past the ibody region and the malloc is oversized.

This does not affect system stability but results in silently
processing garbage data from corrupted images across all library
consumers (dump.erofs, erofsfuse, rebuild).

Validate h_shared_count against the available ibody space.
Return -EFSCORRUPTED on failure.

Reproducer:
  mkdir testdir && echo hello > testdir/a.txt
  setfattr -n user.test -v val testdir/a.txt
  mkfs.erofs test.img testdir
  # corrupt h_shared_count (offset = nid*32 + inode_size + 4) to 0xFF
  # then: fsck.erofs --extract=/tmp/out --xattrs test_corrupted.img
  # Without patch: silently processes invalid shared xattr IDs
  # With patch: returns -EFSCORRUPTED

Signed-off-by: Utkal Singh <singhutkal015 at gmail.com>
---
 lib/xattr.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/lib/xattr.c b/lib/xattr.c
index 565070a..9d52a18 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -1182,6 +1182,13 @@ static int erofs_init_inode_xattrs(struct erofs_inode *vi)
 
 	ih = it.kaddr;
 	vi->xattr_shared_count = ih->h_shared_count;
+	if (vi->xattr_shared_count * sizeof(__le32) >
+	    vi->xattr_isize - sizeof(struct erofs_xattr_ibody_header)) {
+		erofs_err("invalid h_shared_count %u in nid %llu",
+			  vi->xattr_shared_count, vi->nid | 0ULL);
+		erofs_put_metabuf(&it.buf);
+		return -EFSCORRUPTED;
+	}
 	vi->xattr_shared_xattrs = malloc(vi->xattr_shared_count * sizeof(uint));
 	if (!vi->xattr_shared_xattrs) {
 		erofs_put_metabuf(&it.buf);
-- 
2.43.0



More information about the Linux-erofs mailing list