scsi: libiscsi_tcp: prevent R2T range check overflow
PATCH 1/1 scsi: libiscsi_tcp: prevent R2T range check overflow
An iSCSI target controls the R2T data offset and length as 32-bit values. Adding them before comparing the result with the SCSI data buffer length can wrap. An R2T with offset 1 and length U32_MAX then passes the check for a 4096-byte write.
The transmit path treats the wrapped range as valid, exhausts the command scatterlist, and dereferences the NULL next entry in iscsi_tcp_segment_done().
Check the offset first, then compare the length with the remaining bytes in the data buffer.
--- drivers/scsi/libiscsi_tcp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/libiscsi_tcp.c +2 -1
@@ -601,7 +601,8 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) data_length, session->max_burst); data_offset =be32_to_cpu (rhdr->data_offset); -if (data_offset + data_length > task->sc->sdb.length) { +if (data_offset > task->sc->sdb.length || + data_length > task->sc->sdb.length - data_offset) { iscsi_conn_printk(KERN_ERR, conn, "invalid R2T with data len %u at offset %u " "and total length %d\n", data_length,
Signature · 1 line
2.43.0
Quoted 25 lines · Ratnaker Gautam
An iSCSI target controls the R2T data offset and length as 32-bit values. Adding them before comparing the result with the SCSI data buffer length can wrap. An R2T with offset 1 and length
U32_MAXthen passes the check for a 4096-byte write.The transmit path treats the wrapped range as valid, exhausts the command scatterlist, and dereferences the NULL next entry in
iscsi_tcp_segment_done().Check the offset first, then compare the length with the remaining bytes in the data buffer.
Fixes a081c13e39b5 ("[SCSI] iscsi_tcp: split module into lib and lld")Signed-off-by Ratnaker Gautam <[email protected]>--- drivers/scsi/libiscsi_tcp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/scsi/libiscsi_tcp.c +0
-0
drivers/scsi/libiscsi_tcp.c static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) · line 608
Quoted 9 lines
drivers/scsi/libiscsi_tcp.c +2
-1@@ -601,7 +601,8 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) data_length, session->max_burst); data_offset =be32_to_cpu (rhdr->data_offset); -if (data_offset + data_length > task->sc->sdb.length) { +if (data_offset > task->sc->sdb.length || + data_length > task->sc->sdb.length - data_offset) { iscsi_conn_printk(KERN_ERR, conn, "invalid R2T with data len %u at offset %u " "and total length %d\n", data_length,
Ratnaker,
Quoted 4 lines
An iSCSI target controls the R2T data offset and length as 32-bit values. Adding them before comparing the result with the SCSI data buffer length can wrap. An R2T with offset 1 and length
U32_MAXthen passes the check for a 4096-byte write.
Applied to 7.4/scsi-staging, thanks!
Signature · 1 line
Martin K. Petersen
Quoted 10 lines · Ratnaker Gautam
An iSCSI target controls the R2T data offset and length as 32-bit values. Adding them before comparing the result with the SCSI data buffer length can wrap. An R2T with offset 1 and length
U32_MAXthen passes the check for a 4096-byte write.The transmit path treats the wrapped range as valid, exhausts the command scatterlist, and dereferences the NULL next entry in
iscsi_tcp_segment_done().[...]
Applied to 7.4/scsi-queue, thanks!
[1/1] scsi: libiscsi_tcp: prevent R2T range check overflow
https://git.kernel.org/mkp/scsi/c/eb7aa7fd673f
Signature · 1 line
Martin K. Petersen