net80211(4): validate supplied roam:rate values from ifconfig(8)
MFC after: 4 days
This commit is contained in:
parent
64d41eddd7
commit
545619f3f2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=343837
@ -2203,18 +2203,6 @@ ieee80211_ioctl_setregdomain(struct ieee80211vap *vap,
|
||||
return (error == 0 ? ENETRESET : error);
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_ioctl_setroam(struct ieee80211vap *vap,
|
||||
const struct ieee80211req *ireq)
|
||||
{
|
||||
if (ireq->i_len != sizeof(vap->iv_roamparms))
|
||||
return EINVAL;
|
||||
/* XXX validate params */
|
||||
/* XXX? ENETRESET to push to device? */
|
||||
return copyin(ireq->i_data, vap->iv_roamparms,
|
||||
sizeof(vap->iv_roamparms));
|
||||
}
|
||||
|
||||
static int
|
||||
checkrate(const struct ieee80211_rateset *rs, int rate)
|
||||
{
|
||||
@ -2244,6 +2232,73 @@ checkmcs(const struct ieee80211_htrateset *rs, int mcs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_ioctl_setroam(struct ieee80211vap *vap,
|
||||
const struct ieee80211req *ireq)
|
||||
{
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
struct ieee80211_roamparams_req *parms;
|
||||
struct ieee80211_roamparam *src, *dst;
|
||||
const struct ieee80211_htrateset *rs_ht;
|
||||
const struct ieee80211_rateset *rs;
|
||||
int changed, error, mode, is11n, nmodes;
|
||||
|
||||
if (ireq->i_len != sizeof(vap->iv_roamparms))
|
||||
return EINVAL;
|
||||
|
||||
parms = IEEE80211_MALLOC(sizeof(*parms), M_TEMP,
|
||||
IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
|
||||
if (parms == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
error = copyin(ireq->i_data, parms, ireq->i_len);
|
||||
if (error != 0)
|
||||
goto fail;
|
||||
|
||||
changed = 0;
|
||||
nmodes = IEEE80211_MODE_MAX;
|
||||
|
||||
/* validate parameters and check if anything changed */
|
||||
for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) {
|
||||
if (isclr(ic->ic_modecaps, mode))
|
||||
continue;
|
||||
src = &parms->params[mode];
|
||||
dst = &vap->iv_roamparms[mode];
|
||||
rs = &ic->ic_sup_rates[mode]; /* NB: 11n maps to legacy */
|
||||
rs_ht = &ic->ic_sup_htrates;
|
||||
is11n = (mode == IEEE80211_MODE_11NA ||
|
||||
mode == IEEE80211_MODE_11NG);
|
||||
/* XXX TODO: 11ac */
|
||||
if (src->rate != dst->rate) {
|
||||
if (!checkrate(rs, src->rate) &&
|
||||
(!is11n || !checkmcs(rs_ht, src->rate))) {
|
||||
error = EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
changed++;
|
||||
}
|
||||
if (src->rssi != dst->rssi)
|
||||
changed++;
|
||||
}
|
||||
if (changed) {
|
||||
/*
|
||||
* Copy new parameters in place and notify the
|
||||
* driver so it can push state to the device.
|
||||
*/
|
||||
/* XXX locking? */
|
||||
for (mode = IEEE80211_MODE_11A; mode < nmodes; mode++) {
|
||||
if (isset(ic->ic_modecaps, mode))
|
||||
vap->iv_roamparms[mode] = parms->params[mode];
|
||||
}
|
||||
|
||||
if (vap->iv_roaming == IEEE80211_ROAMING_DEVICE)
|
||||
error = ERESTART;
|
||||
}
|
||||
|
||||
fail: IEEE80211_FREE(parms, M_TEMP);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_ioctl_settxparams(struct ieee80211vap *vap,
|
||||
const struct ieee80211req *ireq)
|
||||
|
Loading…
Reference in New Issue
Block a user