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 @@ -84,6 +84,18 @@ bo = ntohl(r2t->bo); bleft = ddtl; + /* + | r2t->bo / r2t->ddtl are attacker-controlled (wire R2T). + | Reject any window that does not lie wholly within the + | initiator's CCB data buffer of edtl bytes; otherwise the + | loop below would walk csio->data_ptr past its allocation + | and leak kernel heap memory to the target. + */ + if (bo > edtl || ddtl > edtl - bo) { + xdebug("bad R2T: bo=%u ddtl=%u edtl=%u", bo, ddtl, edtl); + break; + } + if(sp->opt.maxXmitDataSegmentLength > 0) // danny's RFC bs = MIN(sp->opt.maxXmitDataSegmentLength, ddtl); else