| From: "Darrick J. Wong" <darrick.wong@oracle.com> |
| Date: Sat, 10 Dec 2016 09:55:01 -0500 |
| Subject: ext4: reject inodes with negative size |
| |
| commit 7e6e1ef48fc02f3ac5d0edecbb0c6087cd758d58 upstream. |
| |
| Don't load an inode with a negative size; this causes integer overflow |
| problems in the VFS. |
| |
| [ Added EXT4_ERROR_INODE() to mark file system as corrupted. -TYT] |
| |
| Fixes: a48380f769df (ext4: rename i_dir_acl to i_size_high) |
| Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| [bwh: Backported to 3.2: use EIO instead of EFSCORRUPTED] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| fs/ext4/inode.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/fs/ext4/inode.c |
| +++ b/fs/ext4/inode.c |
| @@ -3829,6 +3829,7 @@ struct inode *ext4_iget(struct super_blo |
| struct inode *inode; |
| journal_t *journal = EXT4_SB(sb)->s_journal; |
| long ret; |
| + loff_t size; |
| int block; |
| |
| inode = iget_locked(sb, ino); |
| @@ -3880,6 +3881,11 @@ struct inode *ext4_iget(struct super_blo |
| ei->i_file_acl |= |
| ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32; |
| inode->i_size = ext4_isize(raw_inode); |
| + if ((size = i_size_read(inode)) < 0) { |
| + EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size); |
| + ret = -EIO; |
| + goto bad_inode; |
| + } |
| ei->i_disksize = inode->i_size; |
| #ifdef CONFIG_QUOTA |
| ei->i_reserved_quota = 0; |