untrusted comment: verify with openbsd-64-base.pub RWQq6XmS4eDAcS//nXkwpe2MSFVDINb10ribd/OrgSTriqv6sDqIV2gQOBmCi5ZQNGxZ89WBzTwlGnWV/oidsRdSKOjeGNV/Aw4= OpenBSD 6.4 errata 023, September 2, 2019: When processing ECN bits on incoming IPv6 fragments, the kernel could crash. Per default pf fragment reassemble prevents the crash. Apply by doing: signify -Vep /etc/signify/openbsd-64-base.pub -x 023_frag6ecn.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/netinet6/frag6.c =================================================================== RCS file: /cvs/src/sys/netinet6/frag6.c,v retrieving revision 1.85 diff -u -p -r1.85 frag6.c --- sys/netinet6/frag6.c 10 Sep 2018 16:14:08 -0000 1.85 +++ sys/netinet6/frag6.c 26 Aug 2019 19:43:53 -0000 @@ -224,6 +224,7 @@ frag6_input(struct mbuf **mp, int *offp, q6->ip6q_ttl = IPV6_FRAGTTL; q6->ip6q_src = ip6->ip6_src; q6->ip6q_dst = ip6->ip6_dst; + q6->ip6q_ecn = (ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK; q6->ip6q_unfrglen = -1; /* The 1st fragment has not arrived. */ q6->ip6q_nfrag = 0; } @@ -299,7 +300,6 @@ frag6_input(struct mbuf **mp, int *offp, mtx_leave(&frag6_mutex); goto dropfrag; } - ip6af->ip6af_flow = ip6->ip6_flow; ip6af->ip6af_mff = ip6f->ip6f_offlg & IP6F_MORE_FRAG; ip6af->ip6af_off = fragoff; ip6af->ip6af_frglen = frgpartlen; @@ -316,9 +316,8 @@ frag6_input(struct mbuf **mp, int *offp, * if CE is set, do not lose CE. * drop if CE and not-ECT are mixed for the same packet. */ - af6 = LIST_FIRST(&q6->ip6q_asfrag); ecn = (ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK; - ecn0 = (ntohl(af6->ip6af_flow) >> 20) & IPTOS_ECN_MASK; + ecn0 = q6->ip6q_ecn; if (ecn == IPTOS_ECN_CE) { if (ecn0 == IPTOS_ECN_NOTECT) { mtx_leave(&frag6_mutex); @@ -326,7 +325,7 @@ frag6_input(struct mbuf **mp, int *offp, goto dropfrag; } if (ecn0 != IPTOS_ECN_CE) - af6->ip6af_flow |= htonl(IPTOS_ECN_CE << 20); + q6->ip6q_ecn = IPTOS_ECN_CE; } if (ecn == IPTOS_ECN_NOTECT && ecn0 != IPTOS_ECN_NOTECT) { mtx_leave(&frag6_mutex); @@ -411,6 +410,8 @@ frag6_input(struct mbuf **mp, int *offp, ip6->ip6_plen = htons((u_short)next + offset - sizeof(struct ip6_hdr)); ip6->ip6_src = q6->ip6q_src; ip6->ip6_dst = q6->ip6q_dst; + if (q6->ip6q_ecn == IPTOS_ECN_CE) + ip6->ip6_flow |= htonl(IPTOS_ECN_CE << 20); nxt = q6->ip6q_nxt; /* Delete frag6 header */ Index: sys/netinet6/ip6_var.h =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_var.h,v retrieving revision 1.84 diff -u -p -r1.84 ip6_var.h --- sys/netinet6/ip6_var.h 10 Oct 2018 11:46:59 -0000 1.84 +++ sys/netinet6/ip6_var.h 26 Aug 2019 19:43:53 -0000 @@ -76,6 +76,7 @@ struct ip6q { int ip6q_nfrag; /* # of fragments */ u_int32_t ip6q_ident; /* fragment identification */ u_int8_t ip6q_nxt; /* ip6f_nxt in first fragment */ + u_int8_t ip6q_ecn; u_int8_t ip6q_ttl; /* time to live in slowtimo units */ }; @@ -85,7 +86,6 @@ struct ip6asfrag { int ip6af_offset; /* offset in ip6af_m to next header */ int ip6af_frglen; /* fragmentable part length */ int ip6af_off; /* fragment offset */ - u_int32_t ip6af_flow; /* ip header flow id */ u_int16_t ip6af_mff; /* more fragment bit in frag off */ };