During inode expansion, ext4_xattr_move_to_block() processes xattr entries from on-disk structures without validating their integrity. Corrupted filesystems may contain xattr entries where e_value_size is zero but e_value_inum is non-zero, indicating the entry claims to store its value in a separate inode but has no actual value. This corruption pattern leads to a WARNING in ext4_xattr_block_set() when it encounters i->value_len of zero while i->in_inode is set, violating the function's invariant that in-inode xattrs must have non-zero length. Add validation in ext4_xattr_move_to_block() to detect this specific corruption pattern and return -EFSCORRUPTED, preventing the invalid data from propagating to downstream functions and causing warnings. Reported-by: syzbot+4c9d23743a2409b80293@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=4c9d23743a2409b80293 Signed-off-by: Deepanshu Kartikey --- fs/ext4/xattr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 5a6fe1513fd2..60e224c622b4 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -2607,7 +2607,10 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode); int needs_kvfree = 0; int error; - + if (value_size == 0 && entry->e_value_inum != 0) { + error = -EFSCORRUPTED; + goto out; + } is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS); bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS); b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS); -- 2.43.0