Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Oct 2021 17:32:56 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 259280] vtblk_maximum_segments can set nsegs too low, allowing panic on some non-aligned raw disk reads
Message-ID:  <bug-259280-227@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D259280

            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 =3D=3D BIO_READ || bp->bio_cmd =3D=3D BIO_WRITE) {
        error =3D sglist_append_bio(sg, bp);
        if (error || sg->sg_nseg =3D=3D sg->sg_maxseg) {=20=20=20=20=20=20=
=20=20=20=20=20=20
            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 =3D open("/dev/vtbd0", 0);
  char buf1[4*4096];
  char *buf =3D buf1;
  while(((unsigned long)buf) % 4096) buf++;
  read(fd, buf + 0xd00, 4096);
}

panic: vtblk_request_execute: bio 0xffffffd0019ded38 data buffer too big 0
cpuid =3D 0
time =3D 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 ]

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-259280-227>