diff options
author | Kristof Provost <kp@FreeBSD.org> | 2020-01-28 22:44:24 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2020-01-28 22:44:24 +0000 |
commit | b02fd8b79028c01715e168a25d0fd86ff09b9ce3 (patch) | |
tree | a3f9e28cc4cbb62a5f1c865afee56af7e6a99043 /sys/net/if_epair.c | |
parent | 1232c361394bdde30022a434d0e801fdbca0f4fb (diff) | |
download | src-b02fd8b79028c01715e168a25d0fd86ff09b9ce3.tar.gz src-b02fd8b79028c01715e168a25d0fd86ff09b9ce3.zip |
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 <ivansprundel@ioactive.com>
MFC after: 3 days
Notes
Notes:
svn path=/head/; revision=357233
Diffstat (limited to 'sys/net/if_epair.c')
-rw-r--r-- | sys/net/if_epair.c | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c index b28fe2b4bd30..376bdbe9117f 100644 --- a/sys/net/if_epair.c +++ b/sys/net/if_epair.c @@ -711,6 +711,21 @@ epair_clone_match(struct if_clone *ifc, const char *name) 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, size_t len, caddr_t params) 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, size_t len, caddr_t params) 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; |