[14/18] ath10k: drop MPDU which has discard flag set by firmware for SDIO

Message ID 20210511200110.11968c725b5c.Idd166365ebea2771c0c0a38c78b5060750f90e17@changeid
State New
Headers show
Series
  • mac80211/driver security fixes
Related show

Commit Message

Johannes Berg May 11, 2021, 6:02 p.m.
From: Wen Gong <wgong@codeaurora.org>

When the discard flag is set by the firmware for an MPDU, it should be
dropped. This allows a mitigation for CVE-2020-24588 to be implemented
in the firmware.

Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00049

Cc: stable@vger.kernel.org
Signed-off-by: Wen Gong <wgong@codeaurora.org>
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/wireless/ath/ath10k/htt_rx.c  |  5 +++++
 drivers/net/wireless/ath/ath10k/rx_desc.h | 14 +++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

Comments

Jeff Johnson May 13, 2021, 5:18 p.m. | #1
On 2021-05-12 11:35, Brian Norris wrote:
> On Tue, May 11, 2021 at 11:03 AM Johannes Berg
> <johannes@sipsolutions.net> wrote:
>> --- a/drivers/net/wireless/ath/ath10k/htt_rx.c
>> +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
>> @@ -2312,6 +2312,11 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct
>> ath10k_htt *htt,
>>         fw_desc = &rx->fw_desc;
>>         rx_desc_len = fw_desc->len;
>> 
>> +       if (fw_desc->u.bits.discard) {
>> +               ath10k_dbg(ar, ATH10K_DBG_HTT, "htt discard mpdu\n");
>> +               goto err;
>> +       }
>> +
>>         /* I have not yet seen any case where num_mpdu_ranges > 1.
>>          * qcacld does not seem handle that case either, so we 
>> introduce
>> the
>>          * same limitiation here as well.
>> diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h
>> b/drivers/net/wireless/ath/ath10k/rx_desc.h
>> index f2b6bf8f0d60..705b6295e466 100644
>> --- a/drivers/net/wireless/ath/ath10k/rx_desc.h
>> +++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
>> @@ -1282,7 +1282,19 @@ struct fw_rx_desc_base {
>>  #define FW_RX_DESC_UDP              (1 << 6)
>> 
>>  struct fw_rx_desc_hl {
>> -       u8 info0;
>> +       union {
>> +               struct {
>> +               u8 discard:1,
>> +                  forward:1,
>> +                  any_err:1,
>> +                  dup_err:1,
>> +                  reserved:1,
>> +                  inspect:1,
>> +                  extension:2;
>> +               } bits;
>> +               u8 info0;
>> +       } u;
> 
> Am I misled here, or are you introducing endianness issues here? From 
> C99:
> 
> "The order of allocation of bit-fields within a unit (high-order to
> low-order or low-order to high-order) is implementation-defined."
> 
> Now, we're pretty well attuned to two implementations (big and little
> endian), and this should work for the most common one (little endian),
> but it's not wise to assume everyone is little endian.
> 
> Brian

This issue was identified in internal review, but due to the embargo 
expiring
we sent it out as-is since that is what had been tested. The author will 
have
a follow-up change to replace this.

Patch

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index b1d93ff5215a..12451ab66a19 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2312,6 +2312,11 @@  static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
 	fw_desc = &rx->fw_desc;
 	rx_desc_len = fw_desc->len;
 
+	if (fw_desc->u.bits.discard) {
+		ath10k_dbg(ar, ATH10K_DBG_HTT, "htt discard mpdu\n");
+		goto err;
+	}
+
 	/* I have not yet seen any case where num_mpdu_ranges > 1.
 	 * qcacld does not seem handle that case either, so we introduce the
 	 * same limitiation here as well.
diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h
index f2b6bf8f0d60..705b6295e466 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -1282,7 +1282,19 @@  struct fw_rx_desc_base {
 #define FW_RX_DESC_UDP              (1 << 6)
 
 struct fw_rx_desc_hl {
-	u8 info0;
+	union {
+		struct {
+		u8 discard:1,
+		   forward:1,
+		   any_err:1,
+		   dup_err:1,
+		   reserved:1,
+		   inspect:1,
+		   extension:2;
+		} bits;
+		u8 info0;
+	} u;
+
 	u8 version;
 	u8 len;
 	u8 flags;