DragonFlyBSD Kernel Audit
DF-2458 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/iscsi/initiator/iscsi_subr.c b/sys/dev/disk/iscsi/initiator/iscsi_subr.c
--- a/sys/dev/disk/iscsi/initiator/iscsi_subr.c
+++ b/sys/dev/disk/iscsi/initiator/iscsi_subr.c
@@ -568,8 +568,25 @@
 
 			      if(pq->mp != NULL) {
 			      caddr_t		dp;
+			      u_int		edtlen = ntohl(cmd->edtlen);
 
+			      /*
+			       | rcmd->bo (Data-Offset / Buffer Offset) is a
+			       | target-controlled 32-bit field.  Without a
+			       | bounds check a malicious iSCSI target can make
+			       | us memcpy() the data segment to
+			       | csio->data_ptr + <attacker offset>, i.e. an
+			       | arbitrary-offset kernel heap write.  Require the
+			       | placement to lie entirely within the expected
+			       | transfer buffer (offset >= 0 and
+			       | offset + len <= edtlen) before copying.
+			       */
 			      offset = ntohl(rcmd->bo);
+			      if (offset < 0 || (u_int)offset + (u_int)len > edtlen) {
+				   xdebug("%d] bad data-in offset=%d len=%d edtlen=%d - dropping",
+					  sp->sid, offset, len, edtlen);
+				   break;
+			      }
 			      dp = csio->data_ptr + offset;
 			      i_mbufcopy(pq->mp, dp, len);
 			 }