Browse Source

qcacmn: Add a tid check for RX to avoid of OOB access

Tid in RX frame header may be larger than MAX TID allowed
value, this will lead a out of boundary array access and
lead to kernel crash at last. Change is aimed to do a TID
check and discard such frame when necessary.

Change-Id: Ie9e7a1816d197d05cf845e81251ef7772721b849
CRs-Fixed: 3071743
Yu Tian 3 years ago
parent
commit
ef29d92da0
3 changed files with 12 additions and 1 deletions
  1. 2 0
      dp/wifi3.0/dp_stats.c
  2. 2 0
      dp/wifi3.0/dp_types.h
  3. 8 1
      dp/wifi3.0/li/dp_li_rx.c

+ 2 - 0
dp/wifi3.0/dp_stats.c

@@ -6710,6 +6710,8 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
 	DP_PRINT_STATS("Reo2rel route drop:%d",
 		       soc->stats.rx.reo2rel_route_drop);
 	DP_PRINT_STATS("Rx Flush count:%d", soc->stats.rx.err.rx_flush_count);
+	DP_PRINT_STATS("Rx invalid TID count:%d",
+		       soc->stats.rx.err.rx_invalid_tid_err);
 }
 
 #ifdef FEATURE_TSO_STATS

+ 2 - 0
dp/wifi3.0/dp_types.h

@@ -1121,6 +1121,8 @@ struct dp_soc_stats {
 			uint32_t msdu_len_err;
 			/* Rx flush count */
 			uint32_t rx_flush_count;
+			/* Rx invalid tid count */
+			uint32_t rx_invalid_tid_err;
 		} err;
 
 		/* packet count per core - per ring */

+ 8 - 1
dp/wifi3.0/li/dp_li_rx.c

@@ -581,8 +581,15 @@ done:
 		}
 
 		/* Get TID from struct cb->tid_val, save to tid */
-		if (qdf_nbuf_is_rx_chfrag_start(nbuf))
+		if (qdf_nbuf_is_rx_chfrag_start(nbuf)) {
 			tid = qdf_nbuf_get_tid_val(nbuf);
+			if (tid >= CDP_MAX_DATA_TIDS) {
+				DP_STATS_INC(soc, rx.err.rx_invalid_tid_err, 1);
+				qdf_nbuf_free(nbuf);
+				nbuf = next;
+				continue;
+			}
+		}
 
 		if (qdf_unlikely(!peer)) {
 			peer = dp_peer_get_ref_by_id(soc, peer_id,