Bug 2068113 - SIGSEGV and out-of-bounds write during processing file via e2fsck
Summary: SIGSEGV and out-of-bounds write during processing file via e2fsck
Keywords:
Status: CLOSED EOL
Alias: None
Product: Fedora
Classification: Fedora
Component: e2fsprogs
Version: 35
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Lukáš Czerner
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2022-03-24 13:47 UTC by Nils Bars
Modified: 2022-12-13 17:20 UTC (History)
13 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2022-12-13 17:20:06 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
The crashing input alongside a script to automatically reproduce the bug. (9.56 KB, application/zip)
2022-03-24 13:47 UTC, Nils Bars
no flags Details

Description Nils Bars 2022-03-24 13:47:27 UTC
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

Comment 1 Guilherme de Almeida Suckevicz 2022-04-05 17:53:49 UTC
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.

Comment 2 Nils Bars 2022-04-08 06:39:36 UTC
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

Comment 3 Nils Bars 2022-04-08 06:47:30 UTC
BTW: Is there any way to grant me the privilege to edit my posts?

Comment 4 Lukáš Czerner 2022-04-11 08:29:54 UTC
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.

Comment 5 Guilherme de Almeida Suckevicz 2022-04-11 17:05:17 UTC
(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.

Comment 6 Guilherme de Almeida Suckevicz 2022-04-11 17:44:05 UTC
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.

Comment 7 Lukáš Czerner 2022-04-11 18:00:32 UTC
(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

Comment 8 John Helmert III 2022-04-15 00:30:52 UTC
This issue is public and has a CVE. Is there a patch? Has it been reported upstream?

Comment 9 Nils Bars 2022-04-21 08:24:43 UTC
(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.

Comment 10 John Helmert III 2022-04-21 13:42:05 UTC
(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

Comment 11 Nils Bars 2022-04-21 13:49:22 UTC
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.

Comment 12 John Helmert III 2022-04-21 14:21:19 UTC
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

Comment 13 Nils Bars 2022-04-21 14:35:16 UTC
I dropped them a mail, thanks.

Comment 14 Lukáš Czerner 2022-04-21 17:38:01 UTC
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

Comment 15 Nils Bars 2022-04-25 09:17:56 UTC
Here is the upstream fix: https://lore.kernel.org/linux-ext4/20220421173148.20193-1-lczerner@redhat.com/T/#u

Comment 16 Theodore Tso 2022-06-07 04:18:24 UTC
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

Comment 17 Nils Bars 2022-06-07 11:05:57 UTC
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.

Comment 18 Guilherme de Almeida Suckevicz 2022-06-07 13:27:39 UTC
(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.

Comment 19 Theodore Tso 2022-06-07 14:44:24 UTC
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.

Comment 20 Theodore Tso 2022-06-07 15:10:54 UTC
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.

Comment 21 Ben Cotton 2022-11-29 18:38:01 UTC
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.

Comment 22 Ben Cotton 2022-12-13 17:20:06 UTC
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.


Note You need to log in before you can comment on or make changes to this bug.