target/iscsi: Fix double free of a TUR followed by a solicited NOPOUT
Subsystems (2)
PATCH 1/1 target/iscsi: Fix double free of a TUR followed by a solicited NOPOUT
From: Alexei Potashnik <[email protected]>
Make sure all non-READ SCSI commands get targ_xfer_tag initialized to 0xffffffff, not just WRITEs.
Double-free of a TUR cmd object occurs under the following scenario:
1. TUR received (targ_xfer_tag is uninitialized and left at 0)
2. TUR status sent
3. First unsolicited NOPIN is sent to initiator (gets targ_xfer_tag of 0)
4. NOPOUT for NOPIN (with TTT=0) arrives
- its ExpStatSN acks TUR status, TUR is queued for removal
- LIO tries to find NOPIN with TTT=0, but finds the same TUR instead, TUR is queued for removal for the 2nd time
--- drivers/target/iscsi/iscsi_target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/target/iscsi/iscsi_target.c +1 -1
@@ -970,7 +970,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;if (hdr->flags &ISCSI_FLAG_CMD_READ ) { cmd->targ_xfer_tag =session_get_next_ttt (conn->sess); - }else if (hdr->flags &ISCSI_FLAG_CMD_WRITE ) + }else cmd->targ_xfer_tag =0xFFFFFFFF ; cmd->cmd_sn =be32_to_cpu (hdr->cmdsn); cmd->exp_stat_sn =be32_to_cpu (hdr->exp_statsn);
Signature · 1 line
2.4.3
Hi Spencer & Alexei,
Quoted 15 lines · Spencer Baugh
From: Alexei Potashnik <[email protected]>
Make sure all non-READ SCSI commands get
targ_xfer_taginitialized to0xffffffff, not just WRITEs.Double-free of a TUR cmd object occurs under the following scenario:
1. TUR received (
targ_xfer_tagis uninitialized and left at 0)
2. TUR status sent
3. First unsolicited NOPIN is sent to initiator (getstarg_xfer_tagof 0)
4. NOPOUT for NOPIN (with TTT=0) arrives
- its ExpStatSN acks TUR status, TUR is queued for removal
- LIO tries to find NOPIN with TTT=0, but finds the same TUR instead, TUR is queued for removal for the 2nd time
Quoted 3 lines
Signed-off-by Alexei Potashnik <[email protected]>Signed-off-by Spencer Baugh <[email protected]>---
Very nice catch on this bug.
Quoted 8 lines
drivers/target/iscsi/iscsi_target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/target/iscsi/iscsi_target.c +0
-0
drivers/target/iscsi/iscsi_target.c int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, · line 976
Quoted 8 lines
drivers/target/iscsi/iscsi_target.c +1
-1@@ -970,7 +970,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;if (hdr->flags &ISCSI_FLAG_CMD_READ ) { cmd->targ_xfer_tag =session_get_next_ttt (conn->sess); - }else if (hdr->flags &ISCSI_FLAG_CMD_WRITE ) + }else cmd->targ_xfer_tag =0xFFFFFFFF ; cmd->cmd_sn =be32_to_cpu (hdr->cmdsn); cmd->exp_stat_sn =be32_to_cpu (hdr->exp_statsn);
One small nit. linux kernel coding style says conditionals should use matching brackets. Since it's a single line body, no reason to use brackets at all.
Applying the updated patch below to target-pending/master with CC' for 3.1 stable.
Thanks!
drivers/target/iscsi/iscsi_target.c +2 -2
@@ -968,9 +968,9 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, cmd->cmd_flags |=ICF_NON_IMMEDIATE_UNSOLICITED_DATA ; conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt; -if (hdr->flags &ISCSI_FLAG_CMD_READ ) { +if (hdr->flags &ISCSI_FLAG_CMD_READ ) cmd->targ_xfer_tag =session_get_next_ttt (conn->sess); - }else if (hdr->flags &ISCSI_FLAG_CMD_WRITE ) +else cmd->targ_xfer_tag =0xFFFFFFFF ; cmd->cmd_sn =be32_to_cpu (hdr->cmdsn); cmd->exp_stat_sn =be32_to_cpu (hdr->exp_statsn);