summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-08-07 17:54:07 +0200
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:13:44 -0400
commit5ba63533bbf653631faab60f6988506160ec6ba4 (patch)
tree8d9ef2670cd3b2f50fe3581820fba5aca365634d /net
parentad5351db89681515681c5d5659ddf4c69e3cc6f5 (diff)
cfg80211: fix alignment problem in scan request
The memory layout for scan requests was rather wrong, we put the scan SSIDs before the channels which could lead to the channel pointers being unaligned in memory. It turns out that using a pointer to the channel array isn't necessary anyway since we can embed a zero-length array into the struct. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c16
-rw-r--r--net/mac80211/scan.c10
-rw-r--r--net/wireless/nl80211.c3
-rw-r--r--net/wireless/scan.c4
-rw-r--r--net/wireless/sme.c3
6 files changed, 18 insertions, 20 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 99433222bc5..d6bd7dd7796 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -715,7 +715,7 @@ struct ieee80211_local {
struct mutex scan_mtx;
unsigned long scanning;
struct cfg80211_ssid scan_ssid;
- struct cfg80211_scan_request int_scan_req;
+ struct cfg80211_scan_request *int_scan_req;
struct cfg80211_scan_request *scan_req;
struct ieee80211_channel *scan_channel;
const u8 *orig_ies;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0c4f8e122ed..b03fd84777f 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -765,9 +765,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
supp_ht = supp_ht || sband->ht_cap.ht_supported;
}
- local->int_scan_req.n_channels = channels;
- local->int_scan_req.channels = kzalloc(sizeof(void *) * channels, GFP_KERNEL);
- if (!local->int_scan_req.channels)
+ local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) +
+ sizeof(void *) * channels, GFP_KERNEL);
+ if (!local->int_scan_req)
return -ENOMEM;
/* if low-level driver supports AP, we also support VLAN */
@@ -882,13 +882,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
/* alloc internal scan request */
i = 0;
- local->int_scan_req.ssids = &local->scan_ssid;
- local->int_scan_req.n_ssids = 1;
+ local->int_scan_req->ssids = &local->scan_ssid;
+ local->int_scan_req->n_ssids = 1;
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
if (!hw->wiphy->bands[band])
continue;
for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) {
- local->int_scan_req.channels[i] =
+ local->int_scan_req->channels[i] =
&hw->wiphy->bands[band]->channels[j];
i++;
}
@@ -920,7 +920,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
fail_workqueue:
wiphy_unregister(local->hw.wiphy);
fail_wiphy_register:
- kfree(local->int_scan_req.channels);
+ kfree(local->int_scan_req->channels);
return result;
}
EXPORT_SYMBOL(ieee80211_register_hw);
@@ -962,7 +962,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
wiphy_unregister(local->hw.wiphy);
ieee80211_wep_free(local);
ieee80211_led_exit(local);
- kfree(local->int_scan_req.channels);
+ kfree(local->int_scan_req);
}
EXPORT_SYMBOL(ieee80211_unregister_hw);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 244f53f3c8b..e091cbc3434 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -277,7 +277,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
if (test_bit(SCAN_HW_SCANNING, &local->scanning))
ieee80211_restore_scan_ies(local);
- if (local->scan_req != &local->int_scan_req)
+ if (local->scan_req != local->int_scan_req)
cfg80211_scan_done(local->scan_req, aborted);
local->scan_req = NULL;
@@ -423,7 +423,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
local->scan_req = req;
local->scan_sdata = sdata;
- if (req != &local->int_scan_req &&
+ if (req != local->int_scan_req &&
sdata->vif.type == NL80211_IFTYPE_STATION &&
!list_empty(&ifmgd->work_list)) {
/* actually wait for the work it's doing to finish/time out */
@@ -743,10 +743,10 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
if (local->scan_req)
goto unlock;
- memcpy(local->int_scan_req.ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
- local->int_scan_req.ssids[0].ssid_len = ssid_len;
+ memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
+ local->int_scan_req->ssids[0].ssid_len = ssid_len;
- ret = __ieee80211_start_scan(sdata, &sdata->local->int_scan_req);
+ ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
unlock:
mutex_unlock(&local->scan_mtx);
return ret;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b3d5c1df08d..667a87d307d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3002,10 +3002,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
goto out;
}
- request->channels = (void *)((char *)request + sizeof(*request));
request->n_channels = n_channels;
if (n_ssids)
- request->ssids = (void *)(request->channels + n_channels);
+ request->ssids = (void *)&request->channels[n_channels];
request->n_ssids = n_ssids;
if (ie_len) {
if (request->ssids)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 1bcb1312bd9..e6c1f11595d 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -612,8 +612,8 @@ int cfg80211_wext_siwscan(struct net_device *dev,
creq->wiphy = wiphy;
creq->dev = dev;
- creq->ssids = (void *)(creq + 1);
- creq->channels = (void *)(creq->ssids + 1);
+ /* SSIDs come after channels */
+ creq->ssids = (void *)&creq->channels[n_channels];
creq->n_channels = n_channels;
creq->n_ssids = 1;
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 104b33e34d2..8e2ef54ea71 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -65,7 +65,6 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
if (!request)
return -ENOMEM;
- request->channels = (void *)((char *)request + sizeof(*request));
if (wdev->conn->params.channel)
request->channels[0] = wdev->conn->params.channel;
else {
@@ -82,7 +81,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
}
}
request->n_channels = n_channels;
- request->ssids = (void *)(request->channels + n_channels);
+ request->ssids = (void *)&request->channels[n_channels];
request->n_ssids = 1;
memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,