DF-3467 / fix.diff
--- 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; } |