From owner-svn-src-head@freebsd.org Tue Jan 28 22:44:26 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 157FE2447BD; Tue, 28 Jan 2020 22:44:26 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 486hWF6KX8z3H0q; Tue, 28 Jan 2020 22:44:25 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id C142C25A7; Tue, 28 Jan 2020 22:44:25 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 00SMiP9Q077449; Tue, 28 Jan 2020 22:44:25 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 00SMiPrb077446; Tue, 28 Jan 2020 22:44:25 GMT (envelope-from kp@FreeBSD.org) Message-Id: <202001282244.00SMiPrb077446@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Tue, 28 Jan 2020 22:44:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r357233 - head/sys/net X-SVN-Group: head X-SVN-Commit-Author: kp X-SVN-Commit-Paths: head/sys/net X-SVN-Commit-Revision: 357233 X-SVN-Commit-Repository: base 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.29 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: Tue, 28 Jan 2020 22:44:26 -0000 Author: kp Date: Tue Jan 28 22:44:24 2020 New Revision: 357233 URL: https://svnweb.freebsd.org/changeset/base/357233 Log: epair: Do not abuse params to register the second interface if_epair used the 'params' argument to pass a pointer to the b interface through if_clone_create(). This pointer can be controlled by userspace, which means it could be abused to trigger a panic. While this requires PRIV_NET_IFCREATE privileges those are assigned to vnet jails, which means that vnet jails could panic the system. Reported by: Ilja Van Sprundel MFC after: 3 days Modified: head/sys/net/if_clone.c head/sys/net/if_clone.h head/sys/net/if_epair.c Modified: head/sys/net/if_clone.c ============================================================================== --- head/sys/net/if_clone.c Tue Jan 28 21:46:59 2020 (r357232) +++ head/sys/net/if_clone.c Tue Jan 28 22:44:24 2020 (r357233) @@ -211,6 +211,18 @@ if_clone_create(char *name, size_t len, caddr_t params return (if_clone_createif(ifc, name, len, params)); } +void +if_clone_addif(struct if_clone *ifc, struct ifnet *ifp) +{ + + if ((ifc->ifc_flags & IFC_NOGROUP) == 0) + if_addgroup(ifp, ifc->ifc_name); + + IF_CLONE_LOCK(ifc); + IFC_IFLIST_INSERT(ifc, ifp); + IF_CLONE_UNLOCK(ifc); +} + /* * Create a clone network interface. */ @@ -233,12 +245,7 @@ if_clone_createif(struct if_clone *ifc, char *name, si if (ifp == NULL) panic("%s: lookup failed for %s", __func__, name); - if ((ifc->ifc_flags & IFC_NOGROUP) == 0) - if_addgroup(ifp, ifc->ifc_name); - - IF_CLONE_LOCK(ifc); - IFC_IFLIST_INSERT(ifc, ifp); - IF_CLONE_UNLOCK(ifc); + if_clone_addif(ifc, ifp); } return (err); Modified: head/sys/net/if_clone.h ============================================================================== --- head/sys/net/if_clone.h Tue Jan 28 21:46:59 2020 (r357232) +++ head/sys/net/if_clone.h Tue Jan 28 22:44:24 2020 (r357233) @@ -79,7 +79,8 @@ int if_clone_list(struct if_clonereq *); struct if_clone *if_clone_findifc(struct ifnet *); void if_clone_addgroup(struct ifnet *, struct if_clone *); -/* The below interface used only by epair(4). */ +/* The below interfaces are used only by epair(4). */ +void if_clone_addif(struct if_clone *, struct ifnet *); int if_clone_destroyif(struct if_clone *, struct ifnet *); #endif /* _KERNEL */ Modified: head/sys/net/if_epair.c ============================================================================== --- head/sys/net/if_epair.c Tue Jan 28 21:46:59 2020 (r357232) +++ head/sys/net/if_epair.c Tue Jan 28 22:44:24 2020 (r357233) @@ -711,6 +711,21 @@ epair_clone_match(struct if_clone *ifc, const char *na return (1); } +static void +epair_clone_add(struct if_clone *ifc, struct epair_softc *scb) +{ + struct ifnet *ifp; + uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */ + + ifp = scb->ifp; + /* Copy epairNa etheraddr and change the last byte. */ + memcpy(eaddr, scb->oifp->if_hw_addr, ETHER_ADDR_LEN); + eaddr[5] = 0x0b; + ether_ifattach(ifp, eaddr); + + if_clone_addif(ifc, ifp); +} + static int epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) { @@ -723,24 +738,6 @@ epair_clone_create(struct if_clone *ifc, char *name, s uint32_t hash; uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */ - /* - * We are abusing params to create our second interface. - * Actually we already created it and called if_clone_create() - * for it to do the official insertion procedure the moment we knew - * it cannot fail anymore. So just do attach it here. - */ - if (params) { - scb = (struct epair_softc *)params; - ifp = scb->ifp; - /* Copy epairNa etheraddr and change the last byte. */ - memcpy(eaddr, scb->oifp->if_hw_addr, ETHER_ADDR_LEN); - eaddr[5] = 0x0b; - ether_ifattach(ifp, eaddr); - /* Correctly set the name for the cloner list. */ - strlcpy(name, ifp->if_xname, len); - return (0); - } - /* Try to see if a special unit was requested. */ error = ifc_name2unit(name, &unit); if (error != 0) @@ -891,10 +888,11 @@ epair_clone_create(struct if_clone *ifc, char *name, s if_setsendqready(ifp); /* We need to play some tricks here for the second interface. */ strlcpy(name, epairname, len); - error = if_clone_create(name, len, (caddr_t)scb); - if (error) - panic("%s: if_clone_create() for our 2nd iface failed: %d", - __func__, error); + + /* Correctly set the name for the cloner list. */ + strlcpy(name, scb->ifp->if_xname, len); + epair_clone_add(ifc, scb); + scb->if_qflush = ifp->if_qflush; ifp->if_qflush = epair_qflush; ifp->if_transmit = epair_transmit;