Date: Thu, 19 Mar 2020 16:50:36 +0000 (UTC) From: Gordon Tetlow <gordon@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r359141 - in releng: 11.3/sys/net 12.1/sys/net Message-ID: <202003191650.02JGoapr024731@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gordon Date: Thu Mar 19 16:50:36 2020 New Revision: 359141 URL: https://svnweb.freebsd.org/changeset/base/359141 Log: Fix incorrect user-controlled pointer use in epair. Approved by: so Security: FreeBSD-SA-20:07.epair Security: CVE-2020-7452 Modified: releng/11.3/sys/net/if_clone.c releng/11.3/sys/net/if_clone.h releng/11.3/sys/net/if_epair.c releng/12.1/sys/net/if_clone.c releng/12.1/sys/net/if_clone.h releng/12.1/sys/net/if_epair.c Modified: releng/11.3/sys/net/if_clone.c ============================================================================== --- releng/11.3/sys/net/if_clone.c Thu Mar 19 16:49:32 2020 (r359140) +++ releng/11.3/sys/net/if_clone.c Thu Mar 19 16:50:36 2020 (r359141) @@ -208,6 +208,17 @@ 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_addgroup(ifp, ifc->ifc_name); + + IF_CLONE_LOCK(ifc); + IFC_IFLIST_INSERT(ifc, ifp); + IF_CLONE_UNLOCK(ifc); +} + /* * Create a clone network interface. */ @@ -230,11 +241,7 @@ if_clone_createif(struct if_clone *ifc, char *name, si if (ifp == NULL) panic("%s: lookup failed for %s", __func__, name); - 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: releng/11.3/sys/net/if_clone.h ============================================================================== --- releng/11.3/sys/net/if_clone.h Thu Mar 19 16:49:32 2020 (r359140) +++ releng/11.3/sys/net/if_clone.h Thu Mar 19 16:50:36 2020 (r359141) @@ -72,7 +72,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: releng/11.3/sys/net/if_epair.c ============================================================================== --- releng/11.3/sys/net/if_epair.c Thu Mar 19 16:49:32 2020 (r359140) +++ releng/11.3/sys/net/if_epair.c Thu Mar 19 16:50:36 2020 (r359141) @@ -704,6 +704,23 @@ 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; + /* Assign a hopefully unique, locally administered etheraddr. */ + eaddr[0] = 0x02; + eaddr[3] = (ifp->if_index >> 8) & 0xff; + eaddr[4] = ifp->if_index & 0xff; + 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) { @@ -713,26 +730,6 @@ epair_clone_create(struct if_clone *ifc, char *name, s int error, unit, wildcard; 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; - /* Assign a hopefully unique, locally administered etheraddr. */ - eaddr[0] = 0x02; - eaddr[3] = (ifp->if_index >> 8) & 0xff; - eaddr[4] = ifp->if_index & 0xff; - eaddr[5] = 0x0b; - ether_ifattach(ifp, eaddr); - /* Correctly set the name for the cloner list. */ - strlcpy(name, scb->ifp->if_xname, len); - return (0); - } - /* Try to see if a special unit was requested. */ error = ifc_name2unit(name, &unit); if (error != 0) @@ -860,10 +857,11 @@ epair_clone_create(struct if_clone *ifc, char *name, s ifp->if_snd.ifq_maxlen = ifqmaxlen; /* 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; Modified: releng/12.1/sys/net/if_clone.c ============================================================================== --- releng/12.1/sys/net/if_clone.c Thu Mar 19 16:49:32 2020 (r359140) +++ releng/12.1/sys/net/if_clone.c Thu Mar 19 16:50:36 2020 (r359141) @@ -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: releng/12.1/sys/net/if_clone.h ============================================================================== --- releng/12.1/sys/net/if_clone.h Thu Mar 19 16:49:32 2020 (r359140) +++ releng/12.1/sys/net/if_clone.h Thu Mar 19 16:50:36 2020 (r359141) @@ -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: releng/12.1/sys/net/if_epair.c ============================================================================== --- releng/12.1/sys/net/if_epair.c Thu Mar 19 16:49:32 2020 (r359140) +++ releng/12.1/sys/net/if_epair.c Thu Mar 19 16:50:36 2020 (r359141) @@ -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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202003191650.02JGoapr024731>