Explorar o código

qcacld-3.0: Use sta id to derive peer in ol_rx_data_cb

Derive peer from sta id in ol_rx_data_cb to
make sure that peer is still valid before
using peer to avoid NULL pointer dereference

Change-Id: I8f9219d4c6ffbfb207385b08bc704cc0f86a1e1b
CRs-Fixed: 962949
Nirav Shah %!s(int64=9) %!d(string=hai) anos
pai
achega
36a87bfb6e
Modificáronse 1 ficheiros con 16 adicións e 6 borrados
  1. 16 6
      core/dp/txrx/ol_txrx.c

+ 16 - 6
core/dp/txrx/ol_txrx.c

@@ -3447,17 +3447,27 @@ void ol_txrx_clear_stats(uint16_t value)
  * ol_rx_data_cb() - data rx callback
  * @peer: peer
  * @buf_list: buffer list
+ * @staid: Station id
  *
  * Return: None
  */
-static void ol_rx_data_cb(struct ol_txrx_peer_t *peer,
-			  qdf_nbuf_t buf_list)
+static void ol_rx_data_cb(struct ol_txrx_pdev_t *pdev,
+			  qdf_nbuf_t buf_list, uint16_t staid)
 {
+	void *cds_ctx = cds_get_global_context();
 	qdf_nbuf_t buf, next_buf;
 	QDF_STATUS ret;
 	ol_txrx_rx_fp data_rx = NULL;
+	struct ol_txrx_peer_t *peer;
+
+	if (qdf_unlikely(!cds_ctx) || qdf_unlikely(!pdev))
+		goto free_buf;
 
-	if (qdf_unlikely(!peer->vdev))
+	/* Do not use peer directly. Derive peer from staid to
+	 * make sure that peer is valid.
+	 */
+	peer = ol_txrx_peer_find_by_local_id(pdev, staid);
+	if (!peer)
 		goto free_buf;
 
 	qdf_spin_lock_bh(&peer->peer_info_lock);
@@ -3563,7 +3573,7 @@ void ol_rx_data_process(struct ol_txrx_peer_t *peer,
 		 * better use multicores.
 		 */
 		if (!ol_cfg_is_rx_thread_enabled(pdev->ctrl_pdev)) {
-			ol_rx_data_cb(peer, rx_buf_list);
+			ol_rx_data_cb(pdev, rx_buf_list, peer->local_id);
 		} else {
 			p_cds_sched_context sched_ctx =
 				get_cds_sched_ctxt();
@@ -3580,13 +3590,13 @@ void ol_rx_data_process(struct ol_txrx_peer_t *peer,
 			}
 			pkt->callback = (cds_ol_rx_thread_cb)
 					ol_rx_data_cb;
-			pkt->context = (void *)peer;
+			pkt->context = (void *)pdev;
 			pkt->Rxpkt = (void *)rx_buf_list;
 			pkt->staId = peer->local_id;
 			cds_indicate_rxpkt(sched_ctx, pkt);
 		}
 #else                           /* QCA_CONFIG_SMP */
-		ol_rx_data_cb(peer, rx_buf_list, 0);
+		ol_rx_data_cb(pdev, rx_buf_list, peer->local_id);
 #endif /* QCA_CONFIG_SMP */
 	}