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);