Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp1766343ybl; Sat, 11 Jan 2020 02:23:12 -0800 (PST) X-Google-Smtp-Source: APXvYqxtc6RnnjVOZy0zzyhd/KsxqL9fSOmqQJE4IKEsMHQs6p3XZwKowyUSXbsE6/SmdAwKN0eM X-Received: by 2002:a9d:73d9:: with SMTP id m25mr6529791otk.350.1578738192669; Sat, 11 Jan 2020 02:23:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578738192; cv=none; d=google.com; s=arc-20160816; b=nQrJqSOzhjIAbZyWHCUjt+a3UfoTJ1WyEIKzC7VVBDx+B78O17W0J42BlAPh/C/tay H90m5PDMy9seZ03KYyk5f8llqE9tyF3cC6cRlqbL4Xq0la4zwKukiez3m6TKkfiu9bKm w6h/eXyBFwI2wFoqiWvbUkJBtonac438HIH1eleb/O24jklh0AoSG/sDBlZHDaDuhrWd t7vAbw4c9h1wOLNHfPDWwXKwDWewyQOFvsnYGD3YoOyP6Gwkw3SqMmob5xk6b+TTh5JE bpMVcdT856+iWGaOBetl/tvra7GosIn9CUQtc63fz+megkXx+Izs2JRT06QyQoNXnCvC Yv9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=/YcuG6qvluZX4bBlMt7xmXHe8BLbZlqtkJbrOPGXOUA=; b=hCbKjt8jkhxlEsJBbQlND+q78v/rc9MSRrThsZNu8swIhn6xqEKJGrOnq9NH425pjL kXO3NmYNCzSFtGTT5pkQ3icggHmpXSuz0RHBK4cL4iqxMOL8zNIhPjgnT/mp5IA5fNzl 5GAyzGLzWTVMVkO5bCteHbTy+iwFP1KiT4733bjZwadj6A2nEZkQWJcyiqK75t0T4J9Q eh/Nz2bP10Lme8doTgRVVyo8sPZwa+xmUtzxvfurm4B/NvW6nJxZtg7EMw/M6ZbHvUqh 9US8emfFAp/XGF/XpFDgkdl1HngRHMuTEjUPSLFFi7YkeuNk1s+IPwUrhMdxvrgys7Zh mBEQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=haKujGtZ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v3si3442219oth.256.2020.01.11.02.23.01; Sat, 11 Jan 2020 02:23:12 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=haKujGtZ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730712AbgAKKWO (ORCPT + 99 others); Sat, 11 Jan 2020 05:22:14 -0500 Received: from mail.kernel.org ([198.145.29.99]:46816 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730160AbgAKKWK (ORCPT ); Sat, 11 Jan 2020 05:22:10 -0500 Received: from localhost (unknown [62.119.166.9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 3E1FB2084D; Sat, 11 Jan 2020 10:22:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1578738129; bh=M01gu7MziXp8+VKh5qcZFPlH1fqzm0ZSof5dqte4qCE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=haKujGtZb5fMO2L6xT27olaBdLXujgwEZl0wWbo/44gvl01a6t0ON5IvhKQfa2zdS GMHqovCVhUGgcGvBIZTVbjOgqIJbl6OtKJQp0UMK2de406607Yx++QL+Y0lxue2xdR ZrwIvfMQOpWP0IGiUlTW54OJw+evqaGqzJ/MwKko= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, qize wang , Kalle Valo , Sasha Levin Subject: [PATCH 5.4 014/165] mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame() Date: Sat, 11 Jan 2020 10:48:53 +0100 Message-Id: <20200111094922.256591309@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200111094921.347491861@linuxfoundation.org> References: <20200111094921.347491861@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: qize wang [ Upstream commit 1e58252e334dc3f3756f424a157d1b7484464c40 ] 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 Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/mwifiex/tdls.c | 70 +++++++++++++++++++-- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c index 09313047beed..7caf1d26124a 100644 --- a/drivers/net/wireless/marvell/mwifiex/tdls.c +++ b/drivers/net/wireless/marvell/mwifiex/tdls.c @@ -953,59 +953,117 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, 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 = get_unaligned_le16((pos + 2)); + } + break; default: break; } -- 2.20.1