From d876c493fc4b811941bfeb4c80beb2dfc4bf025e Mon Sep 17 00:00:00 2001 From: Linfeng Sun Date: Mon, 27 Jul 2026 16:18:41 +0800 Subject: [PATCH] vhost-scsi: Validate T10 PI scatterlist counts When T10 PI is negotiated, vhost-scsi splits protection bytes from the data iterator before mapping the request scatterlists. A malformed request can claim protection bytes that cover or exceed the full payload length. The former leaves no data bytes to map, while the latter underflows exp_data_len before advancing the iterator. Both cases can let a zero data SGL count reach sg_alloc_table_chained(), which triggers BUG_ON(!nents). Reject protection lengths that cover or exceed the payload before subtracting prot_bytes and advancing the iterator. Also propagate negative errors from the protection SGL calculation before calling the allocator, matching the data SGL path. Fixes: bca939d5bcd0 ("vhost-scsi: Dynamically allocate scatterlists") Suggested-by: Jia Jia Signed-off-by: Jia Jia Assisted-by: OpenAI-Codex:GPT-5 Signed-off-by: Linfeng Sun Message-ID: <20260727081841.923151-1-slf@hdu.edu.cn> Signed-off-by: Michael S. Tsirkin --- drivers/vhost/scsi.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 9a1253b9d8c50..c79197edb1637 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -972,6 +972,9 @@ vhost_scsi_mapal(struct vhost_scsi *vs, struct vhost_scsi_cmd *cmd, if (prot_bytes) { sgl_count = vhost_scsi_calc_sgls(prot_iter, prot_bytes, VHOST_SCSI_PREALLOC_PROT_SGLS); + if (sgl_count < 0) + return sgl_count; + cmd->prot_table.sgl = cmd->prot_sgl; ret = sg_alloc_table_chained(&cmd->prot_table, sgl_count, cmd->prot_table.sgl, @@ -1416,6 +1419,11 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) * actual data payload length. */ if (prot_bytes) { + if (prot_bytes >= exp_data_len) { + vq_err(vq, "Protection data exceeds payload length\n"); + goto err; + } + exp_data_len -= prot_bytes; prot_iter = data_iter; iov_iter_truncate(&prot_iter, prot_bytes); -- 2.47.3