freenode
Kernel & Low-Level

Linux SCSI target fixes eight SG overruns hit via vhost-scsi

Guest commands through page-per-entry virtqueue layouts could push host target code past scatterlist bounds into adjacent memory.

Eight fixes landed for the Linux SCSI target core after it was found reading and writing past scatter-gather entry bounds, with KASAN flagging slab use-after-free paths when the bad accesses landed on neighboring pages.

The faults surface most clearly through vhost-scsi. That fabric maps each descriptor inside a single page, so a field that straddles an entry edge is not still inside the command buffer: the next bytes belong to the next physical page. Guests submit the commands over a virtqueue, so a virtual machine can drive the host into those walks.

The broken cases span ordinary command handling and T10 DIF software paths. COMPARE AND WRITE built the write half by extending the first data entry’s offset across the compare length, which loses the true write entries when the halves split across pages. REPORT REFERRALS wrote eight-byte LBAs after a length check that only guaranteed one remaining byte. SET TARGET PORT GROUPS accepted parameter lists that were not a multiple of four and then read a full descriptor past the end. DIF generate and verify copied eight-byte protection tuples and block CRCs without limiting each step to the bytes the current protection or data entry actually held, and escaped application-tag blocks advanced the data cursor as if one entry always covered a full logical block. Passthrough mode sense and mode select touched fixed header and block-descriptor bytes without walking a short multi-entry buffer.

Jia Jia’s series keeps those stores and loads inside the real sg lists: write halves are taken from the entries that hold them, multi-byte fields are clipped or rejected when the buffer ends mid-field, DIF tuples and CRCs cross entries explicitly, and short mode buffers are left alone. For hosts that export LIO targets to guests over vhost-scsi, the practical result is that malformed or awkwardly fragmented command and protection buffers no longer poke host memory the target never owned.