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