MFC r343837:

net80211(4): validate supplied roam:rate values from ifconfig(8)
This commit is contained in:
Andriy Voskoboinyk 2019-02-10 20:26:12 +00:00
parent 75988fabe0
commit 5009172724
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/stable/10/; revision=343973

View File

@ -2140,18 +2140,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)
{
@ -2176,6 +2164,69 @@ checkmcs(int mcs)
}
static __noinline 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_rateset *rs;
int changed, error, mode, is11n, nmodes;
if (ireq->i_len != sizeof(vap->iv_roamparms))
return EINVAL;
parms = malloc(sizeof(*parms), M_TEMP, M_NOWAIT | 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 */
is11n = (mode == IEEE80211_MODE_11NA ||
mode == IEEE80211_MODE_11NG);
if (src->rate != dst->rate) {
if (!checkrate(rs, src->rate) &&
(!is11n || !checkmcs(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: free(parms, M_TEMP);
return error;
}
static int
ieee80211_ioctl_settxparams(struct ieee80211vap *vap,
const struct ieee80211req *ireq)
{