untrusted comment: verify with openbsd-63-base.pub RWRxzbLwAd76ZcEXCheKUn6PxBdrrdUBRinBzAd3ttj/UbqvZXo9k717eee+nD9+V2b7DCR2XaBXQmAV5ptpWrRAvzoSQd4WOwA= OpenBSD 6.3 errata 033, May 3, 2019: If a userland program sets the IPv6 checksum offset on a raw socket, an incoming packet could crash the kernel. ospf6d is such a program. Apply by doing: signify -Vep /etc/signify/openbsd-63-base.pub -x 033_rip6cksum.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/ip6_output.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_output.c,v retrieving revision 1.236 diff -u -p -r1.236 ip6_output.c --- sys/netinet6/ip6_output.c 21 Mar 2018 14:42:41 -0000 1.236 +++ sys/netinet6/ip6_output.c 23 Apr 2019 01:42:26 -0000 @@ -1620,8 +1620,12 @@ ip6_raw_ctloutput(int op, struct socket break; } optval = *mtod(m, int *); - if ((optval % 2) != 0) { - /* the API assumes even offset values */ + if (optval < -1 || + (optval > 0 && (optval % 2) != 0)) { + /* + * The API assumes non-negative even offset + * values or -1 as a special value. + */ error = EINVAL; } else if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { if (optval != icmp6off) Index: sys/netinet6/raw_ip6.c =================================================================== RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v retrieving revision 1.126 diff -u -p -r1.126 raw_ip6.c --- sys/netinet6/raw_ip6.c 1 Feb 2018 21:11:33 -0000 1.126 +++ sys/netinet6/raw_ip6.c 23 Apr 2019 01:42:27 -0000 @@ -185,7 +185,16 @@ rip6_input(struct mbuf **mp, int *offp, } if (proto != IPPROTO_ICMPV6 && in6p->inp_cksum6 != -1) { rip6stat_inc(rip6s_isum); - if (in6_cksum(m, proto, *offp, + /* + * Although in6_cksum() does not need the position of + * the checksum field for verification, enforce that it + * is located within the packet. Userland has given + * a checksum offset, a packet too short for that is + * invalid. Avoid overflow with user supplied offset. + */ + if (m->m_pkthdr.len < *offp + 2 || + m->m_pkthdr.len - *offp - 2 < in6p->inp_cksum6 || + in6_cksum(m, proto, *offp, m->m_pkthdr.len - *offp)) { rip6stat_inc(rip6s_badsum); continue; @@ -440,7 +449,7 @@ rip6_output(struct mbuf *m, struct socke off = offsetof(struct icmp6_hdr, icmp6_cksum); else off = in6p->inp_cksum6; - if (plen < off + 1) { + if (plen < 2 || plen - 2 < off) { error = EINVAL; goto bad; }