[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.