Created attachment 1868128 [details] The crashing input alongside a script to automatically reproduce the bug. SIGSEGV and out-of-bounds write during processing file via e2fsck # Description During the processing of the attached disk image via ``` e2fsck -p -f /testcase ``` an out-of-bounds write is triggered and causes a segmentation fault (SIGSEGV). This bug allows an attacker to perform a denial of service and possibly opens up other attack vectors. To reproduce the crash, we provide scripts alongside the crashing input: - ./reproduce-fedora.sh: Reproduce crash via a Fedora 35 docker container - ./reproduce-ubuntu.sh: Reproduce crash via a Ubuntu 20.04 docker container Unfortunately, we were not able to reproduce the issue on RHEL UBI since it appears that `e2fsprogs` is not part of the standard repository. If you need further details, we are happy to assist where possible. # yum info e2fsprogs Last metadata expiration check: 0:33:04 ago on Thu Mar 24 13:07:02 2022. Installed Packages Name : e2fsprogs Version : 1.46.3 Release : 1.fc35 Architecture : x86_64 Size : 4.2 M Source : e2fsprogs-1.46.3-1.fc35.src.rpm Repository : @System From repo : fedora Summary : Utilities for managing ext2, ext3, and ext4 file systems URL : http://e2fsprogs.sourceforge.net/ License : GPLv2 Description : The e2fsprogs package contains a number of utilities for creating, : checking, modifying, and correcting any inconsistencies in second, : third and fourth extended (ext2/ext3/ext4) file systems. E2fsprogs : contains e2fsck (used to repair file system inconsistencies after an : unclean shutdown), mke2fs (used to initialize a partition to contain : an empty ext2 file system), debugfs (used to examine the internal : structure of a file system, to manually repair a corrupted : file system, or to create test cases for e2fsck), tune2fs (used to : modify file system parameters), and most of the other core ext2fs : file system utilities. : : You should install the e2fsprogs package if you need to manage the : performance of an ext2, ext3, or ext4 file system. # valgrind fedora [+] Running e2fsck -p -f /testcase ==1== Memcheck, a memory error detector ==1== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==1== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info ==1== Command: e2fsck -p -f /testcase ==1== /testcase: Directory inode 2 has extent marked uninitialized at block 0. FIXED. /testcase: Directory inode 2 has extent marked uninitialized at block 1. FIXED. /testcase: Directory inode 2 has extent marked uninitialized at block 2. FIXED. /testcase: Inode 2 extent tree (at level 1) could be shorter. IGNORED. /testcase: Inode 3 extent tree (at level 2) could be narrower. IGNORED. /testcase: Inode 4 extent tree (at level 1) could be narrower. IGNORED. /testcase: Directory inode 11 has extent marked uninitialized at block 0. FIXED. /testcase: Directory inode 11 has extent marked uninitialized at block 1. FIXED. /testcase: Directory inode 11 has extent marked uninitialized at block 2. FIXED. /testcase: Directory inode 11 has extent marked uninitialized at block 4. FIXED. /testcase: Directory inode 11 has extent marked uninitialized at block 5. FIXED. /testcase: Inode 11 extent tree (at level 1) could be shorter. IGNORED. /testcase: Inode 11, i_size is 1191192576, should be 10240. FIXED. /testcase: Inode 2 extent tree (at level 1) could be shorter. IGNORED. [ERROR] quotaio_v2.c:198:v2_init_io: Quota inode 3 corrupted: file size 67382272; dqi_blocks 536870924 [ERROR] quotaio.c:256:quota_file_open: qh_ops->init_io failed /testcase: Update quota info for quota type 0. ==1== Invalid read of size 2 ==1== at 0x484B2CF: memmove (vg_replace_strmem.c:1382) ==1== by 0x487B700: ext2fs_extent_delete (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x488E42B: ext2fs_punch (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x13E890: quota_inode_truncate (quotaio.c:125) ==1== by 0x149781: UnknownInlinedFun (quotaio.c:283) ==1== by 0x149781: quota_file_create (quotaio.c:336) ==1== by 0x14291D: quota_write_inode (mkquota.c:197) ==1== by 0x11BD9A: main (unix.c:1968) ==1== Address 0x4b634c0 is 0 bytes after a block of size 1,024 alloc'd ==1== at 0x484186F: malloc (vg_replace_malloc.c:381) ==1== by 0x48833EC: ext2fs_get_mem (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x487AFE6: ext2fs_extent_get (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x487B19C: ext2fs_extent_goto2 (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x488E1AC: ext2fs_punch (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x13E890: quota_inode_truncate (quotaio.c:125) ==1== by 0x149781: UnknownInlinedFun (quotaio.c:283) ==1== by 0x149781: quota_file_create (quotaio.c:336) ==1== by 0x14291D: quota_write_inode (mkquota.c:197) ==1== by 0x11BD9A: main (unix.c:1968) ==1== ==1== Invalid read of size 2 ==1== at 0x484B2C0: memmove (vg_replace_strmem.c:1382) ==1== by 0x487B700: ext2fs_extent_delete (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x488E42B: ext2fs_punch (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x13E890: quota_inode_truncate (quotaio.c:125) ==1== by 0x149781: UnknownInlinedFun (quotaio.c:283) ==1== by 0x149781: quota_file_create (quotaio.c:336) ==1== by 0x14291D: quota_write_inode (mkquota.c:197) ==1== by 0x11BD9A: main (unix.c:1968) ==1== Address 0x4b634c2 is 2 bytes after a block of size 1,024 alloc'd ==1== at 0x484186F: malloc (vg_replace_malloc.c:381) ==1== by 0x48833EC: ext2fs_get_mem (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x487AFE6: ext2fs_extent_get (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x487B19C: ext2fs_extent_goto2 (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x488E1AC: ext2fs_punch (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x13E890: quota_inode_truncate (quotaio.c:125) ==1== by 0x149781: UnknownInlinedFun (quotaio.c:283) ==1== by 0x149781: quota_file_create (quotaio.c:336) ==1== by 0x14291D: quota_write_inode (mkquota.c:197) ==1== by 0x11BD9A: main (unix.c:1968) ==1== ==1== Invalid write of size 2 ==1== at 0x484B2C3: memmove (vg_replace_strmem.c:1382) ==1== by 0x487B700: ext2fs_extent_delete (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x488E42B: ext2fs_punch (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x13E890: quota_inode_truncate (quotaio.c:125) ==1== by 0x149781: UnknownInlinedFun (quotaio.c:283) ==1== by 0x149781: quota_file_create (quotaio.c:336) ==1== by 0x14291D: quota_write_inode (mkquota.c:197) ==1== by 0x11BD9A: main (unix.c:1968) ==1== Address 0x4b634c0 is 0 bytes after a block of size 1,024 alloc'd ==1== at 0x484186F: malloc (vg_replace_malloc.c:381) ==1== by 0x48833EC: ext2fs_get_mem (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x487AFE6: ext2fs_extent_get (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x487B19C: ext2fs_extent_goto2 (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x488E1AC: ext2fs_punch (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x13E890: quota_inode_truncate (quotaio.c:125) ==1== by 0x149781: UnknownInlinedFun (quotaio.c:283) ==1== by 0x149781: quota_file_create (quotaio.c:336) ==1== by 0x14291D: quota_write_inode (mkquota.c:197) ==1== by 0x11BD9A: main (unix.c:1968) ==1== Signal (11) SIGSEGV si_code=SEGV_ACCERR fault addr=0x4f28000 valgrind: m_mallocfree.c:278 (mk_plain_bszB): Assertion 'bszB != 0' failed. valgrind: This is probably caused by your program erroneously writing past the end of a heap block and corrupting heap metadata. If you fix any invalid writes reported by Memcheck, this assertion failure will probably go away. Please try that before reporting this as a bug. host stacktrace: ==1== at 0x580428CA: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux) ==1== by 0x580429F7: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux) ==1== by 0x58042B9B: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux) ==1== by 0x5804CD6C: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux) ==1== by 0x5800500C: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux) ==1== by 0x580051F1: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux) ==1== by 0x5809BA6C: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux) ==1== by 0x580E41B0: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux) sched status: running_tid=1 Thread 1: status = VgTs_Runnable (lwpid 1) ==1== at 0x484186F: malloc (vg_replace_malloc.c:381) ==1== by 0x402213F: malloc (rtld-malloc.h:56) ==1== by 0x402213F: strdup (strdup.c:42) ==1== by 0x4019037: _dl_load_cache_lookup (dl-cache.c:517) ==1== by 0x4009FB2: _dl_map_object (dl-load.c:2208) ==1== by 0x4014DEB: dl_open_worker_begin (dl-open.c:533) ==1== by 0x4A75667: _dl_catch_exception (in /usr/lib64/libc.so.6) ==1== by 0x4014569: dl_open_worker (dl-open.c:795) ==1== by 0x4A75667: _dl_catch_exception (in /usr/lib64/libc.so.6) ==1== by 0x401495E: _dl_open (dl-open.c:896) ==1== by 0x4A74AB0: do_dlopen (in /usr/lib64/libc.so.6) ==1== by 0x4A75667: _dl_catch_exception (in /usr/lib64/libc.so.6) ==1== by 0x4A75732: _dl_catch_error (in /usr/lib64/libc.so.6) ==1== by 0x4A74A0F: dlerror_run (in /usr/lib64/libc.so.6) ==1== by 0x4A74BC9: __libc_dlopen_mode (in /usr/lib64/libc.so.6) ==1== by 0x4A2C560: __libc_unwind_link_get (in /usr/lib64/libc.so.6) ==1== by 0x4A397B6: backtrace (in /usr/lib64/libc.so.6) ==1== by 0x139E80: die_signal_handler (sigcatcher.c:379) ==1== by 0x495D75F: ??? (in /usr/lib64/libc.so.6) ==1== by 0x484B2CE: memmove (vg_replace_strmem.c:1382) ==1== by 0x487B700: ext2fs_extent_delete (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x488E42B: ext2fs_punch (in /usr/lib64/libext2fs.so.2.4) ==1== by 0x13E890: quota_inode_truncate (quotaio.c:125) ==1== by 0x149781: UnknownInlinedFun (quotaio.c:283) ==1== by 0x149781: quota_file_create (quotaio.c:336) ==1== by 0x14291D: quota_write_inode (mkquota.c:197) ==1== by 0x11BD9A: main (unix.c:1968) client stack range: [0x1FFEFFC000 0x1FFF000FFF] client SP: 0x1FFEFFEA60 valgrind stack range: [0x1002C8E000 0x1002D8DFFF] top usage: 8656 of 1048576 # apt show e2fsprogs Package: e2fsprogs Version: 1.45.5-2ubuntu1 Priority: required Section: admin Origin: Ubuntu Maintainer: Ubuntu Developers <ubuntu-devel-discuss.com> Original-Maintainer: Theodore Y. Ts'o <tytso> Bugs: https://bugs.launchpad.net/ubuntu/+filebug Installed-Size: 1527 kB Pre-Depends: libblkid1 (>= 2.17.2), libc6 (>= 2.14), libcom-err2 (>= 1.43.9), libext2fs2 (= 1.45.5-2ubuntu1), libss2 (>= 1.38), libuuid1 (>= 2.16) Depends: logsave Recommends: e2fsprogs-l10n Suggests: gpart, parted, fuse2fs, e2fsck-static Homepage: http://e2fsprogs.sourceforge.net Task: minimal, ubuntu-core Important: yes Download-Size: 527 kB APT-Manual-Installed: yes APT-Sources: http://archive.ubuntu.com/ubuntu focal/main amd64 Packages Description: ext2/ext3/ext4 file system utilities # valgrind ubuntu [+] Running valgrind e2fsck -p -f /testcase ==1== Memcheck, a memory error detector ==1== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==1== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info ==1== Command: e2fsck -p -f /testcase ==1== /testcase: Directory inode 2 has extent marked uninitialized at block 0. FIXED. /testcase: Directory inode 2 has extent marked uninitialized at block 1. FIXED. /testcase: Directory inode 2 has extent marked uninitialized at block 2. FIXED. /testcase: Inode 2 extent tree (at level 1) could be shorter. IGNORED. /testcase: Inode 3 extent tree (at level 2) could be narrower. IGNORED. /testcase: Inode 4 extent tree (at level 1) could be narrower. IGNORED. /testcase: Directory inode 11 has extent marked uninitialized at block 0. FIXED. /testcase: Directory inode 11 has extent marked uninitialized at block 1. FIXED. /testcase: Directory inode 11 has extent marked uninitialized at block 2. FIXED. /testcase: Directory inode 11 has extent marked uninitialized at block 4. FIXED. /testcase: Directory inode 11 has extent marked uninitialized at block 5. FIXED. /testcase: Inode 11 extent tree (at level 1) could be shorter. IGNORED. /testcase: Inode 11, i_size is 1191192576, should be 10240. FIXED. /testcase: Inode 2 extent tree (at level 1) could be shorter. IGNORED. [ERROR] ../../../../lib/support/quotaio_v2.c:198:v2_init_io: Quota inode 3 corrupted: file size 67382272; dqi_blocks 536870924 [ERROR] ../../../../lib/support/quotaio.c:256:quota_file_open: qh_ops->init_io failed /testcase: Update quota info for quota type 0. ==1== Invalid read of size 2 ==1== at 0x4842B3F: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==1== by 0x486E370: ext2fs_extent_delete (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x487F21D: ext2fs_punch (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x141947: quota_inode_truncate (quotaio.c:125) ==1== by 0x141A71: quota_inode_init_new (quotaio.c:283) ==1== by 0x141A71: quota_file_create (quotaio.c:336) ==1== by 0x13E717: quota_write_inode (mkquota.c:197) ==1== by 0x11BCC9: main (unix.c:1954) ==1== Address 0x4b70c50 is 0 bytes after a block of size 1,024 alloc'd ==1== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==1== by 0x486DF2E: ext2fs_extent_get (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x486E0FC: ext2fs_extent_goto2 (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x487EFAC: ext2fs_punch (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x141947: quota_inode_truncate (quotaio.c:125) ==1== by 0x141A71: quota_inode_init_new (quotaio.c:283) ==1== by 0x141A71: quota_file_create (quotaio.c:336) ==1== by 0x13E717: quota_write_inode (mkquota.c:197) ==1== by 0x11BCC9: main (unix.c:1954) ==1== ==1== Invalid read of size 2 ==1== at 0x4842B30: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==1== by 0x486E370: ext2fs_extent_delete (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x487F21D: ext2fs_punch (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x141947: quota_inode_truncate (quotaio.c:125) ==1== by 0x141A71: quota_inode_init_new (quotaio.c:283) ==1== by 0x141A71: quota_file_create (quotaio.c:336) ==1== by 0x13E717: quota_write_inode (mkquota.c:197) ==1== by 0x11BCC9: main (unix.c:1954) ==1== Address 0x4b70c52 is 2 bytes after a block of size 1,024 alloc'd ==1== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==1== by 0x486DF2E: ext2fs_extent_get (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x486E0FC: ext2fs_extent_goto2 (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x487EFAC: ext2fs_punch (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x141947: quota_inode_truncate (quotaio.c:125) ==1== by 0x141A71: quota_inode_init_new (quotaio.c:283) ==1== by 0x141A71: quota_file_create (quotaio.c:336) ==1== by 0x13E717: quota_write_inode (mkquota.c:197) ==1== by 0x11BCC9: main (unix.c:1954) ==1== ==1== Invalid write of size 2 ==1== at 0x4842B33: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==1== by 0x486E370: ext2fs_extent_delete (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x487F21D: ext2fs_punch (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x141947: quota_inode_truncate (quotaio.c:125) ==1== by 0x141A71: quota_inode_init_new (quotaio.c:283) ==1== by 0x141A71: quota_file_create (quotaio.c:336) ==1== by 0x13E717: quota_write_inode (mkquota.c:197) ==1== by 0x11BCC9: main (unix.c:1954) ==1== Address 0x4b70c50 is 0 bytes after a block of size 1,024 alloc'd ==1== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==1== by 0x486DF2E: ext2fs_extent_get (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x486E0FC: ext2fs_extent_goto2 (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x487EFAC: ext2fs_punch (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x141947: quota_inode_truncate (quotaio.c:125) ==1== by 0x141A71: quota_inode_init_new (quotaio.c:283) ==1== by 0x141A71: quota_file_create (quotaio.c:336) ==1== by 0x13E717: quota_write_inode (mkquota.c:197) ==1== by 0x11BCC9: main (unix.c:1954) ==1== Signal (11) SIGSEGV si_code=SEGV_MAPERR fault addr=0x4f3f000 valgrind: m_mallocfree.c:280 (mk_plain_bszB): Assertion 'bszB != 0' failed. valgrind: This is probably caused by your program erroneously writing past the end of a heap block and corrupting heap metadata. If you fix any invalid writes reported by Memcheck, this assertion failure will probably go away. Please try that before reporting this as a bug. host stacktrace: ==1== at 0x58046FFA: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/memcheck-amd64-linux) ==1== by 0x58047127: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/memcheck-amd64-linux) ==1== by 0x580472CB: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/memcheck-amd64-linux) ==1== by 0x580519A4: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/memcheck-amd64-linux) ==1== by 0x58005BF7: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/memcheck-amd64-linux) ==1== by 0x580A7204: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/memcheck-amd64-linux) ==1== by 0x580F5FD4: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/memcheck-amd64-linux) sched status: running_tid=1 Thread 1: status = VgTs_Runnable (lwpid 1) ==1== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==1== by 0x401F5CE: strdup (strdup.c:42) ==1== by 0x4019A81: _dl_load_cache_lookup (dl-cache.c:338) ==1== by 0x400A989: _dl_map_object (dl-load.c:2102) ==1== by 0x4015D36: dl_open_worker (dl-open.c:513) ==1== by 0x4A87837: _dl_catch_exception (dl-error-skeleton.c:208) ==1== by 0x40155F9: _dl_open (dl-open.c:837) ==1== by 0x4A867E0: do_dlopen (dl-libc.c:96) ==1== by 0x4A87837: _dl_catch_exception (dl-error-skeleton.c:208) ==1== by 0x4A87902: _dl_catch_error (dl-error-skeleton.c:227) ==1== by 0x4A86914: dlerror_run (dl-libc.c:46) ==1== by 0x4A86914: __libc_dlopen_mode (dl-libc.c:195) ==1== by 0x4A53FE8: init (backtrace.c:54) ==1== by 0x4B2A47E: __pthread_once_slow (pthread_once.c:116) ==1== by 0x4A54133: backtrace (backtrace.c:111) ==1== by 0x13CC20: die_signal_handler (sigcatcher.c:379) ==1== by 0x496A0BF: ??? (in /usr/lib/x86_64-linux-gnu/libc-2.31.so) ==1== by 0x4842B3E: memmove (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==1== by 0x486E370: ext2fs_extent_delete (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x487F21D: ext2fs_punch (in /usr/lib/x86_64-linux-gnu/libext2fs.so.2.4) ==1== by 0x141947: quota_inode_truncate (quotaio.c:125) ==1== by 0x141A71: quota_inode_init_new (quotaio.c:283) ==1== by 0x141A71: quota_file_create (quotaio.c:336) ==1== by 0x13E717: quota_write_inode (mkquota.c:197) ==1== by 0x11BCC9: main (unix.c:1954) client stack range: [0x1FFEFFC000 0x1FFF000FFF] client SP: 0x1FFEFFEAF0 valgrind stack range: [0x1002CB6000 0x1002DB5FFF] top usage: 9480 of 1048576
Hi, Thank you for reporting this issue. I was able to reproduce your report and I have a couple of questions before proceeding. > an out-of-bounds write is triggered and causes a segmentation fault (SIGSEGV). > > This bug allows an attacker to perform a denial of service and possibly opens up > other attack vectors. How did you generate the attached image file? What are the other attacker vectors besides DoS? The issue seems to occur in ext2fs_extent_delete() in lib/ext2fs/extent.c when handle->path[handle->level].left is equal to -1, leading to the 'if (path->left)' statement evaluates to true and then the call to memmove() with invalid arguments, resulting in the out-of-bounds read/write. I'm not an expert on ext filesystems and is not clear if the out-of-bounds read/write is limited to 2 bytes and can be controlled by the attacker through the crafted image file. Hi @Lukas, your input is appreciate. Adding needinfo for awareness. Thanks in advance.
Hey, Thanks for the reply! This image file was generated via fuzzer, which is not public yet, that I am currently developing as part of my research. An attack might plug a malicious USB stick into a fully encrypted Linux computer that automatically runs fsck on drives that are marked as dirty. In case this bug is exploitable, it might be used to get arbitrary code execution in the aforementioned case. Unfortunately, I don't have enough time to build a PoC, and I believe it is best to expect bugs to be exploitable as long nobody proves the opposite. Regards, Nils
BTW: Is there any way to grant me the privilege to edit my posts?
Indeed this is a bug and should be fixed. But as always when fuzzer images pop up, I don't consider it a security issue as it requires a physical access and an elaborate, non standard and not very smart setup to automatically run fsck on inserted USB.
(In reply to Lukáš Czerner from comment #4) > Indeed this is a bug and should be fixed. But as always when fuzzer images > pop up, I don't consider it a security issue as it requires a physical > access and an elaborate, non standard and not very smart setup to > automatically run fsck on inserted USB. Hi Lukas, thank you for your input on this. Although that is an attack scenario, that is not the only one. An attacker can corrupt a filesystem or prepare, distribute and force an user to run e2fsck on a crafted filesystem image. Given the conditions to trigger this vulnerability, it has at most a moderate severity. Thanks.
Hi, The CVE-2022-1304 has been assigned for this issue. You can find more information and updates in the links below: https://access.redhat.com/security/cve/CVE-2022-1304 https://bugzilla.redhat.com/show_bug.cgi?id=2069726 Thanks.
(In reply to Guilherme de Almeida Suckevicz from comment #5) > (In reply to Lukáš Czerner from comment #4) > > Indeed this is a bug and should be fixed. But as always when fuzzer images > > pop up, I don't consider it a security issue as it requires a physical > > access and an elaborate, non standard and not very smart setup to > > automatically run fsck on inserted USB. > > Hi Lukas, thank you for your input on this. > > Although that is an attack scenario, that is not the only one. An attacker > can corrupt a filesystem or prepare, distribute and force an user to run > e2fsck a crafted filesystem image. > > Given the conditions to trigger this vulnerability, it has at most a > moderate severity. > > Thanks. Sure, it does not change anything about what I've said. I consider it a regular low priority bug. I've seen plenty of fuzzer bugs, they are always just regular bugs. -Lukas
This issue is public and has a CVE. Is there a patch? Has it been reported upstream?
(In reply to John Helmert III from comment #8) > This issue is public and has a CVE. Is there a patch? Has it been reported > upstream? I can report it upstream, if you can tell me where this is? Actually, it is really hard to find the right place to report this issue.
(In reply to Nils Bars from comment #9) > I can report it upstream, if you can tell me where this is? Actually, it is > really hard to find the right place to report this issue. I agree it's a bit hard to find, but this seems right: https://sourceforge.net/p/e2fsprogs/bugs/ I would also like to note that reporting to upstream should already be a part of the CVE assignment process, according to the MITRE's CNA rules [1]: "2.1.2 If a CVE ID is being assigned to a vulnerability, the CNA MUST make a reasonable effort to notify the maintainer of the code in which that vulnerability exists." [1] https://www.cve.org/ResourcesSupport/AllResources/CNARules#section_2-1_cve_id_management_rules
This is a bug tracker I already found. Unfortunately, it seems not to be the right one, since the most recent *closed* ticket is from 2012.
I apologize. From upstream's README: In case of bugs in these programs, please contact Ted Ts'o at tytso or tytso.edu. See the e2fsck man page for suggestions of what sort of information to include when submitting bug reports for these programs. https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/tree/README#n15
I dropped them a mail, thanks.
e2fsprogs development happens on linux-ext4.org mailing list so you might as well send the report there. Also I've had a stab at it and I think I've figured out an easy way to fix this particular issue. I sent it to the list already. However it may also require some more fixing, because I'd expect e2fsck to be able to spot and fix this extent tree corruption even before we try to use the extent tree. Also even with the fix e2fsck is unable to fix the file system completely on the first try. For some reason the quota files remain corrupted afterwards and will get fixed only on a second pass. I'll try to see what can be done about that. -Lukas
Here is the upstream fix: https://lore.kernel.org/linux-ext4/20220421173148.20193-1-lczerner@redhat.com/T/#u
Note: the CVE Severity Score reported in [1] is bogus, since it claims that the attack vector is "network", which is clearly not correct. This is at best attack vector "physical", which would significantly lower the CVE severity score. [1] https://access.redhat.com/security/cve/CVE-2022-1304
You are certainly right about the attack vector. However, I am wondering whether this is the same issue you addressed in "e2fsck: avoid out-of-bounds write for very deep extent trees" (https://lore.kernel.org/all/20220607042444.1798015-6-tytso@mit.edu/T/), since I reported this issue already some time ago, and it was already addressed in https://lore.kernel.org/linux-ext4/20220421173148.20193-1-lczerner@redhat.com/T/#u.
(In reply to Theodore Tso from comment #16) > Note: the CVE Severity Score reported in [1] is bogus, since it claims that > the attack vector is "network", which is clearly not correct. This is at > best attack vector "physical", which would significantly lower the CVE > severity score. > > [1] https://access.redhat.com/security/cve/CVE-2022-1304 I set the attack vector to network because the vulnerable code is in lib/ext2fs/extent.c which is shipped via the e2fsprogs-libs package via the libext2fs.so library. This package is used by other tools and I assumed the worst case scenario where this vulnerability could be exploited over the network. Although "physical" is an attack scenario, that is not the only one. An attacker can corrupt a filesystem or prepare, distribute and force an user to run e2fsck on a crafted filesystem image, triggering this vulnerability. Therefore, I'm setting attack vector to local. Note that attack complexity is already set to high because of the above. Thanks.
In reply to Guilherme from Comment #18: Unless you demonstrate how someone who doesn't have a local account on the system, can "force" or trick some tool to open a file system image, and then access an inode's extent tree, I don't think it's a correct interpretation of the CVSS. By that interpretation *any* bug in a shared library would be considered as having an attack vector of network, and that's not right. The attack vector network is for cases where you have a program listening on a TCP/IP port, and you can inject malicious data via that network vector. So what network application, precisely, links with libext2fs.so, and will accept a file system image and then operate on it? By your theory of local, an attacker could also "force" a user to run /bin/bash on a shell script, which could also cause all manner of mischief. Should that be considered a vulnerability? But whatever, I consider a lot of the CVE SS games to be a bit silly, and mostly about inflating the egos or reputation of security researchers.
In reply to Nils in comment #17: > However, I am wondering whether this is the same issue you addressed in > "e2fsck: avoid out-of-bounds write for very deep extent trees" > (https://lore.kernel.org/all/20220607042444.1798015-6-tytso@mit.edu/T/), > since I reported this issue already some time ago, and it was already > addressed in https://lore.kernel.org/linux-ext4/20220421173148.20193-1-lczerner@redhat.com/T/#u. I had already applied Lukas's fix in my upstream repository. With that fix applied, test case #5 in the set of fuzzed test cases that Moritz, Nico, and you had sent to me on May 25th was still failing, and it was this fuzzed file system image which commit 8d66e7e93160 ("e2fsck: avoid out-of-bounds write for very deep extent trees") was designed to address. Specifically, that test case had an extent tree which had the tree depth set to 2049 in the extent header, and where the extent tree had a cyclic loop (the index block located at block #7 had a pointer to itself). Commit 2d30ab20ae4e ("libext2fs: check for cyclic loops in the extent tree") will cause the library function to error out early. Without that commit, but with commit 8d66e7e93160 applied, e2fsck will descend the tree 2048 times before treating the index block as a leaf block, and then offering to clear the extent tree. Commit 2d30ab20ae4e is essentially a defense-in-depth measure which makes the library more robust. In any case, in answer to your question, Lukas's patch, which addresses the fuzzed image supplied for this bugzilla report, was for an entirely different case compared to the patch series which I posted last night.
This message is a reminder that Fedora Linux 35 is nearing its end of life. Fedora will stop maintaining and issuing updates for Fedora Linux 35 on 2022-12-13. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as EOL if it remains open with a 'version' of '35'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, change the 'version' to a later Fedora Linux version. Thank you for reporting this issue and we are sorry that we were not able to fix it before Fedora Linux 35 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora Linux, you are encouraged to change the 'version' to a later version prior to this bug being closed.
Fedora Linux 35 entered end-of-life (EOL) status on 2022-12-13. Fedora Linux 35 is no longer maintained, which means that it will not receive any further security or bug fix updates. As a result we are closing this bug. If you can reproduce this bug against a currently maintained version of Fedora Linux please feel free to reopen this bug against that version. Note that the version field may be hidden. Click the "Show advanced fields" button if you do not see the version field. If you are unable to reopen this bug, please file a new report against an active release. Thank you for reporting this bug and we are sorry it could not be fixed.