Module Name: src Committed By: maxv Date: Fri Jan 26 07:49:15 UTC 2018
Modified Files: src/sys/net: if_l2tp.c src/sys/netinet: in_l2tp.c src/sys/netinet6: in6_l2tp.c Log Message: Several fixes in L2TP: * l2tp_input(): use m_copydata, and ensure there is enough space in the chain. Otherwise overflow. * l2tp_tcpmss_clamp(): ensure there is enough space in the chain. * in_l2tp_output(): don't check 'sc' against NULL, it can't be NULL. * in_l2tp_input(): no need to call m_pullup since we use m_copydata. Just check the space in the chain. * in_l2tp_input(): if there is a cookie, make sure the chain has enough space. * in6_l2tp_input(): same changes as in_l2tp_input(). Ok knakahara@ To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/sys/net/if_l2tp.c cvs rdiff -u -r1.11 -r1.12 src/sys/netinet/in_l2tp.c cvs rdiff -u -r1.13 -r1.14 src/sys/netinet6/in6_l2tp.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_l2tp.c diff -u src/sys/net/if_l2tp.c:1.18 src/sys/net/if_l2tp.c:1.19 --- src/sys/net/if_l2tp.c:1.18 Thu Jan 25 10:33:37 2018 +++ src/sys/net/if_l2tp.c Fri Jan 26 07:49:15 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: if_l2tp.c,v 1.18 2018/01/25 10:33:37 maxv Exp $ */ +/* $NetBSD: if_l2tp.c,v 1.19 2018/01/26 07:49:15 maxv Exp $ */ /* * Copyright (c) 2017 Internet Initiative Japan Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_l2tp.c,v 1.18 2018/01/25 10:33:37 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_l2tp.c,v 1.19 2018/01/26 07:49:15 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -465,10 +465,18 @@ l2tpintr(struct l2tp_variant *var) void l2tp_input(struct mbuf *m, struct ifnet *ifp) { + u_long val; KASSERT(ifp != NULL); - if (0 == (mtod(m, u_long) & 0x03)) { + if (m->m_pkthdr.len < sizeof(val)) { + m_freem(m); + return; + } + + m_copydata(m, 0, sizeof(val), &val); + + if ((val & 0x03) == 0) { /* copy and align head of payload */ struct mbuf *m_head; int copy_length; @@ -1375,6 +1383,11 @@ l2tp_tcpmss_clamp(struct ifnet *ifp, str return m; } + if (m->m_pkthdr.len < sizeof(evh)) { + m_freem(m); + return NULL; + } + /* save ether header */ m_copydata(m, 0, sizeof(evh), (void *)&evh); eh = (struct ether_header *)&evh; Index: src/sys/netinet/in_l2tp.c diff -u src/sys/netinet/in_l2tp.c:1.11 src/sys/netinet/in_l2tp.c:1.12 --- src/sys/netinet/in_l2tp.c:1.11 Thu Jan 25 10:45:58 2018 +++ src/sys/netinet/in_l2tp.c Fri Jan 26 07:49:15 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: in_l2tp.c,v 1.11 2018/01/25 10:45:58 maxv Exp $ */ +/* $NetBSD: in_l2tp.c,v 1.12 2018/01/26 07:49:15 maxv Exp $ */ /* * Copyright (c) 2017 Internet Initiative Japan Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in_l2tp.c,v 1.11 2018/01/25 10:45:58 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in_l2tp.c,v 1.12 2018/01/26 07:49:15 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_l2tp.h" @@ -103,9 +103,6 @@ in_l2tp_output(struct l2tp_variant *var, && sin_dst->sin_family == AF_INET); sc = var->lv_softc; - if (sc == NULL) - return ENETUNREACH; - ifp = &sc->l2tp_ec.ec_if; error = l2tp_check_nesting(ifp, m); if (error) { @@ -262,13 +259,12 @@ in_l2tp_input(struct mbuf *m, int off, i struct psref psref; struct l2tp_variant *var; - if (m->m_len < off + sizeof(uint32_t)) { - m = m_pullup(m, off + sizeof(uint32_t)); - if (!m) { - /* if payload length < 4 octets */ - return; - } - } + KASSERT((m->m_flags & M_PKTHDR) != 0); + + if (m->m_pkthdr.len < off + sizeof(uint32_t)) { + m_freem(m); + return; + } /* get L2TP session ID */ m_copydata(m, off, sizeof(uint32_t), (void *)&sess_id); @@ -322,6 +318,10 @@ in_l2tp_input(struct mbuf *m, int off, i m_adj(m, off + sizeof(uint32_t)); if (var->lv_use_cookie == L2TP_COOKIE_ON) { + if (m->m_pkthdr.len < var->lv_my_cookie_len) { + m_freem(m); + goto out; + } if (var->lv_my_cookie_len == 4) { m_copydata(m, 0, sizeof(uint32_t), (void *)&cookie_32); NTOHL(cookie_32); Index: src/sys/netinet6/in6_l2tp.c diff -u src/sys/netinet6/in6_l2tp.c:1.13 src/sys/netinet6/in6_l2tp.c:1.14 --- src/sys/netinet6/in6_l2tp.c:1.13 Thu Jan 25 10:45:58 2018 +++ src/sys/netinet6/in6_l2tp.c Fri Jan 26 07:49:15 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: in6_l2tp.c,v 1.13 2018/01/25 10:45:58 maxv Exp $ */ +/* $NetBSD: in6_l2tp.c,v 1.14 2018/01/26 07:49:15 maxv Exp $ */ /* * Copyright (c) 2017 Internet Initiative Japan Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in6_l2tp.c,v 1.13 2018/01/25 10:45:58 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in6_l2tp.c,v 1.14 2018/01/26 07:49:15 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_l2tp.h" @@ -253,14 +253,12 @@ in6_l2tp_input(struct mbuf **mp, int *of uint64_t cookie_64; struct psref psref; - if (m->m_len < off + sizeof(uint32_t)) { - m = m_pullup(m, off + sizeof(uint32_t)); - if (!m) { - /* if payload length < 4 octets */ - return IPPROTO_DONE; - } - *mp = m; - } + KASSERT((m->m_flags & M_PKTHDR) != 0); + + if (m->m_pkthdr.len < off + sizeof(uint32_t)) { + m_freem(m); + return IPPROTO_DONE; + } /* get L2TP session ID */ m_copydata(m, off, sizeof(uint32_t), (void *)&sess_id); @@ -312,6 +310,10 @@ in6_l2tp_input(struct mbuf **mp, int *of m_adj(m, off + sizeof(uint32_t)); if (var->lv_use_cookie == L2TP_COOKIE_ON) { + if (m->m_pkthdr.len < var->lv_my_cookie_len) { + m_freem(m); + goto out; + } if (var->lv_my_cookie_len == 4) { m_copydata(m, 0, sizeof(uint32_t), (void *)&cookie_32); NTOHL(cookie_32);