untrusted comment: verify with openbsd-64-base.pub RWQq6XmS4eDAcYLbb9Qrbk02GtshyizIW4oHe/sWpX06imFm55277flF2+YK0+OBD9VDRz5rYfecSU3cBVEyHoSv2/3lhcrsZgg= OpenBSD 6.4 errata 015, March 22, 2019: A state in pf could pass ICMP packets to a destination IP address that did not match the state. Apply by doing: signify -Vep /etc/signify/openbsd-64-base.pub -x 015_pficmp.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: KK=`sysctl -n kern.osversion | cut -d# -f1` cd /usr/src/sys/arch/`machine`/compile/$KK make obj make config make make install Index: sys/net/pf.c =================================================================== RCS file: /cvs/src/sys/net/pf.c,v retrieving revision 1.1076 diff -u -p -r1.1076 pf.c --- sys/net/pf.c 4 Oct 2018 20:25:59 -0000 1.1076 +++ sys/net/pf.c 20 Mar 2019 20:25:06 -0000 @@ -4976,7 +4976,7 @@ pf_test_state_icmp(struct pf_pdesc *pd, u_short *reason) { u_int16_t virtual_id, virtual_type; - u_int8_t icmptype; + u_int8_t icmptype, icmpcode; int icmp_dir, iidx, ret, copyback = 0; struct pf_state_key_cmp key; @@ -4984,10 +4984,12 @@ pf_test_state_icmp(struct pf_pdesc *pd, switch (pd->proto) { case IPPROTO_ICMP: icmptype = pd->hdr.icmp.icmp_type; + icmpcode = pd->hdr.icmp.icmp_code; break; #ifdef INET6 case IPPROTO_ICMPV6: icmptype = pd->hdr.icmp6.icmp6_type; + icmpcode = pd->hdr.icmp6.icmp6_code; break; #endif /* INET6 */ default: @@ -5163,6 +5165,24 @@ pf_test_state_icmp(struct pf_pdesc *pd, unhandled_af(pd->af); } + if (PF_ANEQ(pd->dst, pd2.src, pd->af)) { + if (pf_status.debug >= LOG_NOTICE) { + log(LOG_NOTICE, + "pf: BAD ICMP %d:%d outer dst: ", + icmptype, icmpcode); + pf_print_host(pd->src, 0, pd->af); + addlog(" -> "); + pf_print_host(pd->dst, 0, pd->af); + addlog(" inner src: "); + pf_print_host(pd2.src, 0, pd2.af); + addlog(" -> "); + pf_print_host(pd2.dst, 0, pd2.af); + addlog("\n"); + } + REASON_SET(reason, PFRES_BADSTATE); + return (PF_DROP); + } + switch (pd2.proto) { case IPPROTO_TCP: { struct tcphdr *th = &pd2.hdr.tcp; @@ -5231,7 +5251,7 @@ pf_test_state_icmp(struct pf_pdesc *pd, if (pf_status.debug >= LOG_NOTICE) { log(LOG_NOTICE, "pf: BAD ICMP %d:%d ", - icmptype, pd->hdr.icmp.icmp_code); + icmptype, icmpcode); pf_print_host(pd->src, 0, pd->af); addlog(" -> "); pf_print_host(pd->dst, 0, pd->af); @@ -5245,7 +5265,7 @@ pf_test_state_icmp(struct pf_pdesc *pd, if (pf_status.debug >= LOG_DEBUG) { log(LOG_DEBUG, "pf: OK ICMP %d:%d ", - icmptype, pd->hdr.icmp.icmp_code); + icmptype, icmpcode); pf_print_host(pd->src, 0, pd->af); addlog(" -> "); pf_print_host(pd->dst, 0, pd->af);