From owner-svn-src-head@FreeBSD.ORG Sat Jan 10 03:13:17 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id A36487EB; Sat, 10 Jan 2015 03:13:17 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8FC17817; Sat, 10 Jan 2015 03:13:17 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0A3DH0E060089; Sat, 10 Jan 2015 03:13:17 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0A3DHIG060086; Sat, 10 Jan 2015 03:13:17 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201501100313.t0A3DHIG060086@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Sat, 10 Jan 2015 03:13:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r276901 - head/sys/net X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 10 Jan 2015 03:13:17 -0000 Author: ae Date: Sat Jan 10 03:13:16 2015 New Revision: 276901 URL: https://svnweb.freebsd.org/changeset/base/276901 Log: Move the recursion detection code into separate function gif_check_nesting(). Also make MTAG_GIF definition private to if_gif.c. MFC after: 1 week Modified: head/sys/net/if_gif.c head/sys/net/if_gif.h Modified: head/sys/net/if_gif.c ============================================================================== --- head/sys/net/if_gif.c Sat Jan 10 01:05:12 2015 (r276900) +++ head/sys/net/if_gif.c Sat Jan 10 03:13:16 2015 (r276901) @@ -446,24 +446,12 @@ gif_qflush(struct ifnet *ifp __unused) } -int -gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, - struct route *ro) +#define MTAG_GIF 1080679712 +static int +gif_check_nesting(struct ifnet *ifp, struct mbuf *m) { struct m_tag *mtag; - uint32_t af; - int gif_called; - int error = 0; -#ifdef MAC - error = mac_ifnet_check_transmit(ifp, m); - if (error) - goto err; -#endif - if ((ifp->if_flags & IFF_MONITOR) != 0 || - (ifp->if_flags & IFF_UP) == 0) { - error = ENETDOWN; - goto err; - } + int count; /* * gif may cause infinite recursion calls when misconfigured. @@ -472,35 +460,49 @@ gif_output(struct ifnet *ifp, struct mbu * High nesting level may cause stack exhaustion. * We'll prevent this by introducing upper limit. */ - gif_called = 1; - mtag = m_tag_locate(m, MTAG_GIF, MTAG_GIF_CALLED, NULL); - while (mtag != NULL) { + count = 1; + mtag = NULL; + while ((mtag = m_tag_locate(m, MTAG_GIF, 0, mtag)) != NULL) { if (*(struct ifnet **)(mtag + 1) == ifp) { - log(LOG_NOTICE, - "gif_output: loop detected on %s\n", - (*(struct ifnet **)(mtag + 1))->if_xname); - error = EIO; /* is there better errno? */ - goto err; + log(LOG_NOTICE, "%s: loop detected\n", ifp->if_xname); + return (EIO); } - mtag = m_tag_locate(m, MTAG_GIF, MTAG_GIF_CALLED, mtag); - gif_called++; + count++; } - if (gif_called > V_max_gif_nesting) { + if (count > V_max_gif_nesting) { log(LOG_NOTICE, - "gif_output: recursively called too many times(%d)\n", - gif_called); - error = EIO; /* is there better errno? */ + "%s: if_output recursively called too many times(%d)\n", + if_name(ifp), count); + return (EIO); + } + mtag = m_tag_alloc(MTAG_GIF, 0, sizeof(struct ifnet *), M_NOWAIT); + if (mtag == NULL) + return (ENOMEM); + *(struct ifnet **)(mtag + 1) = ifp; + m_tag_prepend(m, mtag); + return (0); +} + +int +gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, + struct route *ro) +{ + uint32_t af; + int error = 0; +#ifdef MAC + error = mac_ifnet_check_transmit(ifp, m); + if (error) goto err; - } - mtag = m_tag_alloc(MTAG_GIF, MTAG_GIF_CALLED, sizeof(struct ifnet *), - M_NOWAIT); - if (mtag == NULL) { - error = ENOMEM; +#endif + if ((ifp->if_flags & IFF_MONITOR) != 0 || + (ifp->if_flags & IFF_UP) == 0) { + error = ENETDOWN; goto err; } - *(struct ifnet **)(mtag + 1) = ifp; - m_tag_prepend(m, mtag); + error = gif_check_nesting(ifp, m); + if (error != 0) + goto err; m->m_flags &= ~(M_BCAST|M_MCAST); if (dst->sa_family == AF_UNSPEC) bcopy(dst->sa_data, &af, sizeof(af)); Modified: head/sys/net/if_gif.h ============================================================================== --- head/sys/net/if_gif.h Sat Jan 10 01:05:12 2015 (r276900) +++ head/sys/net/if_gif.h Sat Jan 10 03:13:16 2015 (r276901) @@ -90,9 +90,6 @@ struct gif_softc { #define GIF_MTU_MIN (1280) /* Minimum MTU */ #define GIF_MTU_MAX (8192) /* Maximum MTU */ -#define MTAG_GIF 1080679712 -#define MTAG_GIF_CALLED 0 - struct etherip_header { #if BYTE_ORDER == LITTLE_ENDIAN u_int eip_resvl:4, /* reserved */