Skip to content

Commit 1afe4a6

Browse files
committed
Merge tag 'wireless-2024-06-14' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless
Johannes Berg says: ==================== Various fixes: * cfg80211: wext scan * mac80211: monitor regression, scan counted_by, offload * iwlwifi: locking, 6 GHz scan, remain-on-channel * tag 'wireless-2024-06-14' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: wifi: mac80211: fix monitor channel with chanctx emulation wifi: mac80211: Avoid address calculations via out of bounds array indexing wifi: mac80211: Recalc offload when monitor stop wifi: iwlwifi: scan: correctly check if PSC listen period is needed wifi: iwlwifi: mvm: fix ROC version check wifi: iwlwifi: mvm: unlock mvm mutex wifi: cfg80211: wext: add extra SIOCSIWSCAN data check wifi: cfg80211: wext: set ssids=NULL for passive scans ==================== Link: https://lore.kernel.org/r/20240614085710.24103-3-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 89aa361 + 0d9c2be commit 1afe4a6

File tree

8 files changed

+50
-26
lines changed

8 files changed

+50
-26
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4795,7 +4795,7 @@ static int iwl_mvm_roc_station(struct iwl_mvm *mvm,
47954795

47964796
if (fw_ver == IWL_FW_CMD_VER_UNKNOWN) {
47974797
ret = iwl_mvm_send_aux_roc_cmd(mvm, channel, vif, duration);
4798-
} else if (fw_ver == 3) {
4798+
} else if (fw_ver >= 3) {
47994799
ret = iwl_mvm_roc_add_cmd(mvm, channel, vif, duration,
48004800
ROC_ACTIVITY_HOTSPOT);
48014801
} else {

drivers/net/wireless/intel/iwlwifi/mvm/scan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1830,7 +1830,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
18301830
*/
18311831
if (!iwl_mvm_is_scan_fragmented(params->type)) {
18321832
if (!cfg80211_channel_is_psc(params->channels[i]) ||
1833-
flags & IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN) {
1833+
psc_no_listen) {
18341834
if (unsolicited_probe_on_chan) {
18351835
max_s_ssids = 2;
18361836
max_bssids = 6;

drivers/net/wireless/intel/iwlwifi/mvm/time-event.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
12381238
if (te_data->id >= SESSION_PROTECT_CONF_MAX_ID) {
12391239
IWL_DEBUG_TE(mvm,
12401240
"No remain on channel event\n");
1241+
mutex_unlock(&mvm->mutex);
12411242
return;
12421243
}
12431244

@@ -1253,6 +1254,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
12531254
te_data = iwl_mvm_get_roc_te(mvm);
12541255
if (!te_data) {
12551256
IWL_WARN(mvm, "No remain on channel event\n");
1257+
mutex_unlock(&mvm->mutex);
12561258
return;
12571259
}
12581260

net/mac80211/driver-ops.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,18 @@ int drv_assign_vif_chanctx(struct ieee80211_local *local,
311311
might_sleep();
312312
lockdep_assert_wiphy(local->hw.wiphy);
313313

314+
/*
315+
* We should perhaps push emulate chanctx down and only
316+
* make it call ->config() when the chanctx is actually
317+
* assigned here (and unassigned below), but that's yet
318+
* another change to all drivers to add assign/unassign
319+
* emulation callbacks. Maybe later.
320+
*/
321+
if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
322+
local->emulate_chanctx &&
323+
!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
324+
return 0;
325+
314326
if (!check_sdata_in_driver(sdata))
315327
return -EIO;
316328

@@ -338,6 +350,11 @@ void drv_unassign_vif_chanctx(struct ieee80211_local *local,
338350
might_sleep();
339351
lockdep_assert_wiphy(local->hw.wiphy);
340352

353+
if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
354+
local->emulate_chanctx &&
355+
!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
356+
return;
357+
341358
if (!check_sdata_in_driver(sdata))
342359
return;
343360

net/mac80211/iface.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
686686
ieee80211_del_virtual_monitor(local);
687687

688688
ieee80211_recalc_idle(local);
689+
ieee80211_recalc_offload(local);
689690

690691
if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
691692
break;
@@ -1121,9 +1122,6 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
11211122
struct ieee80211_sub_if_data *sdata;
11221123
int ret;
11231124

1124-
if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
1125-
return 0;
1126-
11271125
ASSERT_RTNL();
11281126
lockdep_assert_wiphy(local->hw.wiphy);
11291127

@@ -1145,11 +1143,13 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
11451143

11461144
ieee80211_set_default_queues(sdata);
11471145

1148-
ret = drv_add_interface(local, sdata);
1149-
if (WARN_ON(ret)) {
1150-
/* ok .. stupid driver, it asked for this! */
1151-
kfree(sdata);
1152-
return ret;
1146+
if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
1147+
ret = drv_add_interface(local, sdata);
1148+
if (WARN_ON(ret)) {
1149+
/* ok .. stupid driver, it asked for this! */
1150+
kfree(sdata);
1151+
return ret;
1152+
}
11531153
}
11541154

11551155
set_bit(SDATA_STATE_RUNNING, &sdata->state);
@@ -1187,9 +1187,6 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
11871187
{
11881188
struct ieee80211_sub_if_data *sdata;
11891189

1190-
if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
1191-
return;
1192-
11931190
ASSERT_RTNL();
11941191
lockdep_assert_wiphy(local->hw.wiphy);
11951192

@@ -1209,7 +1206,8 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
12091206

12101207
ieee80211_link_release_channel(&sdata->deflink);
12111208

1212-
drv_remove_interface(local, sdata);
1209+
if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
1210+
drv_remove_interface(local, sdata);
12131211

12141212
kfree(sdata);
12151213
}

net/mac80211/scan.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_sub_if_data *sdata)
358358
struct cfg80211_scan_request *req;
359359
struct cfg80211_chan_def chandef;
360360
u8 bands_used = 0;
361-
int i, ielen, n_chans;
361+
int i, ielen;
362+
u32 *n_chans;
362363
u32 flags = 0;
363364

364365
req = rcu_dereference_protected(local->scan_req,
@@ -368,34 +369,34 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_sub_if_data *sdata)
368369
return false;
369370

370371
if (ieee80211_hw_check(&local->hw, SINGLE_SCAN_ON_ALL_BANDS)) {
372+
local->hw_scan_req->req.n_channels = req->n_channels;
373+
371374
for (i = 0; i < req->n_channels; i++) {
372375
local->hw_scan_req->req.channels[i] = req->channels[i];
373376
bands_used |= BIT(req->channels[i]->band);
374377
}
375-
376-
n_chans = req->n_channels;
377378
} else {
378379
do {
379380
if (local->hw_scan_band == NUM_NL80211_BANDS)
380381
return false;
381382

382-
n_chans = 0;
383+
n_chans = &local->hw_scan_req->req.n_channels;
384+
*n_chans = 0;
383385

384386
for (i = 0; i < req->n_channels; i++) {
385387
if (req->channels[i]->band !=
386388
local->hw_scan_band)
387389
continue;
388-
local->hw_scan_req->req.channels[n_chans] =
390+
local->hw_scan_req->req.channels[(*n_chans)++] =
389391
req->channels[i];
390-
n_chans++;
392+
391393
bands_used |= BIT(req->channels[i]->band);
392394
}
393395

394396
local->hw_scan_band++;
395-
} while (!n_chans);
397+
} while (!*n_chans);
396398
}
397399

398-
local->hw_scan_req->req.n_channels = n_chans;
399400
ieee80211_prepare_scan_chandef(&chandef);
400401

401402
if (req->flags & NL80211_SCAN_FLAG_MIN_PREQ_CONTENT)

net/mac80211/util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1843,7 +1843,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
18431843

18441844
/* add interfaces */
18451845
sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata);
1846-
if (sdata) {
1846+
if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
18471847
/* in HW restart it exists already */
18481848
WARN_ON(local->resuming);
18491849
res = drv_add_interface(local, sdata);

net/wireless/scan.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3416,10 +3416,14 @@ int cfg80211_wext_siwscan(struct net_device *dev,
34163416
wiphy = &rdev->wiphy;
34173417

34183418
/* Determine number of channels, needed to allocate creq */
3419-
if (wreq && wreq->num_channels)
3419+
if (wreq && wreq->num_channels) {
3420+
/* Passed from userspace so should be checked */
3421+
if (unlikely(wreq->num_channels > IW_MAX_FREQUENCIES))
3422+
return -EINVAL;
34203423
n_channels = wreq->num_channels;
3421-
else
3424+
} else {
34223425
n_channels = ieee80211_get_num_supported_channels(wiphy);
3426+
}
34233427

34243428
creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
34253429
n_channels * sizeof(void *),
@@ -3493,8 +3497,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
34933497
memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
34943498
creq->ssids[0].ssid_len = wreq->essid_len;
34953499
}
3496-
if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
3500+
if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE) {
3501+
creq->ssids = NULL;
34973502
creq->n_ssids = 0;
3503+
}
34983504
}
34993505

35003506
for (i = 0; i < NUM_NL80211_BANDS; i++)

0 commit comments

Comments
 (0)