Date: Tue, 15 Jan 2019 02:26:03 +0000 (UTC) From: Andriy Voskoboinyk <avos@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r343036 - stable/10/sys/net80211 Message-ID: <201901150226.x0F2Q3lQ068936@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avos Date: Tue Jan 15 02:26:03 2019 New Revision: 343036 URL: https://svnweb.freebsd.org/changeset/base/343036 Log: MFC r342966: net80211: fix possible panic for some drivers after r342465 Check if rate control structures were allocated before trying to access them in various places; this was possible before on allocation failure (unlikely), but was revealed after r342211 where allocation was deferred. The patch was adjusted a bit since file contents are different enough since r306591. Also, 'rate_stats' sysctl is not available here, so the panic is unlikely to happen here even without this patch. Modified: stable/10/sys/net80211/ieee80211_amrr.c stable/10/sys/net80211/ieee80211_rssadapt.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/net80211/ieee80211_amrr.c ============================================================================== --- stable/10/sys/net80211/ieee80211_amrr.c Tue Jan 15 02:16:23 2019 (r343035) +++ stable/10/sys/net80211/ieee80211_amrr.c Tue Jan 15 02:26:03 2019 (r343036) @@ -98,6 +98,9 @@ amrr_setinterval(const struct ieee80211vap *vap, int m struct ieee80211_amrr *amrr = vap->iv_rs; int t; + if (!amrr) + return; + if (msecs < 100) msecs = 100; t = msecs_to_ticks(msecs); @@ -152,6 +155,12 @@ amrr_node_init(struct ieee80211_node *ni) struct ieee80211_amrr_node *amn; uint8_t rate; + if (!amrr) { + if_printf(vap->iv_ifp, "ratectl structure was not allocated, " + "per-node structure allocation skipped\n"); + return; + } + if (ni->ni_rctls == NULL) { ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node), M_80211_RATECTL, M_NOWAIT|M_ZERO); @@ -303,10 +312,19 @@ static int amrr_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused) { struct ieee80211_amrr_node *amn = ni->ni_rctls; - struct ieee80211_amrr *amrr = amn->amn_amrr; + struct ieee80211_amrr *amrr; const struct ieee80211_rateset *rs = NULL; int rix; + /* XXX should return -1 here, but drivers may not expect this... */ + if (!amn) + { + ni->ni_txrate = ni->ni_rates.rs_rates[0]; + return 0; + } + + amrr = amn->amn_amrr; + /* 11n or not? Pick the right rateset */ if (amrr_node_is_11n(ni)) { /* XXX ew */ @@ -346,6 +364,9 @@ amrr_tx_complete(const struct ieee80211vap *vap, struct ieee80211_amrr_node *amn = ni->ni_rctls; int retries = *(int *)arg1; + if (!amn) + return; + amn->amn_txcnt++; if (ok) amn->amn_success++; @@ -374,9 +395,12 @@ amrr_sysctl_interval(SYSCTL_HANDLER_ARGS) { struct ieee80211vap *vap = arg1; struct ieee80211_amrr *amrr = vap->iv_rs; - int msecs = ticks_to_msecs(amrr->amrr_interval); - int error; + int msecs, error; + if (!amrr) + return ENOMEM; + + msecs = ticks_to_msecs(amrr->amrr_interval); error = sysctl_handle_int(oidp, &msecs, 0, req); if (error || !req->newptr) return error; @@ -389,6 +413,9 @@ amrr_sysctlattach(struct ieee80211vap *vap, struct sysctl_ctx_list *ctx, struct sysctl_oid *tree) { struct ieee80211_amrr *amrr = vap->iv_rs; + + if (!amrr) + return; SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap, Modified: stable/10/sys/net80211/ieee80211_rssadapt.c ============================================================================== --- stable/10/sys/net80211/ieee80211_rssadapt.c Tue Jan 15 02:16:23 2019 (r343035) +++ stable/10/sys/net80211/ieee80211_rssadapt.c Tue Jan 15 02:26:03 2019 (r343036) @@ -114,6 +114,9 @@ rssadapt_setinterval(const struct ieee80211vap *vap, i struct ieee80211_rssadapt *rs = vap->iv_rs; int t; + if (!rs) + return; + if (msecs < 100) msecs = 100; t = msecs_to_ticks(msecs); @@ -172,6 +175,12 @@ rssadapt_node_init(struct ieee80211_node *ni) struct ieee80211_rssadapt *rsa = vap->iv_rs; const struct ieee80211_rateset *rs = &ni->ni_rates; + if (!rsa) { + if_printf(vap->iv_ifp, "ratectl structure was not allocated, " + "per-node structure allocation skipped\n"); + return; + } + if (ni->ni_rctls == NULL) { ni->ni_rctls = ra = malloc(sizeof(struct ieee80211_rssadapt_node), @@ -226,10 +235,18 @@ rssadapt_rate(struct ieee80211_node *ni, void *arg __u { struct ieee80211_rssadapt_node *ra = ni->ni_rctls; u_int pktlen = iarg; - const struct ieee80211_rateset *rs = &ra->ra_rates; + const struct ieee80211_rateset *rs; uint16_t (*thrs)[IEEE80211_RATE_SIZE]; int rix, rssi; + /* XXX should return -1 here, but drivers may not expect this... */ + if (!ra) + { + ni->ni_txrate = ni->ni_rates.rs_rates[0]; + return 0; + } + + rs = &ra->ra_rates; if ((ticks - ra->ra_ticks) > ra->ra_rs->interval) { rssadapt_updatestats(ra); ra->ra_ticks = ticks; @@ -315,6 +332,9 @@ rssadapt_tx_complete(const struct ieee80211vap *vap, struct ieee80211_rssadapt_node *ra = ni->ni_rctls; int pktlen = *(int *)arg1, rssi = *(int *)arg2; + if (!ra) + return; + if (success) { ra->ra_nok++; if ((ra->ra_rix + 1) < ra->ra_rates.rs_nrates && @@ -331,9 +351,12 @@ rssadapt_sysctl_interval(SYSCTL_HANDLER_ARGS) { struct ieee80211vap *vap = arg1; struct ieee80211_rssadapt *rs = vap->iv_rs; - int msecs = ticks_to_msecs(rs->interval); - int error; + int msecs, error; + if (!rs) + return ENOMEM; + + msecs = ticks_to_msecs(rs->interval); error = sysctl_handle_int(oidp, &msecs, 0, req); if (error || !req->newptr) return error;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201901150226.x0F2Q3lQ068936>