⬢ DragonFlyBSD Kernel Audit
DF-2966 / fix.diff
← back to finding ↓ download raw
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -129,12 +129,48 @@
  * Note: you cant unload it again because a socket may be using it.
  * XXX can't fail at this time.
  */
+static void
+net_init_domain_fill(struct domain *dp)
+{
+	struct protosw *pr;
+	struct pr_usrreqs *pu;
+
+	/* Close the NULL-dispatch window: publish only protosw whose
+	 * optional hooks are stubbed.  dom_init/pr_init still run after
+	 * publication (boot-order dependency - see ip_init). */
+	for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
+		pu = pr->pr_usrreqs;
+		if (pu == NULL)
+			continue;
+		PR_NOTSUPP(pr, ctloutput);
+		PRU_NOTSUPP(pu, accept);
+		PRU_NOTSUPP(pu, bind);
+		PRU_NOTSUPP(pu, connect);
+		PRU_NOTSUPP(pu, connect2);
+		PRU_NOTSUPP(pu, control);
+		PRU_NOTSUPP(pu, disconnect);
+		PRU_NOTSUPP(pu, listen);
+		PRU_NOTSUPP(pu, peeraddr);
+		PRU_NOTSUPP(pu, rcvd);
+		PRU_NOTSUPP(pu, rcvoob);
+		PRU_NOTSUPP(pu, shutdown);
+		PRU_NOTSUPP(pu, sockaddr);
+		if (pu->pru_sense == NULL)
+			pu->pru_sense = pru_sense_null;
+		if (pu->pru_sosend == NULL)
+			pu->pru_sosend = pru_sosend_notsupp;
+		if (pu->pru_soreceive == NULL)
+			pu->pru_soreceive = pru_soreceive_notsupp;
+	}
+}
+
 void
 net_add_domain(void *data)
 {
 	struct domain *dp = data;
 
 	crit_enter();
+	net_init_domain_fill(dp);
 	SLIST_INSERT_HEAD(&domains, dp, dom_next);
 	crit_exit();
 	net_init_domain(dp);