NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/58338: ld@virtio is confused about size parameters



>Number:         58338
>Category:       kern
>Synopsis:       ld@virtio is confused about size parameters
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 12 16:50:00 +0000 2024
>Originator:     Taylor R Campbell
>Release:        current, 10, 9, ...
>Organization:
The VirtBlkD Foundation
>Environment:
>Description:
ld@virtio reads the SIZE_MAX parameter as if it were the maximum size of a _transfer_:

    299 	/* At least genfs_io assumes maxxfer == MAXPHYS. */
    300 	if (features & VIRTIO_BLK_F_SIZE_MAX) {
    301 		maxxfersize = virtio_read_device_config_4(vsc,
    302 		    VIRTIO_BLK_CONFIG_SIZE_MAX);
...
    348 	ld->sc_maxxfer = maxxfersize;

https://nxr.netbsd.org/xref/src/sys/dev/pci/ld_virtio.c?r=1.34#299

But the SIZE_MAX is actually the maximum size of a _single segment_ in a transfer:

 VIRTIO_BLK_F_SIZE_MAX (1)
    Maximum size of any single segment is in size_max. 

https://docs.oasis-open.org/virtio/virtio/v1.3/csd01/virtio-v1.3-csd01.html#x1-3080003

ld@virtio later uses d->sc_maxxfer (i.e., the virtio SIZE_MAX parameter) to chose the total dmamap size, and divides it by NBPG (number of bytes per page) to get a number of segments -- which, for non-aligned inputs, might require adding 2 segments, a magic number which was confused for the number of overhead segments in the virtio transfer for header and status, even though those are passed through a different dmamap (vr_cmdsts):

    222 		r = bus_dmamap_create(virtio_dmat(sc->sc_virtio),
    223 				      ld->sc_maxxfer,
    224 				      (ld->sc_maxxfer / NBPG) +
    225 				      VIRTIO_BLK_CTRL_SEGMENTS,
    226 				      ld->sc_maxxfer,
    227 				      0,
    228 				      BUS_DMA_WAITOK|BUS_DMA_ALLOCNOW,
    229 				      &vr->vr_payload);

https://nxr.netbsd.org/xref/src/sys/dev/pci/ld_virtio.c?r=1.34#222
>How-To-Repeat:
use ld@virtio in a VM with more restrictive SEG_MAX and SIZE_MAX parameters, like firecracker or qemu microvm
>Fix:
Yes, please!



Home | Main Index | Thread Index | Old Index