DF-1827 / fix.diff
diff --git a/sys/dev/disk/iscsi/initiator/isc_soc.c b/sys/dev/disk/iscsi/initiator/isc_soc.c --- a/sys/dev/disk/iscsi/initiator/isc_soc.c +++ b/sys/dev/disk/iscsi/initiator/isc_soc.c @@ -108,10 +108,27 @@ /* | mbuf for the iSCSI header */ - MGETHDR(mh, M_WAITOK, MT_DATA); + /* + | Compute the total iSCSI header length up-front so MH_ALIGN + | can seat it correctly at the END of m_pktdat. The original + | code MH_ALIGN'd only the BHS (sizeof(union ipdu_u)), leaving + | zero trailing bytes for AHS or the header digest, so the + | subsequent bcopy()s wrote past m_pktdat (DF-1827). + */ + { + size_t hdrlen = sizeof(union ipdu_u) + + (sp->hdrDigest ? sizeof(int) : 0) + + pp->ahs_len; + + if (hdrlen > MHLEN) { + debug(2, "iSCSI header too large (%zu > %ld)", hdrlen, (long)MHLEN); + return E2BIG; + } + MGETHDR(mh, M_WAITOK, MT_DATA); + mh->m_pkthdr.rcvif = NULL; + MH_ALIGN(mh, hdrlen); + } mh->m_len = mh->m_pkthdr.len = sizeof(union ipdu_u); - mh->m_pkthdr.rcvif = NULL; - MH_ALIGN(mh, sizeof(union ipdu_u)); bcopy(&pp->ipdu, mh->m_data, sizeof(union ipdu_u)); mh->m_next = NULL; |