diff options
author | bluhm <bluhm@openbsd.org> | 2017-05-18 14:48:27 +0000 |
---|---|---|
committer | bluhm <bluhm@openbsd.org> | 2017-05-18 14:48:27 +0000 |
commit | 39f937bf2254af86ebedcb5397cd67572510b6b7 (patch) | |
tree | bc3b71fe8f90c50bdeb9719c9059381fc18a211e /sys/dev/usb/if_umb.c | |
parent | sync (diff) | |
download | wireguard-openbsd-39f937bf2254af86ebedcb5397cd67572510b6b7.tar.xz wireguard-openbsd-39f937bf2254af86ebedcb5397cd67572510b6b7.zip |
Grab the netlock in umb_state_task() and umb_decode_ip_configuration()
when calling in_ioctl(). These ioctls modify the routing table,
which is global. So they need the lock.
Found with Zaur Molotnikov's static lock analyzer.
OK gerhard@ mpi@
Diffstat (limited to 'sys/dev/usb/if_umb.c')
-rw-r--r-- | sys/dev/usb/if_umb.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/dev/usb/if_umb.c b/sys/dev/usb/if_umb.c index 2e09c6d54c3..a7843ab0375 100644 --- a/sys/dev/usb/if_umb.c +++ b/sys/dev/usb/if_umb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_umb.c,v 1.12 2017/05/03 15:32:31 gerhard Exp $ */ +/* $OpenBSD: if_umb.c,v 1.13 2017/05/18 14:48:27 bluhm Exp $ */ /* * Copyright (c) 2016 genua mbH @@ -949,7 +949,7 @@ umb_state_task(void *arg) struct ifnet *ifp = GET_IFP(sc); struct ifreq ifr; struct in_aliasreq ifra; - int s; + int s, ns; int state; s = splnet(); @@ -973,6 +973,7 @@ umb_state_task(void *arg) */ memset(sc->sc_info.ipv4dns, 0, sizeof (sc->sc_info.ipv4dns)); + NET_LOCK(ns); if (in_ioctl(SIOCGIFADDR, (caddr_t)&ifr, ifp, 1) == 0 && satosin(&ifr.ifr_addr)->sin_addr.s_addr != INADDR_ANY) { @@ -981,6 +982,7 @@ umb_state_task(void *arg) sizeof (ifra.ifra_addr)); in_ioctl(SIOCDIFADDR, (caddr_t)&ifra, ifp, 1); } + NET_UNLOCK(ns); } if_link_state_change(ifp); } @@ -1613,7 +1615,7 @@ umb_decode_ip_configuration(struct umb_softc *sc, void *data, int len) { struct mbim_cid_ip_configuration_info *ic = data; struct ifnet *ifp = GET_IFP(sc); - int s; + int s, ns; uint32_t avail; uint32_t val; int n, i; @@ -1667,7 +1669,10 @@ umb_decode_ip_configuration(struct umb_softc *sc, void *data, int len) sin->sin_len = sizeof (ifra.ifra_mask); in_len2mask(&sin->sin_addr, ipv4elem.prefixlen); - if ((rv = in_ioctl(SIOCAIFADDR, (caddr_t)&ifra, ifp, 1)) == 0) { + NET_LOCK(ns); + rv = in_ioctl(SIOCAIFADDR, (caddr_t)&ifra, ifp, 1); + NET_UNLOCK(ns); + if (rv == 0) { if (ifp->if_flags & IFF_DEBUG) log(LOG_INFO, "%s: IPv4 addr %s, mask %s, " "gateway %s\n", DEVNAM(ifp->if_softc), |