From 01e579408b2076c47112d4a568eff5d016fd4410 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sun, 18 Oct 2020 21:34:04 +0000 Subject: [PATCH] net80211: factor out the priv(9) checks into OS specifc code. Factor out the priv(9) checks into OS specifc code so other OSes can equally implement them. This sorts out those XXX in the net80211 code. We provide 3 arguments (cmd, vap, ifp) where available to the functions, in order to allow other OSes to use that data but also in case we'd add auditing to these check to have the information available. For now the arguments are marked __unused. PR: 249403 Reported by: martin(NetBSD) Reviewed by: adrian, martin(NetBSD) MFC after: 10 days Sponsored by: Rubicon Communications, LLC (d/b/a "Netgate") Differential Revision: https://reviews.freebsd.org/D26541 --- sys/net80211/ieee80211_freebsd.c | 38 +++++++++++++++++++++++++++++++- sys/net80211/ieee80211_freebsd.h | 13 +++++++++++ sys/net80211/ieee80211_ioctl.c | 18 ++++++--------- 3 files changed, 57 insertions(+), 12 deletions(-) diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index ed5362d7b446..850c93d1e5df 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -75,6 +75,42 @@ SYSCTL_INT(_net_wlan, OID_AUTO, debug, CTLFLAG_RW, &ieee80211_debug, static const char wlanname[] = "wlan"; static struct if_clone *wlan_cloner; +/* + * priv(9) NET80211 checks. + * Return 0 if operation is allowed, E* (usually EPERM) otherwise. + */ +int +ieee80211_priv_check_vap_getkey(u_long cmd __unused, + struct ieee80211vap *vap __unused, struct ifnet *ifp __unused) +{ + + return (priv_check(curthread, PRIV_NET80211_VAP_GETKEY)); +} + +int +ieee80211_priv_check_vap_manage(u_long cmd __unused, + struct ieee80211vap *vap __unused, struct ifnet *ifp __unused) +{ + + return (priv_check(curthread, PRIV_NET80211_VAP_MANAGE)); +} + +int +ieee80211_priv_check_vap_setmac(u_long cmd __unused, + struct ieee80211vap *vap __unused, struct ifnet *ifp __unused) +{ + + return (priv_check(curthread, PRIV_NET80211_VAP_SETMAC)); +} + +int +ieee80211_priv_check_create_vap(u_long cmd __unused, + struct ieee80211vap *vap __unused, struct ifnet *ifp __unused) +{ + + return (priv_check(curthread, PRIV_NET80211_CREATE_VAP)); +} + static int wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params) { @@ -83,7 +119,7 @@ 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); + error = ieee80211_priv_check_create_vap(0, NULL, NULL); if (error) return error; diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h index 71abe9099903..c3811cc32e84 100644 --- a/sys/net80211/ieee80211_freebsd.h +++ b/sys/net80211/ieee80211_freebsd.h @@ -42,6 +42,19 @@ #include +/* + * priv(9) NET80211 checks. + */ +struct ieee80211vap; +int ieee80211_priv_check_vap_getkey(u_long, struct ieee80211vap *, + struct ifnet *); +int ieee80211_priv_check_vap_manage(u_long, struct ieee80211vap *, + struct ifnet *); +int ieee80211_priv_check_vap_setmac(u_long, struct ieee80211vap *, + struct ifnet *); +int ieee80211_priv_check_create_vap(u_long, struct ieee80211vap *, + struct ifnet *); + /* * Common state locking definitions. */ diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index 3c27fff1b3b1..2fef9ac0084a 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -40,7 +40,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -72,7 +71,8 @@ static int ieee80211_scanreq(struct ieee80211vap *, struct ieee80211_scan_req *); static int -ieee80211_ioctl_getkey(struct ieee80211vap *vap, struct ieee80211req *ireq) +ieee80211_ioctl_getkey(u_long cmd, struct ieee80211vap *vap, + struct ieee80211req *ireq) { struct ieee80211com *ic = vap->iv_ic; struct ieee80211_node *ni; @@ -106,8 +106,7 @@ 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; - /* XXX TODO: move priv check to ieee80211_freebsd.c */ - if (priv_check(curthread, PRIV_NET80211_VAP_GETKEY) == 0) { + if (ieee80211_priv_check_vap_getkey(cmd, vap, NULL) == 0) { /* NB: only root can read key data */ ik.ik_keyrsc = wk->wk_keyrsc[IEEE80211_NONQOS_TID]; ik.ik_keytsc = wk->wk_keytsc; @@ -822,8 +821,7 @@ 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 */ - /* XXX TODO: move priv check to ieee80211_freebsd.c */ - if (priv_check(curthread, PRIV_NET80211_VAP_GETKEY) == 0) { + if (ieee80211_priv_check_vap_getkey(cmd, vap, NULL) == 0) { bcopy(vap->iv_nw_keys[kid].wk_key, tmpkey, len); } else { bzero(tmpkey, len); @@ -916,7 +914,7 @@ ieee80211_ioctl_get80211(struct ieee80211vap *vap, u_long cmd, ireq->i_val = (vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0; break; case IEEE80211_IOC_WPAKEY: - error = ieee80211_ioctl_getkey(vap, ireq); + error = ieee80211_ioctl_getkey(cmd, vap, ireq); break; case IEEE80211_IOC_CHANINFO: error = ieee80211_ioctl_getchaninfo(vap, ireq); @@ -3630,8 +3628,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) (struct ieee80211req *) data); break; case SIOCS80211: - /* XXX TODO: move priv check to ieee80211_freebsd.c */ - error = priv_check(curthread, PRIV_NET80211_VAP_MANAGE); + error = ieee80211_priv_check_vap_manage(cmd, vap, ifp); if (error == 0) error = ieee80211_ioctl_set80211(vap, cmd, (struct ieee80211req *) data); @@ -3677,8 +3674,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } break; case SIOCSIFLLADDR: - /* XXX TODO: move priv check to ieee80211_freebsd.c */ - error = priv_check(curthread, PRIV_NET80211_VAP_SETMAC); + error = ieee80211_priv_check_vap_setmac(cmd, vap, ifp); if (error == 0) break; /* Fallthrough */