From: claudio Date: Fri, 8 Dec 2017 21:56:22 +0000 (+0000) Subject: The adjttl functions use m_pullup(). In some cases m_pullup() can return X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=25d240d263d10cd9492fd3851b3826d667edb794;p=openbsd The adjttl functions use m_pullup(). In some cases m_pullup() can return a new mbuf chain and this chain needs to be returned to the caller else a use after free may happen. Issue reported by Maxime Villard OK bluhm@ deraadt@ --- diff --git a/sys/netmpls/mpls_input.c b/sys/netmpls/mpls_input.c index b8930cbe6e7..20c395e44be 100644 --- a/sys/netmpls/mpls_input.c +++ b/sys/netmpls/mpls_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpls_input.c,v 1.62 2017/12/08 21:52:49 claudio Exp $ */ +/* $OpenBSD: mpls_input.c,v 1.63 2017/12/08 21:56:22 claudio Exp $ */ /* * Copyright (c) 2008 Claudio Jeker @@ -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); @@ -135,7 +135,7 @@ 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) { if_put(ifp); return; } @@ -145,7 +145,7 @@ do_v4: #ifdef INET6 case MPLS_LABEL_IPV6NULL: do_v6: - if (mpls_ip6_adjttl(m, ttl)) { + if ((m = mpls_ip6_adjttl(m, ttl)) == NULL) { if_put(ifp); return; } @@ -227,12 +227,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 @@ -294,7 +294,7 @@ done: rtfree(rt); } -int +struct mbuf * mpls_ip_adjttl(struct mbuf *m, u_int8_t ttl) { struct ip *ip; @@ -303,18 +303,18 @@ mpls_ip_adjttl(struct mbuf *m, u_int8_t ttl) 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; + return NULL; } /* set IP ttl from MPLS ttl */ @@ -324,11 +324,11 @@ mpls_ip_adjttl(struct mbuf *m, u_int8_t ttl) 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; @@ -336,14 +336,14 @@ mpls_ip6_adjttl(struct mbuf *m, u_int8_t ttl) 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 */