Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp2347724ybz; Thu, 23 Apr 2020 16:29:50 -0700 (PDT) X-Google-Smtp-Source: APiQypIA7IRkRdAxRfGlHrVqonAZHVL/s5gpqUz49hFB43LSwN0NmPZo+ghaXSSduJ4td9Z4l2zV X-Received: by 2002:aa7:d689:: with SMTP id d9mr5096050edr.22.1587684589972; Thu, 23 Apr 2020 16:29:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587684589; cv=none; d=google.com; s=arc-20160816; b=U2wfhHmhQ8Od7XY3CdcJDpfvwWnW6AGwQG10VKQrVwebcCcxKC4gE6GfG6v6g4nJrD VWe9LuTfyGEa+npgmwKxGJsnETLyr8O0x9QhfHbfErs1NfJDGqiGTbNPVdoIWt7t67sp F391cGCP/bDekE3p9zUl6jXBfqrYiwGvYjRDaoL457Cn6LHO3a6DG+POOAtYXuA7WDFf z5X62pdQJ1wvZ9OV4pm6QWMT2nehT5rO8EYa3tlgovfAD8wcUVJwm8NG8muT0W7+vsLv T9gxaNv5qIZg5+9Vmp5GG5kyLzbQmDDysO7SpEOAISHiVUkXBB+zrhSOa2C/Nco8tM4a UU4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=S/JO7qbHqdAGVrmqwjukuxc4U9UDTVhrUOTx/8DRiWg=; b=o8VZHroGJOAQ6397P2dJ2i7CodnNnsNInzoceTlaC5B2IqO4ARvxVIfwlAMiTL7JsT j2wyQodWZRFMn/eBSNuUDtdHoUqoxJhOWh0aBLQ4+PfvdwaeIDyIs28pymJYMCCRX8eS 6E4FJIeXe4nhlhKT7JKaZkPYLQgnwV8P3twwFZF9pFUJ22zSf+SnJLoVUhJpqNse8qfQ lASFzHdSASDZvOQarEkHB2nQCxLI897rLoZzsyH1GjZ2IDF+APL2migzBmayCHoBhEqa tGqTTzfEbPK7HVRUc5drKZc5WxxDzh05j/6IMGsMWnCIFWqEjqZDlgoHrWigZtOuu7Vj TkyA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r18si2093780ejj.211.2020.04.23.16.29.27; Thu, 23 Apr 2020 16:29:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729703AbgDWX0L (ORCPT + 99 others); Thu, 23 Apr 2020 19:26:11 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:48128 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726632AbgDWXG0 (ORCPT ); Thu, 23 Apr 2020 19:06:26 -0400 Received: from [192.168.4.242] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1jRkvH-0004ZM-U9; Fri, 24 Apr 2020 00:06:24 +0100 Received: from ben by deadeye with local (Exim 4.93) (envelope-from ) id 1jRkvH-00E6ea-HE; Fri, 24 Apr 2020 00:06:23 +0100 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, Denis Kirjanov , "Kalle Valo" , "qize wang" Date: Fri, 24 Apr 2020 00:03:53 +0100 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) X-Patchwork-Hint: ignore Subject: [PATCH 3.16 006/245] mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame() In-Reply-To: X-SA-Exim-Connect-IP: 192.168.4.242 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.83-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: qize wang commit 1e58252e334dc3f3756f424a157d1b7484464c40 upstream. mwifiex_process_tdls_action_frame() without checking the incoming tdls infomation element's vality before use it, this may cause multi heap buffer overflows. Fix them by putting vality check before use it. IE is TLV struct, but ht_cap and ht_oper aren’t TLV struct. the origin marvell driver code is wrong: memcpy(&sta_ptr->tdls_cap.ht_oper, pos,.... memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos,... Fix the bug by changing pos(the address of IE) to pos+2 ( the address of IE value ). Signed-off-by: qize wang Signed-off-by: Kalle Valo [bwh: Backported to 3.16: adjust filename, context] Signed-off-by: Ben Hutchings --- drivers/net/wireless/mwifiex/tdls.c | 70 +++++++++++++++++++-- 1 file changed, 64 insertions(+), 6 deletions(-) --- a/drivers/net/wireless/mwifiex/tdls.c +++ b/drivers/net/wireless/mwifiex/tdls.c @@ -847,59 +847,117 @@ void mwifiex_process_tdls_action_frame(s switch (*pos) { case WLAN_EID_SUPP_RATES: + if (pos[1] > 32) + return; sta_ptr->tdls_cap.rates_len = pos[1]; for (i = 0; i < pos[1]; i++) sta_ptr->tdls_cap.rates[i] = pos[i + 2]; break; case WLAN_EID_EXT_SUPP_RATES: + if (pos[1] > 32) + return; basic = sta_ptr->tdls_cap.rates_len; + if (pos[1] > 32 - basic) + return; for (i = 0; i < pos[1]; i++) sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2]; sta_ptr->tdls_cap.rates_len += pos[1]; break; case WLAN_EID_HT_CAPABILITY: - memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos, + if (pos > end - sizeof(struct ieee80211_ht_cap) - 2) + return; + if (pos[1] != sizeof(struct ieee80211_ht_cap)) + return; + /* copy the ie's value into ht_capb*/ + memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2, sizeof(struct ieee80211_ht_cap)); sta_ptr->is_11n_enabled = 1; break; case WLAN_EID_HT_OPERATION: - memcpy(&sta_ptr->tdls_cap.ht_oper, pos, + if (pos > end - + sizeof(struct ieee80211_ht_operation) - 2) + return; + if (pos[1] != sizeof(struct ieee80211_ht_operation)) + return; + /* copy the ie's value into ht_oper*/ + memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2, sizeof(struct ieee80211_ht_operation)); break; case WLAN_EID_BSS_COEX_2040: + if (pos > end - 3) + return; + if (pos[1] != 1) + return; sta_ptr->tdls_cap.coex_2040 = pos[2]; break; case WLAN_EID_EXT_CAPABILITY: + if (pos > end - sizeof(struct ieee_types_header)) + return; + if (pos[1] < sizeof(struct ieee_types_header)) + return; + if (pos[1] > 8) + return; memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos, sizeof(struct ieee_types_header) + min_t(u8, pos[1], 8)); break; case WLAN_EID_RSN: + if (pos > end - sizeof(struct ieee_types_header)) + return; + if (pos[1] < sizeof(struct ieee_types_header)) + return; + if (pos[1] > IEEE_MAX_IE_SIZE - + sizeof(struct ieee_types_header)) + return; memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, sizeof(struct ieee_types_header) + min_t(u8, pos[1], IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header))); break; case WLAN_EID_QOS_CAPA: + if (pos > end - 3) + return; + if (pos[1] != 1) + return; sta_ptr->tdls_cap.qos_info = pos[2]; break; case WLAN_EID_VHT_OPERATION: - if (priv->adapter->is_hw_11ac_capable) - memcpy(&sta_ptr->tdls_cap.vhtoper, pos, + if (priv->adapter->is_hw_11ac_capable) { + if (pos > end - + sizeof(struct ieee80211_vht_operation) - 2) + return; + if (pos[1] != + sizeof(struct ieee80211_vht_operation)) + return; + /* copy the ie's value into vhtoper*/ + memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2, sizeof(struct ieee80211_vht_operation)); + } break; case WLAN_EID_VHT_CAPABILITY: if (priv->adapter->is_hw_11ac_capable) { - memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos, + if (pos > end - + sizeof(struct ieee80211_vht_cap) - 2) + return; + if (pos[1] != sizeof(struct ieee80211_vht_cap)) + return; + /* copy the ie's value into vhtcap*/ + memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2, sizeof(struct ieee80211_vht_cap)); sta_ptr->is_11ac_enabled = 1; } break; case WLAN_EID_AID: - if (priv->adapter->is_hw_11ac_capable) + if (priv->adapter->is_hw_11ac_capable) { + if (pos > end - 4) + return; + if (pos[1] != 2) + return; sta_ptr->tdls_cap.aid = le16_to_cpu(*(__le16 *)(pos + 2)); + } + break; default: break; }