mac80211: fix HT information element parsing
authorJohannes Berg <johannes@sipsolutions.net>
Tue, 7 Oct 2008 17:31:17 +0000 (19:31 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 15 Oct 2008 00:47:15 +0000 (20:47 -0400)
There's no checking that the HT IEs are of the right length
which can be used by an attacker to cause an out-of-bounds
access by sending a too short HT information/capability IE.
Fix it by simply pretending those IEs didn't exist when too
short.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/util.c

index 8025b294588bc0e1c44b61bfb465085cb0184c84..156e42a003ae77ac38e77aa1e047d58575e87eec 100644 (file)
@@ -816,8 +816,8 @@ struct ieee802_11_elems {
        u8 *ext_supp_rates;
        u8 *wmm_info;
        u8 *wmm_param;
-       u8 *ht_cap_elem;
-       u8 *ht_info_elem;
+       struct ieee80211_ht_cap *ht_cap_elem;
+       struct ieee80211_ht_addt_info *ht_info_elem;
        u8 *mesh_config;
        u8 *mesh_id;
        u8 *peer_link;
@@ -844,8 +844,6 @@ struct ieee802_11_elems {
        u8 ext_supp_rates_len;
        u8 wmm_info_len;
        u8 wmm_param_len;
-       u8 ht_cap_elem_len;
-       u8 ht_info_elem_len;
        u8 mesh_config_len;
        u8 mesh_id_len;
        u8 peer_link_len;
index 49f86fa56bff396adfc99daf8c921be3517a8cfb..87665d7bb4f9aa0bad666295914edca3dfefa701 100644 (file)
@@ -1348,10 +1348,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
            (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
                struct ieee80211_ht_bss_info bss_info;
                ieee80211_ht_cap_ie_to_ht_info(
-                               (struct ieee80211_ht_cap *)
                                elems.ht_cap_elem, &sta->sta.ht_info);
                ieee80211_ht_addt_info_ie_to_ht_bss_info(
-                               (struct ieee80211_ht_addt_info *)
                                elems.ht_info_elem, &bss_info);
                ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
        }
@@ -1709,7 +1707,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                struct ieee80211_ht_bss_info bss_info;
 
                ieee80211_ht_addt_info_ie_to_ht_bss_info(
-                               (struct ieee80211_ht_addt_info *)
                                elems.ht_info_elem, &bss_info);
                changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
                                               &bss_info);
index f32561ec224ca4fb1ec6a83a53d0b59dc7d63451..cee4884b9d06215f86b73630362fae1f9ab87168 100644 (file)
@@ -529,12 +529,12 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
                        elems->ext_supp_rates_len = elen;
                        break;
                case WLAN_EID_HT_CAPABILITY:
-                       elems->ht_cap_elem = pos;
-                       elems->ht_cap_elem_len = elen;
+                       if (elen >= sizeof(struct ieee80211_ht_cap))
+                               elems->ht_cap_elem = (void *)pos;
                        break;
                case WLAN_EID_HT_EXTRA_INFO:
-                       elems->ht_info_elem = pos;
-                       elems->ht_info_elem_len = elen;
+                       if (elen >= sizeof(struct ieee80211_ht_addt_info))
+                               elems->ht_info_elem = (void *)pos;
                        break;
                case WLAN_EID_MESH_ID:
                        elems->mesh_id = pos;