mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-28 12:53:14 +01:00
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: bca939d5bc ("vhost-scsi: Dynamically allocate scatterlists")
Suggested-by: Jia Jia <[email protected]>
Signed-off-by: Jia Jia <[email protected]>
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <[email protected]>
Message-ID: <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
This commit is contained in:
1 parent
727e1f5698
commit
d876c493fc
1 file changed
+8
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user