⬢ DragonFlyBSD Kernel Audit
DF-3467 / fix.diff
← back to finding ↓ download raw
--- a/sys/net/ipfw3_layer4/ip_fw3_layer4.c
+++ b/sys/net/ipfw3_layer4/ip_fw3_layer4.c
@@ -116,6 +116,13 @@
 	 */
 	dst_ip.s_addr = htonl(fid->dst_ip);
 	src_ip.s_addr = htonl(fid->src_ip);
+	/*
+	 * Hold the pcbinfo token across lookup + dereference: the pcb
+	 * is otherwise freed by a concurrent in_pcbdetach() between the
+	 * two (the lookup takes no reference of its own).
+	 */
+	KKASSERT(!LWKT_TOKEN_HELD(&pi->pcbinfo_token));
+	lwkt_gettoken(&pi->pcbinfo_token);
 	if (oif) {
 		pcb = in_pcblookup_hash(pi,
 				dst_ip, htons(fid->dst_port),
--- a/sys/net/ipfw3_layer4/ip_fw3_layer4.c
+++ b/sys/net/ipfw3_layer4/ip_fw3_layer4.c
@@ -128,6 +128,7 @@
 				wildcard, NULL);
 	}
 	if (pcb == NULL || pcb->inp_socket == NULL) {
+		lwkt_reltoken(&pi->pcbinfo_token);
 		return 0;
 	}