[PATCH v5 2/3] scsi: target: Clear all control read scatterlist entries

From: Yong Liu

Date: Fri Nov 13 2026 - 05:33:27 EST


__target_submit() only clears the first scatterlist entry of a control
read buffer supplied by a fabric driver. Control CDB handlers can leave
response bytes untouched, so later entries can retain stale kernel data
that is returned to the initiator.

Clear every supplied scatterlist entry before command execution. Use
sg_zero_buffer() so entries spanning multiple pages are handled as well.
Keep clearing the full entries, including any part beyond data_length,
as the existing code does for the first entry.

Fixes: 944981c7e106 ("target: Add control CDB READ payload zero work-around")
Cc: stable@xxxxxxxxxxxxxxx
Suggested-by: Bart Van Assche <bvanassche@xxxxxxx>
Signed-off-by: Yong Liu <pkfxxxing@xxxxxxxxx>
---
drivers/target/target_core_transport.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 927861c30a..267f5e2cc8 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1633,23 +1633,16 @@ static int __target_submit(struct se_cmd *cmd)
core_alua_check_nonop_delay(cmd);

if (cmd->t_data_nents != 0) {
- /*
- * This is primarily a hack for udev and tcm loop which sends
- * INQUIRYs with a single page and expects the data to be
- * cleared.
- */
+ /* Control CDB handlers may leave response bytes untouched. */
if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) &&
cmd->data_direction == DMA_FROM_DEVICE) {
- struct scatterlist *sgl = cmd->t_data_sg;
- unsigned char *buf = NULL;
+ struct scatterlist *sg;
+ unsigned int i;

- BUG_ON(!sgl);
+ BUG_ON(!cmd->t_data_sg);

- buf = kmap_local_page(sg_page(sgl));
- if (buf) {
- memset(buf + sgl->offset, 0, sgl->length);
- kunmap_local(buf);
- }
+ for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i)
+ sg_zero_buffer(sg, 1, sg->length, 0);
}
}

--
2.43.0