Skip to contentSkip to conversation

scsi: libiscsi_tcp: prevent R2T range check overflow

PATCH Applied Ratnaker Gautam 3 participants 4 messages Oct 19 – Oct 29

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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.

Fixes a081c13e39b5 ("[SCSI] iscsi_tcp: split module into lib and lld")
---
 drivers/scsi/libiscsi_tcp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/libiscsi_tcp.c +2 -1
index d35f93451ee9b..3c9e736d45e7e 100644
@@ -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
maintainer Acked-by on v1 1/1
#1 lore raw
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_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.

Fixes a081c13e39b5 ("[SCSI] iscsi_tcp: split module into lib and lld")
---
 drivers/scsi/libiscsi_tcp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/scsi/libiscsi_tcp.c +0 -0
index d35f93451ee9b..3c9e736d45e7e 100644

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,
maintainer Applied
#2 lore raw
In reply to Ratnaker Gautam

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_MAX then passes the check for a 4096-byte write.

Applied to 7.4/scsi-staging, thanks!

Signature · 1 line
Martin K. Petersen
maintainer Applied
#3 lore raw
In reply to Ratnaker Gautam
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_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().

[...]

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