[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 12/32] cfg80211: Use mem_to_flex_dup() with struct cfg80211_bss_ies



As part of the work to perform bounds checking on all memcpy() uses,
replace the open-coded a deserialization of bytes out of memory into a
trailing flexible array by using a flex_array.h helper to perform the
allocation, bounds checking, and copying.

Cc: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>
Cc: "David S. Miller" <davem@xxxxxxxxxxxxx>
Cc: Jakub Kicinski <kuba@xxxxxxxxxx>
Cc: Paolo Abeni <pabeni@xxxxxxxxxx>
Cc: Eric Dumazet <edumazet@xxxxxxxxxx>
Cc: linux-wireless@xxxxxxxxxxxxxxx
Cc: netdev@xxxxxxxxxxxxxxx
Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx>
---
 include/net/cfg80211.h |  4 ++--
 net/wireless/scan.c    | 21 ++++++---------------
 2 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 68713388b617..fa236015f6ef 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2600,9 +2600,9 @@ struct cfg80211_inform_bss {
 struct cfg80211_bss_ies {
        u64 tsf;
        struct rcu_head rcu_head;
-       int len;
+       DECLARE_FLEX_ARRAY_ELEMENTS_COUNT(int, len);
        bool from_beacon;
-       u8 data[];
+       DECLARE_FLEX_ARRAY_ELEMENTS(u8, data);
 };
 
 /**
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 4a6d86432910..9f53d05c6aaa 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1932,7 +1932,7 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
                                gfp_t gfp)
 {
        struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
-       struct cfg80211_bss_ies *ies;
+       struct cfg80211_bss_ies *ies = NULL;
        struct ieee80211_channel *channel;
        struct cfg80211_internal_bss tmp = {}, *res;
        int bss_type;
@@ -1978,13 +1978,10 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
         * override the IEs pointer should we have received an earlier
         * indication of Probe Response data.
         */
-       ies = kzalloc(sizeof(*ies) + ielen, gfp);
-       if (!ies)
+       if (mem_to_flex_dup(&ies, ie, ielen, gfp))
                return NULL;
-       ies->len = ielen;
        ies->tsf = tsf;
        ies->from_beacon = false;
-       memcpy(ies->data, ie, ielen);
 
        switch (ftype) {
        case CFG80211_BSS_FTYPE_BEACON:
@@ -2277,7 +2274,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
        size_t ielen = len - offsetof(struct ieee80211_mgmt,
                                      u.probe_resp.variable);
        size_t new_ie_len;
-       struct cfg80211_bss_ies *new_ies;
+       struct cfg80211_bss_ies *new_ies = NULL;
        const struct cfg80211_bss_ies *old;
        u8 cpy_len;
 
@@ -2314,8 +2311,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
        if (!new_ie)
                return;
 
-       new_ies = kzalloc(sizeof(*new_ies) + new_ie_len, GFP_ATOMIC);
-       if (!new_ies)
+       if (mem_to_flex_dup(&new_ies, new_ie, new_ie_len, GFP_ATOMIC))
                goto out_free;
 
        pos = new_ie;
@@ -2333,10 +2329,8 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
        memcpy(pos, mbssid + cpy_len, ((ie + ielen) - (mbssid + cpy_len)));
 
        /* update ie */
-       new_ies->len = new_ie_len;
        new_ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
        new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control);
-       memcpy(new_ies->data, new_ie, new_ie_len);
        if (ieee80211_is_probe_resp(mgmt->frame_control)) {
                old = rcu_access_pointer(nontrans_bss->proberesp_ies);
                rcu_assign_pointer(nontrans_bss->proberesp_ies, new_ies);
@@ -2363,7 +2357,7 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
                                      gfp_t gfp)
 {
        struct cfg80211_internal_bss tmp = {}, *res;
-       struct cfg80211_bss_ies *ies;
+       struct cfg80211_bss_ies *ies = NULL;
        struct ieee80211_channel *channel;
        bool signal_valid;
        struct ieee80211_ext *ext = NULL;
@@ -2442,14 +2436,11 @@ cfg80211_inform_single_bss_frame_data(struct wiphy 
*wiphy,
                capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
        }
 
-       ies = kzalloc(sizeof(*ies) + ielen, gfp);
-       if (!ies)
+       if (mem_to_flex_dup(&ies, variable, ielen, gfp))
                return NULL;
-       ies->len = ielen;
        ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
        ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control) ||
                           ieee80211_is_s1g_beacon(mgmt->frame_control);
-       memcpy(ies->data, variable, ielen);
 
        if (ieee80211_is_probe_resp(mgmt->frame_control))
                rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
-- 
2.32.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.