diff --git a/sys/dev/disk/iscsi/initiator/iscsi.c b/sys/dev/disk/iscsi/initiator/iscsi.c --- a/sys/dev/disk/iscsi/initiator/iscsi.c +++ b/sys/dev/disk/iscsi/initiator/iscsi.c @@ -453,6 +453,18 @@ pp = &pq->pdu; pq->pdu = *(pdu_t *)arg; pq->refcnt = 0; + /* + | AHS length must be a multiple of 4 (the iSCSI BHS AHSLength field is + | counted in 4-byte words). A non-multiple-of-4 ahs_len makes the + | data-segment padding in i_send()/isc_sendPDU() diverge from the + | total-length rounding in i_prepPDU(), overflowing pq->buf. Reject it + | here rather than computing an inconsistent wire length. + */ + if(pp->ahs_len & 0x3) { + xdebug("i_send: ahs_len=%d not a multiple of 4", pp->ahs_len); + error = EINVAL; + goto out; + } if((error = i_prepPDU(sp, pq)) != 0) goto out;