Bug 259107 - A damaged ext2 superblock can cause a panic due to a recursive bread().
Summary: A damaged ext2 superblock can cause a panic due to a recursive bread().
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: Neel Chauhan
URL: https://reviews.freebsd.org/D33029
Keywords:
Depends on:
Blocks:
 
Reported: 2021-10-12 16:21 UTC by Robert Morris
Modified: 2021-12-04 22:35 UTC (History)
3 users (show)

See Also:


Attachments
A damaged ext3 disk image that causes a recursive bread lock attempt. (1.49 KB, application/x-gzip)
2021-10-12 16:21 UTC, Robert Morris
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Morris 2021-10-12 16:21:48 UTC
Created attachment 228630 [details]
A damaged ext3 disk image that causes a recursive bread lock attempt.

If a damaged ext2 file system has its e2fs_first_dblock superblock
field set to zero instead of 1, ext2_compute_sb_data() will attempt
to bread() block 1 even though ext2_mount() already has that disk
block locked. The panic could be avoided if ext2_compute_sb_data()
had another sanity check on e2fs_first_dblock.

I've attached a demo disk image:

# gunzip ext39.img.gz
# mdconfig -f ext39.img
# mount -t ext2fs -o ro /dev/md0 /mnt
panic: lockmgr_xlock_hard: recursing on non recursive lockmgr 0xfffffe00086efc78 @ /usr/src/sys/kern/vfs_bio.c:3962
panic() at panic+0x43/frame 0xfffffe009bb522c0
lockmgr_xlock_hard() at lockmgr_xlock_hard+0xee/frame 0xfffffe009bb52370
__lockmgr_args() at __lockmgr_args+0x1f9/frame 0xfffffe009bb52410
getblkx() at getblkx+0x195/frame 0xfffffe009bb524d0
breadn_flags() at breadn_flags+0x44/frame 0xfffffe009bb52540
ext2_compute_sb_data() at ext2_compute_sb_data+0x80d/frame 0xfffffe009bb525d0
ext2_mount() at ext2_mount+0xea9/frame 0xfffffe009bb52770
vfs_domount() at vfs_domount+0x8d8/frame 0xfffffe009bb529e0
vfs_donmount() at vfs_donmount+0x880/frame 0xfffffe009bb52a80
sys_nmount() at sys_nmount+0x69/frame 0xfffffe009bb52ac0
amd64_syscall() at amd64_syscall+0x12e/frame 0xfffffe009bb52bf0
fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe009bb52bf0
Comment 1 commit-hook freebsd_committer freebsd_triage 2021-11-29 17:54:41 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=3dd3a395ba975d0fbe13320e6e69fb85b037da5e

commit 3dd3a395ba975d0fbe13320e6e69fb85b037da5e
Author:     Neel Chauhan <nc@FreeBSD.org>
AuthorDate: 2021-11-16 22:59:26 +0000
Commit:     Neel Chauhan <nc@FreeBSD.org>
CommitDate: 2021-11-29 17:53:45 +0000

    ext2: Check for e2fs_first_dblock in ext2_compute_sb_data()

    This prevents a kernel panic on a damaged ext2 superblock.

    PR:                     259107
    Reported by:            Robert Morris <rtm@lcs.mit.edu>
    Differential Revision:  https://reviews.freebsd.org/D33029

 sys/fs/ext2fs/ext2_vfsops.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
Comment 2 Neel Chauhan freebsd_committer freebsd_triage 2021-11-29 17:55:46 UTC
Committed!

Also to other committers: Sorry if I forgot the "MFC After:" or "Reviewed by:" tags.
Comment 3 commit-hook freebsd_committer freebsd_triage 2021-12-04 22:35:12 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=c0e1884b11c0f86cd7bec28b03b9d6a3a4a45c3b

commit c0e1884b11c0f86cd7bec28b03b9d6a3a4a45c3b
Author:     Neel Chauhan <nc@FreeBSD.org>
AuthorDate: 2021-11-16 22:59:26 +0000
Commit:     Neel Chauhan <nc@FreeBSD.org>
CommitDate: 2021-12-04 22:34:20 +0000

    ext2: Check for e2fs_first_dblock in ext2_compute_sb_data()

    This prevents a kernel panic on a damaged ext2 superblock.

    PR:                     259107
    Reported by:            Robert Morris <rtm@lcs.mit.edu>
    Differential Revision:  https://reviews.freebsd.org/D33029

    (cherry picked from commit 3dd3a395ba975d0fbe13320e6e69fb85b037da5e)

 sys/fs/ext2fs/ext2_vfsops.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)