DragonFlyBSD Kernel Audit
DF-2459 / fix.diff
← back to finding ↓ download raw
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;
 	  }