Commit 5f920d5d authored by Jan Kara's avatar Jan Kara Committed by Theodore Ts'o
Browse files

ext4: verify fast symlink length



Verify fast symlink length stored in inode->i_size matches the string
stored in the inode to avoid surprises from corrupted filesystems.

Reported-by: default avatar <syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com>
Tested-by: default avatar <syzbot+48a99e426f29859818c0@syzkaller.appspotmail.com>
Fixes: bae80473 ("ext4: use inode_set_cached_link()")
Suggested-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Reviewed-by: default avatarBaokun Li <libaokun1@huawei.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Link: https://patch.msgid.link/20250206094454.20522-2-jack@suse.cz


Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent c8e008b6
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -5029,8 +5029,16 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
			inode->i_op = &ext4_encrypted_symlink_inode_operations;
		} else if (ext4_inode_is_fast_symlink(inode)) {
			inode->i_op = &ext4_fast_symlink_inode_operations;
			nd_terminate_link(ei->i_data, inode->i_size,
				sizeof(ei->i_data) - 1);
			if (inode->i_size == 0 ||
			    inode->i_size >= sizeof(ei->i_data) ||
			    strnlen((char *)ei->i_data, inode->i_size + 1) !=
								inode->i_size) {
				ext4_error_inode(inode, function, line, 0,
					"invalid fast symlink length %llu",
					 (unsigned long long)inode->i_size);
				ret = -EFSCORRUPTED;
				goto bad_inode;
			}
			inode_set_cached_link(inode, (char *)ei->i_data,
					      inode->i_size);
		} else {