https://github.com/torvalds/linux
Revision 29a5b8a137ac8eb410cc823653a29ac0e7b7e1b0 authored by Luís Henriques on 22 August 2022, 09:42:35 UTC, committed by Theodore Ts'o on 22 September 2022, 14:50:54 UTC
When walking through an inode extents, the ext4_ext_binsearch_idx() function
assumes that the extent header has been previously validated.  However, there
are no checks that verify that the number of entries (eh->eh_entries) is
non-zero when depth is > 0.  And this will lead to problems because the
EXT_FIRST_INDEX() and EXT_LAST_INDEX() will return garbage and result in this:

[  135.245946] ------------[ cut here ]------------
[  135.247579] kernel BUG at fs/ext4/extents.c:2258!
[  135.249045] invalid opcode: 0000 [#1] PREEMPT SMP
[  135.250320] CPU: 2 PID: 238 Comm: tmp118 Not tainted 5.19.0-rc8+ #4
[  135.252067] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b-rebuilt.opensuse.org 04/01/2014
[  135.255065] RIP: 0010:ext4_ext_map_blocks+0xc20/0xcb0
[  135.256475] Code:
[  135.261433] RSP: 0018:ffffc900005939f8 EFLAGS: 00010246
[  135.262847] RAX: 0000000000000024 RBX: ffffc90000593b70 RCX: 0000000000000023
[  135.264765] RDX: ffff8880038e5f10 RSI: 0000000000000003 RDI: ffff8880046e922c
[  135.266670] RBP: ffff8880046e9348 R08: 0000000000000001 R09: ffff888002ca580c
[  135.268576] R10: 0000000000002602 R11: 0000000000000000 R12: 0000000000000024
[  135.270477] R13: 0000000000000000 R14: 0000000000000024 R15: 0000000000000000
[  135.272394] FS:  00007fdabdc56740(0000) GS:ffff88807dd00000(0000) knlGS:0000000000000000
[  135.274510] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  135.276075] CR2: 00007ffc26bd4f00 CR3: 0000000006261004 CR4: 0000000000170ea0
[  135.277952] Call Trace:
[  135.278635]  <TASK>
[  135.279247]  ? preempt_count_add+0x6d/0xa0
[  135.280358]  ? percpu_counter_add_batch+0x55/0xb0
[  135.281612]  ? _raw_read_unlock+0x18/0x30
[  135.282704]  ext4_map_blocks+0x294/0x5a0
[  135.283745]  ? xa_load+0x6f/0xa0
[  135.284562]  ext4_mpage_readpages+0x3d6/0x770
[  135.285646]  read_pages+0x67/0x1d0
[  135.286492]  ? folio_add_lru+0x51/0x80
[  135.287441]  page_cache_ra_unbounded+0x124/0x170
[  135.288510]  filemap_get_pages+0x23d/0x5a0
[  135.289457]  ? path_openat+0xa72/0xdd0
[  135.290332]  filemap_read+0xbf/0x300
[  135.291158]  ? _raw_spin_lock_irqsave+0x17/0x40
[  135.292192]  new_sync_read+0x103/0x170
[  135.293014]  vfs_read+0x15d/0x180
[  135.293745]  ksys_read+0xa1/0xe0
[  135.294461]  do_syscall_64+0x3c/0x80
[  135.295284]  entry_SYSCALL_64_after_hwframe+0x46/0xb0

