Ensure the SSID element is bounds-checked prior to invoking memcpy()
with its length field.

Cc: <[email protected]>
Cc: Johannes Berg <[email protected]>
Cc: Kees Cook <[email protected]>
Reported-by: Nicolas Waisman <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
---
 net/wireless/wext-sme.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index c67d7a82ab13..3fd2cc7fc36a 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -201,6 +201,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
                               struct iw_request_info *info,
                               struct iw_point *data, char *ssid)
 {
+       int ret = 0;
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
        /* call only for station! */
@@ -219,7 +220,10 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
                if (ie) {
                        data->flags = 1;
                        data->length = ie[1];
-                       memcpy(ssid, ie + 2, data->length);
+                       if (data->length > IW_ESSID_MAX_SIZE)
+                               ret = -EINVAL;
+                       else
+                               memcpy(ssid, ie + 2, data->length);
                }
                rcu_read_unlock();
        } else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) {
@@ -229,7 +233,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
        }
        wdev_unlock(wdev);
 
-       return 0;
+       return ret;
 }
 
 int cfg80211_mgd_wext_siwap(struct net_device *dev,
-- 
2.23.0.581.g78d2f28ef7-goog

Reply via email to