Skip to content

Commit 2220eaf

Browse files
committed
ext4: add bounds checking in get_max_inline_xattr_value_size()
Normally the extended attributes in the inode body would have been checked when the inode is first opened, but if someone is writing to the block device while the file system is mounted, it's possible for the inode table to get corrupted. Add bounds checking to avoid reading beyond the end of allocated memory if this happens. Reported-by: syzbot+1966db24521e5f6e23f7@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=1966db24521e5f6e23f7 Cc: stable@kernel.org Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent 6dcc98f commit 2220eaf

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

fs/ext4/inline.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ static int get_max_inline_xattr_value_size(struct inode *inode,
3434
struct ext4_xattr_ibody_header *header;
3535
struct ext4_xattr_entry *entry;
3636
struct ext4_inode *raw_inode;
37+
void *end;
3738
int free, min_offs;
3839

3940
if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
@@ -57,14 +58,23 @@ static int get_max_inline_xattr_value_size(struct inode *inode,
5758
raw_inode = ext4_raw_inode(iloc);
5859
header = IHDR(inode, raw_inode);
5960
entry = IFIRST(header);
61+
end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
6062

6163
/* Compute min_offs. */
62-
for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
64+
while (!IS_LAST_ENTRY(entry)) {
65+
void *next = EXT4_XATTR_NEXT(entry);
66+
67+
if (next >= end) {
68+
EXT4_ERROR_INODE(inode,
69+
"corrupt xattr in inline inode");
70+
return 0;
71+
}
6372
if (!entry->e_value_inum && entry->e_value_size) {
6473
size_t offs = le16_to_cpu(entry->e_value_offs);
6574
if (offs < min_offs)
6675
min_offs = offs;
6776
}
77+
entry = next;
6878
}
6979
free = min_offs -
7080
((void *)entry - (void *)IFIRST(header)) - sizeof(__u32);

0 commit comments

Comments
 (0)