From f7d38a13a85b74dcedfe3957889edd40ece4cc2f Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 19 Jul 2020 15:16:27 +0000 Subject: [PATCH] [net80211] Add new privileges; restrict what can be done in a jail. Split the MANAGE privilege into MANAGE, SETMAC and CREATE_VAP. + VAP_MANAGE is everything but setting the MAC and creating a VAP. + VAP_SETMAC is setting the MAC address of the VAP. Typically you wouldn't want the jail to be able to modify this. + CREATE_VAP is to create a new VAP. Again, you don't want to be doing this in a jail, but this DOES stop being able to run some corner cases like Dynamic WDS (DWDS) AP in a jail/vnet. We can figure this bit out later. This allows me to run wpa_supplicant in a jail after transferring a STA VAP into it. I unfortunately can't currently set the wlan debugging inside the jail; that would be super useful! Reviewed by: bz Differential Revision: https://reviews.freebsd.org/D25630 --- sys/kern/kern_jail.c | 6 ++---- sys/net80211/ieee80211_freebsd.c | 5 +++++ sys/net80211/ieee80211_ioctl.c | 15 ++++++++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index e09a2b66c64d..81000783265e 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -3107,10 +3107,8 @@ prison_priv_check(struct ucred *cred, int priv) /* * 802.11-related privileges. */ - case PRIV_NET80211_GETKEY: -#ifdef notyet - case PRIV_NET80211_MANAGE: /* XXX-BZ discuss with sam@ */ -#endif + case PRIV_NET80211_VAP_GETKEY: + case PRIV_NET80211_VAP_MANAGE: #ifdef notyet /* diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index 6b55357dd49f..c9afb8b5177a 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -82,6 +83,10 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params) struct ieee80211com *ic; int error; + error = priv_check(curthread, PRIV_NET80211_CREATE_VAP); + if (error) + return error; + error = copyin(params, &cp, sizeof(cp)); if (error) return error; diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index 0eed8667460e..0c3794f62669 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -106,7 +106,8 @@ ieee80211_ioctl_getkey(struct ieee80211vap *vap, struct ieee80211req *ireq) ik.ik_flags = wk->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV); if (wk->wk_keyix == vap->iv_def_txkey) ik.ik_flags |= IEEE80211_KEY_DEFAULT; - if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { + /* XXX TODO: move priv check to ieee80211_freebsd.c */ + if (priv_check(curthread, PRIV_NET80211_VAP_GETKEY) == 0) { /* NB: only root can read key data */ ik.ik_keyrsc = wk->wk_keyrsc[IEEE80211_NONQOS_TID]; ik.ik_keytsc = wk->wk_keytsc; @@ -815,7 +816,8 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd, return EINVAL; len = (u_int) vap->iv_nw_keys[kid].wk_keylen; /* NB: only root can read WEP keys */ - if (priv_check(curthread, PRIV_NET80211_GETKEY) == 0) { + /* XXX TODO: move priv check to ieee80211_freebsd.c */ + if (priv_check(curthread, PRIV_NET80211_VAP_GETKEY) == 0) { bcopy(vap->iv_nw_keys[kid].wk_key, tmpkey, len); } else { bzero(tmpkey, len); @@ -3636,7 +3638,8 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) (struct ieee80211req *) data); break; case SIOCS80211: - error = priv_check(curthread, PRIV_NET80211_MANAGE); + /* XXX TODO: move priv check to ieee80211_freebsd.c */ + error = priv_check(curthread, PRIV_NET80211_VAP_MANAGE); if (error == 0) error = ieee80211_ioctl_set80211(vap, cmd, (struct ieee80211req *) data); @@ -3681,6 +3684,12 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } break; + case SIOCSIFLLADDR: + /* XXX TODO: move priv check to ieee80211_freebsd.c */ + error = priv_check(curthread, PRIV_NET80211_VAP_SETMAC); + if (error == 0) + break; + /* Fallthrough */ default: /* * Pass unknown ioctls first to the driver, and if it