svn commit: r343036 - stable/10/sys/net80211
Andriy Voskoboinyk
avos at FreeBSD.org
Tue Jan 15 02:26:05 UTC 2019
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;
More information about the svn-src-all
mailing list