[PATCH v2] scsi: libiscsi_tcp: bound SCSI Response data segment to the connection buffer

HyeongJun An posted 1 patch 1 week, 2 days ago
drivers/scsi/libiscsi_tcp.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
[PATCH v2] scsi: libiscsi_tcp: bound SCSI Response data segment to the connection buffer
Posted by HyeongJun An 1 week, 2 days ago
iscsi_tcp_hdr_dissect() receives the data segment of several PDU types
into the fixed-size conn->data buffer, which is allocated for
ISCSI_DEF_MAX_RECV_SEG_LEN (8192) bytes.  For the LOGIN_RSP, TEXT_RSP,
REJECT and ASYNC_EVENT opcodes the dissect path already rejects a PDU
whose DataSegmentLength exceeds that buffer.

The SCSI Command Response (ISCSI_OP_SCSI_CMD_RSP) path also copies its
data segment (sense/response data) into conn->data via
iscsi_tcp_data_recv_prep(), but it does so without the same check.  The
only upstream bound on in.datalen is conn->max_recv_dlength, the
initiator's advertised MaxRecvDataSegmentLength, which is commonly
negotiated well above 8192 (open-iscsi defaults to 262144).  A target
that returns a SCSI Response with a DataSegmentLength between 8193 and
max_recv_dlength therefore overflows the 8192-byte conn->data buffer.

Once the same bound applies, ISCSI_OP_SCSI_CMD_RSP is handled exactly
like those responses: bound the data segment, receive it into conn->data
when present, and otherwise complete the PDU with no data.  Fold the
opcode into that case group rather than duplicating the check.

Fixes: a081c13e39b5 ("[SCSI] iscsi_tcp: split module into lib and lld")
Suggested-by: Chris Leech <cleech@redhat.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
---
v2: Fold ISCSI_OP_SCSI_CMD_RSP into the LOGIN_RSP/TEXT_RSP/REJECT/
    ASYNC_EVENT case group instead of duplicating the bounds check, as
    suggested by Chris Leech.  The handling is identical: both bound the
    data segment to conn->data, receive it when present, and otherwise
    complete the PDU with no data (the latter via the LOGOUT_RSP
    fallthrough).  No functional change from v1.

v1: https://lore.kernel.org/all/20260710050645.1194212-1-sammiee5311@gmail.com/

 drivers/scsi/libiscsi_tcp.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index e90805ba868f..7223bb18b048 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -752,13 +752,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 		rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
 		spin_unlock(&conn->session->back_lock);
 		break;
-	case ISCSI_OP_SCSI_CMD_RSP:
-		if (tcp_conn->in.datalen) {
-			iscsi_tcp_data_recv_prep(tcp_conn);
-			return 0;
-		}
-		rc = iscsi_complete_pdu(conn, hdr, NULL, 0);
-		break;
 	case ISCSI_OP_R2T:
 		if (ahslen) {
 			rc = ISCSI_ERR_AHSLEN;
@@ -766,6 +759,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 		}
 		rc = iscsi_tcp_r2t_rsp(conn, hdr);
 		break;
+	case ISCSI_OP_SCSI_CMD_RSP:
 	case ISCSI_OP_LOGIN_RSP:
 	case ISCSI_OP_TEXT_RSP:
 	case ISCSI_OP_REJECT:
-- 
2.43.0
Re: [PATCH v2] scsi: libiscsi_tcp: bound SCSI Response data segment to the connection buffer
Posted by Chris Leech 1 week, 2 days ago
On Thu, Jul 16, 2026 at 03:58:48PM +0900, HyeongJun An wrote:
> iscsi_tcp_hdr_dissect() receives the data segment of several PDU types
> into the fixed-size conn->data buffer, which is allocated for
> ISCSI_DEF_MAX_RECV_SEG_LEN (8192) bytes.  For the LOGIN_RSP, TEXT_RSP,
> REJECT and ASYNC_EVENT opcodes the dissect path already rejects a PDU
> whose DataSegmentLength exceeds that buffer.
> 
> The SCSI Command Response (ISCSI_OP_SCSI_CMD_RSP) path also copies its
> data segment (sense/response data) into conn->data via
> iscsi_tcp_data_recv_prep(), but it does so without the same check.  The
> only upstream bound on in.datalen is conn->max_recv_dlength, the
> initiator's advertised MaxRecvDataSegmentLength, which is commonly
> negotiated well above 8192 (open-iscsi defaults to 262144).  A target
> that returns a SCSI Response with a DataSegmentLength between 8193 and
> max_recv_dlength therefore overflows the 8192-byte conn->data buffer.
> 
> Once the same bound applies, ISCSI_OP_SCSI_CMD_RSP is handled exactly
> like those responses: bound the data segment, receive it into conn->data
> when present, and otherwise complete the PDU with no data.  Fold the
> opcode into that case group rather than duplicating the check.
> 
> Fixes: a081c13e39b5 ("[SCSI] iscsi_tcp: split module into lib and lld")
> Suggested-by: Chris Leech <cleech@redhat.com>
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
> ---
> v2: Fold ISCSI_OP_SCSI_CMD_RSP into the LOGIN_RSP/TEXT_RSP/REJECT/
>     ASYNC_EVENT case group instead of duplicating the bounds check, as
>     suggested by Chris Leech.  The handling is identical: both bound the
>     data segment to conn->data, receive it when present, and otherwise
>     complete the PDU with no data (the latter via the LOGOUT_RSP
>     fallthrough).  No functional change from v1.
> 
> v1: https://lore.kernel.org/all/20260710050645.1194212-1-sammiee5311@gmail.com/
> 
>  drivers/scsi/libiscsi_tcp.c | 8 +-------
>  1 file changed, 1 insertion(+), 7 deletions(-)

Acked-by: Chris Leech <cleech@redhat.com>