[Bug 259280] vtblk_maximum_segments can set nsegs too low, allowing panic on some non-aligned raw disk reads
Date: Tue, 19 Oct 2021 17:32:56 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=259280 Bug ID: 259280 Summary: vtblk_maximum_segments can set nsegs too low, allowing panic on some non-aligned raw disk reads Product: Base System Version: CURRENT Hardware: Any OS: Any Status: New Severity: Affects Only Me Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: rtm@lcs.mit.edu The virtio block device code's vtblk_maximum_segments() sets nsegs to 3 if the device doesn't have VIRTIO_BLK_F_SEG_MAX set. However, a 4096-byte read() to a non-page-aligned memory address can then panic in vtblk_request_execute() due to using up all the segments, in this code: if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) { error = sglist_append_bio(sg, bp); if (error || sg->sg_nseg == sg->sg_maxseg) { panic("%s: bio %p data buffer too big %d", __func__, bp, error); sg_nseg and sg_maxseg both end up as three, triggering the panic. I actually got this panic, on the tinyemu RISC-V simulator, running e2fsck on a broken ext2 file system. Here's a program that panics on tinyemu (but not qemu, which sets VIRTIO_BLK_F_SEG_MAX): int main() { int fd = open("/dev/vtbd0", 0); char buf1[4*4096]; char *buf = buf1; while(((unsigned long)buf) % 4096) buf++; read(fd, buf + 0xd00, 4096); } panic: vtblk_request_execute: bio 0xffffffd0019ded38 data buffer too big 0 cpuid = 0 time = 1634664503 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+0x148 panic() at panic+0x2a vtblk_request_execute() at vtblk_request_execute+0x23a vtblk_startio() at vtblk_startio+0x198 vtblk_strategy() at vtblk_strategy+0x66 g_disk_start() at g_disk_start+0x2b0 g_io_schedule_down() at g_io_schedule_down+0x32a g_down_procbody() at g_down_procbody+0x58 fork_exit() at fork_exit+0x68 fork_trampoline() at fork_trampoline+0xa KDB: enter: panic [ thread pid 13 tid 100019 ] -- You are receiving this mail because: You are the assignee for the bug.