mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
vhost-scsi: do not count PI bytes in the data length
vhost_scsi_handle_vq() moves pi_bytesout or pi_bytesin into the
protection sgl and subtracts those bytes from exp_data_len. The length
passed to TCM is still exp_data_len + prot_bytes.
prot_bytes comes from virtio_scsi_cmd_req_pi. With
VIRTIO_SCSI_F_T10_PI negotiated, vhost reads that header and does not
check that the CDB is a READ or WRITE. sbc_check_prot() replaces
data_length from the CDB only when the protect field is non-zero.
target_cmd_size_check() leaves a write's data_length unchanged when the
CDB size is smaller, so a command that does not get that replacement
keeps a data_length larger than the data sgl.
The KASAN report is a MODE SELECT whose header had pi_bytesout set.
The data sgl held only the parameter list. spc_emulate_modeselect()
walked data_length and read the next physical page.
Pass the data sgl length. Protected READ and WRITE still take their
length from the CDB in sbc_check_prot().
KASAN reports:
BUG: KASAN: use-after-free in spc_emulate_modeselect+0x145/0x380 [target_core_mod]
Read of size 1
spc_emulate_modeselect
__target_execute_cmd
target_execute_cmd
vhost_scsi_write_pending
transport_generic_new_cmd
__target_submit
target_queued_submit_work
process_one_work
worker_thread
kthread
ret_from_fork
ret_from_fork_asm
Fixes: 9f977ef7b6 ("vhost-scsi: Include prot_bytes into expected data transfer length")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261012103954.136698-1-physicalmtea@gmail.com>
This commit is contained in:
parent
f41f153d49
commit
1f5bc40e33
|
|
@ -1546,9 +1546,17 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
|
|||
* vhost_scsi_queue_data_in() and vhost_scsi_queue_status()
|
||||
*/
|
||||
cmd->tvc_vq_desc = vc.head;
|
||||
/*
|
||||
* vhost_scsi_mapal() maps the PI bytes into cmd->prot_table.
|
||||
* It maps the remaining exp_data_len bytes into cmd->table,
|
||||
* which is the data SGL passed to the target core. Its
|
||||
* expected length must therefore exclude prot_bytes.
|
||||
*
|
||||
* sbc_check_prot() derives the data length for protected READ
|
||||
* and WRITE commands from the CDB.
|
||||
*/
|
||||
vhost_scsi_target_queue_cmd(nexus, cmd, cdb, lun, task_attr,
|
||||
data_direction,
|
||||
exp_data_len + prot_bytes);
|
||||
data_direction, exp_data_len);
|
||||
ret = 0;
|
||||
err:
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user