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
此提交包含在:
Yeshwanth Sriram Guntuka
2020-06-29 17:01:55 +05:30
提交者 nshrivas
父節點 307b78c912
當前提交 90e1136afb

查看文件

@@ -2247,7 +2247,13 @@ done:
tid = qdf_nbuf_get_tid_val(nbuf);
peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf);
peer = dp_peer_find_by_id(soc, peer_id);
if (qdf_unlikely(!peer)) {
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) {
QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) = false;
@@ -2272,7 +2278,6 @@ done:
qdf_nbuf_free(nbuf);
nbuf = next;
DP_STATS_INC(soc, rx.err.invalid_vdev, 1);
dp_peer_unref_del_find_by_id(peer);
continue;
}
@@ -2360,7 +2365,6 @@ done:
dp_info_rl("scatter msdu len %d, dropped",
msdu_len);
nbuf = next;
dp_peer_unref_del_find_by_id(peer);
continue;
}
} else {
@@ -2382,7 +2386,6 @@ done:
DP_STATS_INC(peer, rx.multipass_rx_pkt_drop, 1);
qdf_nbuf_free(nbuf);
nbuf = next;
dp_peer_unref_del_find_by_id(peer);
continue;
}
}
@@ -2396,7 +2399,6 @@ done:
qdf_nbuf_free(nbuf);
/* Statistics */
nbuf = next;
dp_peer_unref_del_find_by_id(peer);
continue;
}
@@ -2409,7 +2411,6 @@ done:
DP_STATS_INC(peer, rx.nawds_mcast_drop, 1);
qdf_nbuf_free(nbuf);
nbuf = next;
dp_peer_unref_del_find_by_id(peer);
continue;
}
@@ -2438,7 +2439,6 @@ done:
qdf_nbuf_free(nbuf);
nbuf = next;
dp_peer_unref_del_find_by_id(peer);
continue;
}
dp_rx_fill_mesh_stats(vdev, nbuf, rx_tlv_hdr, peer);
@@ -2465,7 +2465,6 @@ done:
qdf_nbuf_free(nbuf);
nbuf = next;
DP_STATS_INC(soc, rx.err.invalid_sa_da_idx, 1);
dp_peer_unref_del_find_by_id(peer);
continue;
}
/* WDS Source Port Learning */
@@ -2484,7 +2483,6 @@ done:
nbuf,
msdu_metadata)) {
nbuf = next;
dp_peer_unref_del_find_by_id(peer);
tid_stats->intrabss_cnt++;
continue; /* Get next desc */
}
@@ -2500,7 +2498,6 @@ done:
tid_stats->delivered_to_stack++;
nbuf = next;
dp_peer_unref_del_find_by_id(peer);
}
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 (quota) {
num_pending =