an(4): Require privileges for all SIOCGAIRONET requests.

SIOCGAIRONET allows userspace to query an(4) for various device
properties and configuration, which appears to potentially include
sensitive information such as WEP keys (an(4) seems to predate WPA).

Also avoid races by copying in the request structure to a temporary
buffer before locking and modifying the device softc.

Reported by:	Ilja Van Sprundel <ivansprundel@ioactive.com>
MFC after:	3 days
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Mark Johnston 2019-12-17 21:34:38 +00:00
parent 00488f54de
commit a2c770294a

View File

@ -1875,6 +1875,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
int len;
int i, max;
struct an_softc *sc;
struct an_req *areq;
struct ifreq *ifr;
struct thread *td = curthread;
struct ieee80211req *ireq;
@ -1934,17 +1935,21 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
error = 0;
break;
case SIOCGAIRONET:
error = copyin(ifr_data_get_ptr(ifr), &sc->areq,
sizeof(sc->areq));
if (error != 0)
error = priv_check(td, PRIV_DRIVER);
if (error)
break;
areq = malloc(sizeof(*areq), M_TEMP, M_WAITOK);
error = copyin(ifr_data_get_ptr(ifr), areq, sizeof(*areq));
if (error != 0) {
free(areq, M_TEMP);
break;
}
AN_LOCK(sc);
memcpy(&sc->areq, areq, sizeof(sc->areq));
#ifdef ANCACHE
if (sc->areq.an_type == AN_RID_ZERO_CACHE) {
error = priv_check(td, PRIV_DRIVER);
if (error)
break;
sc->an_sigitems = sc->an_nextitem = 0;
free(areq, M_TEMP);
break;
} else if (sc->areq.an_type == AN_RID_READ_CACHE) {
char *pt = (char *)&sc->areq.an_val;
@ -1960,12 +1965,14 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
#endif
if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) {
AN_UNLOCK(sc);
free(areq, M_TEMP);
error = EINVAL;
break;
}
memcpy(areq, &sc->areq, sizeof(*areq));
AN_UNLOCK(sc);
error = copyout(&sc->areq, ifr_data_get_ptr(ifr),
sizeof(sc->areq));
error = copyout(areq, ifr_data_get_ptr(ifr), sizeof(*areq));
free(areq, M_TEMP);
break;
case SIOCSAIRONET:
if ((error = priv_check(td, PRIV_DRIVER)))