qcacmn: Decrement peer ref cnt after dp_rx_deliver_to_stack
Ths issue scenario is that valid peer is fetched from peer_id in dp_rx_process and peer ref count is released prior to invoking dp_rx_deliver_to_stack. In parallel, the peer is freed in a different context. This results in use after free within dp_rx_check_delivery_to_stack since stale peer is dereferenced to update stats. Fix is to decrement peer ref cnt after dp_rx_deliver_to_stack Change-Id: I145247f7795f926faba66c05927fdae0599f0cad CRs-Fixed: 2720396
This commit is contained in:

committed by
nshrivas

parent
307b78c912
commit
90e1136afb
@@ -2247,7 +2247,13 @@ done:
|
|||||||
tid = qdf_nbuf_get_tid_val(nbuf);
|
tid = qdf_nbuf_get_tid_val(nbuf);
|
||||||
|
|
||||||
peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf);
|
peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf);
|
||||||
|
|
||||||
|
if (qdf_unlikely(!peer)) {
|
||||||
peer = dp_peer_find_by_id(soc, peer_id);
|
peer = dp_peer_find_by_id(soc, peer_id);
|
||||||
|
} else if (peer && peer->peer_id != peer_id) {
|
||||||
|
dp_peer_unref_del_find_by_id(peer);
|
||||||
|
peer = dp_peer_find_by_id(soc, peer_id);
|
||||||
|
}
|
||||||
|
|
||||||
if (peer) {
|
if (peer) {
|
||||||
QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) = false;
|
QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) = false;
|
||||||
@@ -2272,7 +2278,6 @@ done:
|
|||||||
qdf_nbuf_free(nbuf);
|
qdf_nbuf_free(nbuf);
|
||||||
nbuf = next;
|
nbuf = next;
|
||||||
DP_STATS_INC(soc, rx.err.invalid_vdev, 1);
|
DP_STATS_INC(soc, rx.err.invalid_vdev, 1);
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2360,7 +2365,6 @@ done:
|
|||||||
dp_info_rl("scatter msdu len %d, dropped",
|
dp_info_rl("scatter msdu len %d, dropped",
|
||||||
msdu_len);
|
msdu_len);
|
||||||
nbuf = next;
|
nbuf = next;
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2382,7 +2386,6 @@ done:
|
|||||||
DP_STATS_INC(peer, rx.multipass_rx_pkt_drop, 1);
|
DP_STATS_INC(peer, rx.multipass_rx_pkt_drop, 1);
|
||||||
qdf_nbuf_free(nbuf);
|
qdf_nbuf_free(nbuf);
|
||||||
nbuf = next;
|
nbuf = next;
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2396,7 +2399,6 @@ done:
|
|||||||
qdf_nbuf_free(nbuf);
|
qdf_nbuf_free(nbuf);
|
||||||
/* Statistics */
|
/* Statistics */
|
||||||
nbuf = next;
|
nbuf = next;
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2409,7 +2411,6 @@ done:
|
|||||||
DP_STATS_INC(peer, rx.nawds_mcast_drop, 1);
|
DP_STATS_INC(peer, rx.nawds_mcast_drop, 1);
|
||||||
qdf_nbuf_free(nbuf);
|
qdf_nbuf_free(nbuf);
|
||||||
nbuf = next;
|
nbuf = next;
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2438,7 +2439,6 @@ done:
|
|||||||
|
|
||||||
qdf_nbuf_free(nbuf);
|
qdf_nbuf_free(nbuf);
|
||||||
nbuf = next;
|
nbuf = next;
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dp_rx_fill_mesh_stats(vdev, nbuf, rx_tlv_hdr, peer);
|
dp_rx_fill_mesh_stats(vdev, nbuf, rx_tlv_hdr, peer);
|
||||||
@@ -2465,7 +2465,6 @@ done:
|
|||||||
qdf_nbuf_free(nbuf);
|
qdf_nbuf_free(nbuf);
|
||||||
nbuf = next;
|
nbuf = next;
|
||||||
DP_STATS_INC(soc, rx.err.invalid_sa_da_idx, 1);
|
DP_STATS_INC(soc, rx.err.invalid_sa_da_idx, 1);
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* WDS Source Port Learning */
|
/* WDS Source Port Learning */
|
||||||
@@ -2484,7 +2483,6 @@ done:
|
|||||||
nbuf,
|
nbuf,
|
||||||
msdu_metadata)) {
|
msdu_metadata)) {
|
||||||
nbuf = next;
|
nbuf = next;
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
tid_stats->intrabss_cnt++;
|
tid_stats->intrabss_cnt++;
|
||||||
continue; /* Get next desc */
|
continue; /* Get next desc */
|
||||||
}
|
}
|
||||||
@@ -2500,7 +2498,6 @@ done:
|
|||||||
|
|
||||||
tid_stats->delivered_to_stack++;
|
tid_stats->delivered_to_stack++;
|
||||||
nbuf = next;
|
nbuf = next;
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qdf_likely(deliver_list_head)) {
|
if (qdf_likely(deliver_list_head)) {
|
||||||
@@ -2519,6 +2516,9 @@ done:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qdf_likely(peer))
|
||||||
|
dp_peer_unref_del_find_by_id(peer);
|
||||||
|
|
||||||
if (dp_rx_enable_eol_data_check(soc) && rx_bufs_used) {
|
if (dp_rx_enable_eol_data_check(soc) && rx_bufs_used) {
|
||||||
if (quota) {
|
if (quota) {
|
||||||
num_pending =
|
num_pending =
|
||||||
|
Reference in New Issue
Block a user