DF-2459 / fix.diff
diff --git a/sys/dev/disk/iscsi/initiator/isc_sm.c b/sys/dev/disk/iscsi/initiator/isc_sm.c --- a/sys/dev/disk/iscsi/initiator/isc_sm.c +++ b/sys/dev/disk/iscsi/initiator/isc_sm.c @@ -225,6 +225,22 @@ nop_out = &pp->ipdu.nop_out; nop_out->sn.maxcmd = 0; memset(nop_out->mbz, 0, sizeof(nop_out->mbz)); + /* + | We are reusing a *received* PDU for sending. Received + | PDUs carry any AHS/data in the mbuf chain (pq->mp), never + | in pp->ahs / pp->ds (both stay NULL from pdu_alloc). + | isc_sendPDU() however does bcopy(pp->ahs, ...) whenever + | pp->ahs_len is non-zero -- so a NOP-IN whose BHS carried a + | non-zero AHSLength would make that bcopy read from NULL and + | panic. The outgoing NOP-OUT keep-alive carries no AHS and + | no data, so drop the stale length fields and let isc_qout + | re-prepare the PDU for transmission. + */ + pp->ahs_len = 0; + pp->ahs = NULL; + pp->ds_len = 0; + pp->ds = NULL; + pq->len = 0; /* forces isc_qout() -> i_prepPDU() */ (void)isc_qout(sp, pq); //XXX: should check return? return; } |