diff options
author | Will Deacon <will@kernel.org> | 2019-10-04 05:51:32 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2019-10-04 08:04:08 -0400 |
commit | 4ac2813cc867ae563a1ba5a9414bfb554e5796fa (patch) | |
tree | ce2debc1c58aec090511a3df0ac5ad9b5ef33a37 | |
parent | 4152561f5da3fca92af7179dd538ea89e248f9d0 (diff) |
cfg80211: wext: avoid copying malformed SSIDs
Ensure the SSID element is bounds-checked prior to invoking memcpy()
with its length field, when copying to userspace.
Cc: <stable@vger.kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Reported-by: Nicolas Waisman <nico@semmle.com>
Signed-off-by: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20191004095132.15777-2-will@kernel.org
[adjust commit log a bit]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | net/wireless/wext-sme.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index c67d7a82ab13..73fd0eae08ca 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c | |||
@@ -202,6 +202,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, | |||
202 | struct iw_point *data, char *ssid) | 202 | struct iw_point *data, char *ssid) |
203 | { | 203 | { |
204 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 204 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
205 | int ret = 0; | ||
205 | 206 | ||
206 | /* call only for station! */ | 207 | /* call only for station! */ |
207 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) | 208 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) |
@@ -219,7 +220,10 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, | |||
219 | if (ie) { | 220 | if (ie) { |
220 | data->flags = 1; | 221 | data->flags = 1; |
221 | data->length = ie[1]; | 222 | data->length = ie[1]; |
222 | memcpy(ssid, ie + 2, data->length); | 223 | if (data->length > IW_ESSID_MAX_SIZE) |
224 | ret = -EINVAL; | ||
225 | else | ||
226 | memcpy(ssid, ie + 2, data->length); | ||
223 | } | 227 | } |
224 | rcu_read_unlock(); | 228 | rcu_read_unlock(); |
225 | } else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) { | 229 | } else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) { |
@@ -229,7 +233,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, | |||
229 | } | 233 | } |
230 | wdev_unlock(wdev); | 234 | wdev_unlock(wdev); |
231 | 235 | ||
232 | return 0; | 236 | return ret; |
233 | } | 237 | } |
234 | 238 | ||
235 | int cfg80211_mgd_wext_siwap(struct net_device *dev, | 239 | int cfg80211_mgd_wext_siwap(struct net_device *dev, |