wifi: mwifiex: Sanity check tlv_len and tlv_bitmap_len
authorGustavo A. R. Silva <gustavoars@kernel.org>
Fri, 25 Aug 2023 03:10:45 +0000 (21:10 -0600)
committerKalle Valo <kvalo@kernel.org>
Mon, 4 Sep 2023 17:16:13 +0000 (20:16 +0300)
Add sanity checks for both `tlv_len` and `tlv_bitmap_len` before
decoding data from `event_buf`.

This prevents any malicious or buggy firmware from overflowing
`event_buf` through large values for `tlv_len` and `tlv_bitmap_len`.

Suggested-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/d4f8780527d551552ee96f17a0229e02e1c200d1.1692931954.git.gustavoars@kernel.org
drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c

index 735aac52bdc4d0844f977272b4dcc3da71d5eb03..10690e82358b892f04327d41981d5eb7f5791309 100644 (file)
@@ -921,6 +921,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv,
        while (tlv_buf_left > sizeof(*tlv_rxba)) {
                tlv_type = le16_to_cpu(tlv_rxba->header.type);
                tlv_len  = le16_to_cpu(tlv_rxba->header.len);
+               if (size_add(sizeof(tlv_rxba->header), tlv_len) > tlv_buf_left) {
+                       mwifiex_dbg(priv->adapter, WARN,
+                                   "TLV size (%zu) overflows event_buf buf_left=%d\n",
+                                   size_add(sizeof(tlv_rxba->header), tlv_len),
+                                   tlv_buf_left);
+                       return;
+               }
+
                if (tlv_type != TLV_TYPE_RXBA_SYNC) {
                        mwifiex_dbg(priv->adapter, ERROR,
                                    "Wrong TLV id=0x%x\n", tlv_type);
@@ -929,6 +937,14 @@ void mwifiex_11n_rxba_sync_event(struct mwifiex_private *priv,
 
                tlv_seq_num = le16_to_cpu(tlv_rxba->seq_num);
                tlv_bitmap_len = le16_to_cpu(tlv_rxba->bitmap_len);
+               if (size_add(sizeof(*tlv_rxba), tlv_bitmap_len) > tlv_buf_left) {
+                       mwifiex_dbg(priv->adapter, WARN,
+                                   "TLV size (%zu) overflows event_buf buf_left=%d\n",
+                                   size_add(sizeof(*tlv_rxba), tlv_bitmap_len),
+                                   tlv_buf_left);
+                       return;
+               }
+
                mwifiex_dbg(priv->adapter, INFO,
                            "%pM tid=%d seq_num=%d bitmap_len=%d\n",
                            tlv_rxba->mac, tlv_rxba->tid, tlv_seq_num,