Created attachment 233866 [details] a disk image that causes a buffer overflow during tasting, due to unexpected FFS superblock content ffs_sbget() allocates fs->fs_cssize bytes to hold fs_csp: size = fs->fs_cssize; ... if ((space = UFS_MALLOC(size, filltype, M_WAITOK)) == NULL) { but it can copy a whole fragment into that space: for (i = 0; i < blks; i += fs->fs_frag) { ...; size = (blks - i) * fs->fs_fsize; ...; error = (*readfunc)(devfd, dbtob(fsbtodb(fs, fs->fs_csaddr + i)), (void **)&buf, size); ...; memcpy(space, buf, size); If fs_cssize is smaller than fs_fsize, the memcpy() can write attacker-supplied bytes beyond the end of space. I've attached a disk image containing garbage that looks enough like FFS for taste to proceed, with fs_cssize = 16 and fs_fsize = 5120. # uname -a FreeBSD 14.0-CURRENT FreeBSD 14.0-CURRENT #224 main-n250919-29f81bc20825-dirty: Thu May 12 04:42:56 EDT 2022 rtm@zika:/usr/obj/usr/rtm/symbsd/src/riscv.riscv64/sys/RTM riscv # mdconfig -f taste6b.img Memory modified after free 0xffffffd000852b40(24) val=ffffffff @ 0xffffffd000852b40 panic: Fatal page fault at 0xffffffc00051b2b0: 0xffffffff00000070 cpuid = 0 time = 1651916658 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 page_fault_handler() at page_fault_handler+0x1aa do_trap_supervisor() at do_trap_supervisor+0x76 cpu_exception_handler_supervisor() at cpu_exception_handler_supervisor+0x70 --- exception 13, tval = 0xffffffff00000070 mtrash_ctor() at mtrash_ctor+0x86 item_ctor() at item_ctor+0xa0 cache_alloc_item() at cache_alloc_item+0x5a uma_zalloc_arg() at uma_zalloc_arg+0x58 uma_zalloc() at uma_zalloc+0x10 malloc() at malloc+0x80 ffs_sbget() at ffs_sbget+0x1e8 g_label_ufs_taste_common() at g_label_ufs_taste_common+0x6c g_label_ufs_volume_taste() at g_label_ufs_volume_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>
Created attachment 233874 [details] Proposed fix for bug 263934 Proposed fix
Thanks for your report. Normally the superblock check hash would detect the corruption, but of course a hacker could update the chcek hash after corrupting the superblock. Let me know if the attached patch solves this problem.
(In reply to Kirk McKusick from comment #2) Yes -- your patch makes the problem go away for me.
(In reply to Robert Morris from comment #3) Thanks for the followup. Based on your other reported superblock corruption bugs, I believe that the correct fix is to put in a more complete set of superblock integrity checks. I will get back to you with that change in the hopes that it will cover all your submitted superblock related corruption reports.
Please check to see if my proposed change in https://reviews.freebsd.org/D35219 resolves this bug. Based on your testing of my first proposed fix, it should.
(In reply to Kirk McKusick from comment #5) Yes -- your validate_sblock() of Apr 12 makes this problem go away.
(In reply to Robert Morris from comment #6) Could you recheck with my updated patch of May 21 to ensure my relaxed checks did not reopen the vulnerability.
(In reply to Kirk McKusick from comment #7) 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