Created attachment 233761 [details] a disk image that causes a page fault in the FFS taste crc32 code If you attach a disk containing garbage that looks enough like an FFS file system with fs_sbsize=0xffffffff, the taste code calls calculate_crc32c() with a huge length that causes a kernel page fault. readsuper()'s sanity-check says if(... && fs->fs_sbsize <= SBLOCKSIZE fs_sbsize is signed int32, so 0xffffffff looks OK. But the crc32 code treats the length as an unsigned, causing it to read off the end of the block buffer. I've included a demo: # mdconfig -f taste5a.img panic: vm_fault_lookup: fault on nofault entry, addr: 0xffffffc047800000 cpuid = 0 time = 1651438166 KDB: stack backtrace: db_trace_self() at db_trace_self db_trace_self_wrapper() at db_trace_self_wrapper+0x38 kdb_backtrace() at kdb_backtrace+0x2c vpanic() at vpanic+0x16e panic() at panic+0x2a vm_fault_lookup() at vm_fault_lookup+0x1bc vm_fault() at vm_fault+0x9e vm_fault_trap() at vm_fault_trap+0x68 page_fault_handler() at page_fault_handler+0x13c do_trap_supervisor() at do_trap_supervisor+0x76 cpu_exception_handler_supervisor() at cpu_exception_handler_supervisor+0x70 --- exception 13, tval = 0xffffffc047800000 crc32c_sb8_64_bit() at crc32c_sb8_64_bit+0xcc multitable_crc32c() at multitable_crc32c+0x18 table_crc32c() at table_crc32c+0x22 calculate_crc32c() at calculate_crc32c+0xc ffs_calc_sbhash() at ffs_calc_sbhash+0x28 readsuper() at readsuper+0xe2 ffs_sbget() at ffs_sbget+0xc8 g_label_ufs_taste_common() at g_label_ufs_taste_common+0x6c g_label_ufs_id_taste() at g_label_ufs_id_taste+0xe g_label_taste() at g_label_taste+0x198 g_new_provider_event() at g_new_provider_event+0xb8 one_event() at one_event+0x106 g_run_events() at g_run_events+0x8a g_event_procbody() at g_event_procbody+0x56 fork_exit() at fork_exit+0x80 fork_trampoline() at fork_trampoline+0xa KDB: enter: panic [ thread pid 13 tid 100017 ] Stopped at breakpoint+0xa: c.ldsp s0,0(sp) db>
This appears to be a dupe of (or another case of) bug 244342
Please check to see if my proposed change in https://reviews.freebsd.org/D35219 resolves this bug.
(In reply to Kirk McKusick from comment #2) validate_sblock() ought to check that fs_sbsize is >= 0; without that, it's still possible to force a crash in the crc32 code.
(In reply to Robert Morris from comment #3) Right. The lower bound test should be fs->fs_sbsize < fs->fs_fsize since a zero-length superblock size would be wrong. I am working on some other feedback about problems that the checks cause. I will do an update to the patch when I have figured them out. Thanks for your help in identifying and fixing these vulnerabilities.
(In reply to Kirk McKusick from comment #4) Can you verify that my patch of May 21 fixes this problem?
(In reply to Kirk McKusick from comment #5) Yes -- your patch of May 21 makes this problem go away for me.
Fixed by https://reviews.freebsd.org/D35219 Will close when MFC'ed to 13.
MFC'ed to 13 with commit b999366aab4e2d59cb8869b0e5ef0f70ab9b9bbe on Fri May 27 12:21:11 2022 -0700