untrusted comment: verify with openbsd-63-base.pub RWRxzbLwAd76ZeXJ4+O6l1UcypT2D0NY3Vpu/Xf9jtESRHY4PfT07CK/YPYN0EABdBlRgMrrUDNiwQTj9PpOaVUlAuVMpCD2zgc= OpenBSD 6.3 errata 031, 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-63-base.pub -x 031_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.1063 diff -u -p -r1.1063 pf.c --- sys/net/pf.c 6 Mar 2018 17:35:53 -0000 1.1063 +++ sys/net/pf.c 20 Mar 2019 20:24:15 -0000 @@ -4947,7 +4947,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; @@ -4955,10 +4955,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: @@ -5134,6 +5136,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; @@ -5199,7 +5219,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); @@ -5213,7 +5233,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);