This patch simply adds an extra check in __ext4_ext_check(), verifying that
eh_entries is not 0 when eh_depth is > 0.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=215941
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216283
Cc: Baokun Li <libaokun1@huawei.com>
Cc: stable@kernel.org
Signed-off-by: Luís Henriques <lhenriques@suse.de>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Baokun Li <libaokun1@huawei.com>
Link: https://lore.kernel.org/r/20220822094235.2690-1-lhenriques@suse.de
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
1 parent 83e80a6
History
Tip revision: 29a5b8a137ac8eb410cc823653a29ac0e7b7e1b0 authored by Luís Henriques on 22 August 2022, 09:42:35 UTC
ext4: fix bug in extents parsing when eh_entries == 0 and eh_depth > 0
Tip revision: 29a5b8a
File Mode Size
9p
adfs
affs
afs
autofs
befs
bfs
btrfs
cachefiles
ceph
cifs
coda
configfs
cramfs
crypto
debugfs
devpts
dlm
ecryptfs
efivarfs
efs
erofs
exfat
exportfs
ext2
ext4
f2fs
fat
freevxfs
fscache
fuse
gfs2
hfs
hfsplus
hostfs
hpfs
hugetlbfs
iomap
isofs
jbd2
jffs2
jfs
kernfs
ksmbd
lockd
minix
netfs
nfs
nfs_common
nfsd
nilfs2
nls
notify
ntfs
ntfs3
ocfs2
omfs
openpromfs
orangefs
overlayfs
proc
pstore
qnx4
qnx6
quota
ramfs
reiserfs
romfs
smbfs_common
squashfs
sysfs
sysv
tracefs
ubifs
udf
ufs
unicode
vboxsf
verity
xfs
zonefs
Kconfig -rw-r--r-- 9.8 KB
Kconfig.binfmt -rw-r--r-- 7.4 KB
Makefile -rw-r--r-- 4.5 KB
aio.c -rw-r--r-- 61.0 KB
anon_inodes.c -rw-r--r-- 8.1 KB
attr.c -rw-r--r-- 13.3 KB
bad_inode.c -rw-r--r-- 5.8 KB
binfmt_aout.c -rw-r--r-- 8.2 KB
binfmt_elf.c -rw-r--r-- 61.6 KB
binfmt_elf_fdpic.c -rw-r--r-- 43.4 KB
binfmt_elf_test.c -rw-r--r-- 2.7 KB
binfmt_flat.c -rw-r--r-- 25.8 KB
binfmt_misc.c -rw-r--r-- 17.4 KB
binfmt_script.c -rw-r--r-- 4.2 KB
buffer.c -rw-r--r-- 80.1 KB
char_dev.c -rw-r--r-- 16.5 KB
compat_binfmt_elf.c -rw-r--r-- 3.8 KB
coredump.c -rw-r--r-- 28.8 KB
d_path.c -rw-r--r-- 11.5 KB
dax.c -rw-r--r-- 52.4 KB
dcache.c -rw-r--r-- 88.0 KB
direct-io.c -rw-r--r-- 39.0 KB
drop_caches.c -rw-r--r-- 1.9 KB
eventfd.c -rw-r--r-- 12.0 KB
eventpoll.c -rw-r--r-- 64.9 KB
exec.c -rw-r--r-- 51.1 KB
fcntl.c -rw-r--r-- 23.3 KB
fhandle.c -rw-r--r-- 6.8 KB
file.c -rw-r--r-- 31.6 KB
file_table.c -rw-r--r-- 11.0 KB
filesystems.c -rw-r--r-- 6.5 KB
fs-writeback.c -rw-r--r-- 78.8 KB
fs_context.c -rw-r--r-- 17.7 KB
fs_parser.c -rw-r--r-- 10.7 KB
fs_pin.c -rw-r--r-- 1.9 KB
fs_struct.c -rw-r--r-- 3.4 KB
fs_types.c -rw-r--r-- 2.5 KB
fsopen.c -rw-r--r-- 10.9 KB
init.c -rw-r--r-- 6.1 KB
inode.c -rw-r--r-- 67.3 KB
internal.h -rw-r--r-- 5.8 KB
ioctl.c -rw-r--r-- 23.9 KB
kernel_read_file.c -rw-r--r-- 4.4 KB
libfs.c -rw-r--r-- 39.7 KB
locks.c -rw-r--r-- 75.1 KB
mbcache.c -rw-r--r-- 12.3 KB
mount.h -rw-r--r-- 4.0 KB
mpage.c -rw-r--r-- 18.8 KB
namei.c -rw-r--r-- 136.5 KB
namespace.c -rw-r--r-- 113.9 KB
no-block.c -rw-r--r-- 478 bytes
nsfs.c -rw-r--r-- 6.6 KB
open.c -rw-r--r-- 37.4 KB
pipe.c -rw-r--r-- 36.0 KB
pnode.c -rw-r--r-- 15.1 KB
pnode.h -rw-r--r-- 2.0 KB
posix_acl.c -rw-r--r-- 25.8 KB
proc_namespace.c -rw-r--r-- 8.1 KB
read_write.c -rw-r--r-- 40.0 KB
readdir.c -rw-r--r-- 13.9 KB
remap_range.c -rw-r--r-- 14.1 KB
select.c -rw-r--r-- 34.7 KB
seq_file.c -rw-r--r-- 25.7 KB
signalfd.c -rw-r--r-- 8.7 KB
splice.c -rw-r--r-- 38.7 KB
stack.c -rw-r--r-- 2.5 KB
stat.c -rw-r--r-- 21.7 KB
statfs.c -rw-r--r-- 9.7 KB
super.c -rw-r--r-- 46.7 KB
sync.c -rw-r--r-- 10.4 KB
sysctls.c -rw-r--r-- 809 bytes
timerfd.c -rw-r--r-- 13.9 KB
userfaultfd.c -rw-r--r-- 54.6 KB
utimes.c -rw-r--r-- 7.6 KB
xattr.c -rw-r--r-- 28.9 KB

back to top