untrusted comment: signature from openbsd 6.1 base secret key RWQEQa33SgQSErIs32NkWeYlQCL0d8A4xo1GYgP+klVxwasSWScgaoheiMysdtWtRxTVRH0X+no03zTNLOp6pmKQFk8fpnxgsAE= OpenBSD 6.1 errata 033, December 10th, 2017: A number of bugs were discovered in the MPLS stack that can be used to remotely trigger kernel crashes. Apply by doing: signify -Vep /etc/signify/openbsd-61-base.pub -x 033_mpls.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/netmpls/mpls_input.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netmpls/mpls_input.c,v retrieving revision 1.59 diff -u -p -r1.59 mpls_input.c --- sys/netmpls/mpls_input.c 2 Mar 2017 03:09:50 -0000 1.59 +++ sys/netmpls/mpls_input.c 8 Dec 2017 23:11:58 -0000 @@ -45,9 +45,9 @@ #define MPLS_TTL_GET(l) (ntohl((l) & MPLS_TTL_MASK)) #endif -int mpls_ip_adjttl(struct mbuf *, u_int8_t); +struct mbuf *mpls_ip_adjttl(struct mbuf *, u_int8_t); #ifdef INET6 -int mpls_ip6_adjttl(struct mbuf *, u_int8_t); +struct mbuf *mpls_ip6_adjttl(struct mbuf *, u_int8_t); #endif struct mbuf *mpls_do_error(struct mbuf *, int, int, int); @@ -60,10 +60,19 @@ mpls_input(struct mbuf *m) struct shim_hdr *shim; struct rtentry *rt; struct rt_mpls *rt_mpls; - struct ifnet *ifp = NULL; + struct ifnet *ifp; u_int8_t ttl; int hasbos; + if ((ifp = if_get(m->m_pkthdr.ph_ifidx)) == NULL || + !ISSET(ifp->if_xflags, IFXF_MPLS)) { + m_freem(m); + if_put(ifp); + return; + } + if_put(ifp); + ifp = NULL; + /* drop all broadcast and multicast packets */ if (m->m_flags & (M_BCAST | M_MCAST)) { m_freem(m); @@ -104,6 +113,8 @@ mpls_input(struct mbuf *m) if (ntohl(smpls->smpls_label) < MPLS_LABEL_RESERVED_MAX) { m = mpls_shim_pop(m); + if (m == NULL) + return; if (!hasbos) { /* * RFC 4182 relaxes the position of the @@ -119,19 +130,22 @@ mpls_input(struct mbuf *m) switch (ntohl(smpls->smpls_label)) { case MPLS_LABEL_IPV4NULL: do_v4: - if (mpls_ip_adjttl(m, ttl)) + if ((m = mpls_ip_adjttl(m, ttl)) == NULL) return; niq_enqueue(&ipintrq, m); return; #ifdef INET6 case MPLS_LABEL_IPV6NULL: do_v6: - if (mpls_ip6_adjttl(m, ttl)) + if ((m = mpls_ip6_adjttl(m, ttl)) == NULL) return; niq_enqueue(&ip6intrq, m); return; #endif /* INET6 */ case MPLS_LABEL_IMPLNULL: + if (m->m_len < sizeof(u_char) && + (m = m_pullup(m, sizeof(u_char))) == NULL) + return; switch (*mtod(m, u_char *) >> 4) { case IPVERSION: goto do_v4; @@ -173,6 +187,8 @@ do_v6: switch (rt_mpls->mpls_operation) { case MPLS_OP_POP: m = mpls_shim_pop(m); + if (m == NULL) + goto done; if (!hasbos) /* just forward to gw */ break; @@ -199,12 +215,12 @@ do_v6: switch(rt->rt_gateway->sa_family) { case AF_INET: - if (mpls_ip_adjttl(m, ttl)) + if ((m = mpls_ip_adjttl(m, ttl)) == NULL) goto done; break; #ifdef INET6 case AF_INET6: - if (mpls_ip6_adjttl(m, ttl)) + if ((m = mpls_ip6_adjttl(m, ttl)) == NULL) goto done; break; #endif @@ -266,7 +282,7 @@ done: rtfree(rt); } -int +struct mbuf * mpls_ip_adjttl(struct mbuf *m, u_int8_t ttl) { struct ip *ip; @@ -275,18 +291,18 @@ mpls_ip_adjttl(struct mbuf *m, u_int8_t if (mpls_mapttl_ip) { if (m->m_len < sizeof(struct ip) && (m = m_pullup(m, sizeof(struct ip))) == NULL) - return -1; + return NULL; ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; if (m->m_len < hlen) { if ((m = m_pullup(m, hlen)) == NULL) - return -1; + return NULL; ip = mtod(m, struct ip *); } /* make sure we have a valid header */ if (in_cksum(m, hlen) != 0) { - m_free(m); - return -1; + m_freem(m); + return NULL; } /* set IP ttl from MPLS ttl */ @@ -296,11 +312,11 @@ mpls_ip_adjttl(struct mbuf *m, u_int8_t ip->ip_sum = 0; ip->ip_sum = in_cksum(m, hlen); } - return 0; + return m; } #ifdef INET6 -int +struct mbuf * mpls_ip6_adjttl(struct mbuf *m, u_int8_t ttl) { struct ip6_hdr *ip6hdr; @@ -308,14 +324,14 @@ mpls_ip6_adjttl(struct mbuf *m, u_int8_t if (mpls_mapttl_ip6) { if (m->m_len < sizeof(struct ip6_hdr) && (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) - return -1; + return NULL; ip6hdr = mtod(m, struct ip6_hdr *); /* set IPv6 ttl from MPLS ttl */ ip6hdr->ip6_hlim = ttl; } - return 0; + return m; } #endif /* INET6 */ @@ -334,7 +350,7 @@ mpls_do_error(struct mbuf *m, int type, for (nstk = 0; nstk < MPLS_INKERNEL_LOOP_MAX; nstk++) { if (m->m_len < sizeof(*shim) && - (m = m_pullup(m, sizeof(*ip))) == NULL) + (m = m_pullup(m, sizeof(*shim))) == NULL) return (NULL); stack[nstk] = *mtod(m, struct shim_hdr *); m_adj(m, sizeof(*shim)); @@ -343,6 +359,9 @@ mpls_do_error(struct mbuf *m, int type, } shim = &stack[0]; + if (m->m_len < sizeof(u_char) && + (m = m_pullup(m, sizeof(u_char))) == NULL) + return (NULL); switch (*mtod(m, u_char *) >> 4) { case IPVERSION: if (m->m_len < sizeof(*ip) &&