qcacld-3.0: Fix use-after-free when skb is copied

When we receive a packet from the network stack for
transmission, we make a copy of this skb and free the
shared skb before trying to trasnmit it.

Currently the mac address used for tdls operations is
taken as a pointer to the original skb, which gets freed
after the skb_unshare.

Copy the mac address into a local stack memory instead
of using a pointer to the skb data to avoid the
use-after-free condition.

Change-Id: I9f0e6260476d5a41b7209a6a599f50a548b953b5
CRs-Fixed: 2733445
This commit is contained in:
Rakesh Pillai 2020-07-18 01:07:29 +05:30 • committed by snandini
commit 9f72aa9c82

View file

@ -945,7 +945,7 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb,
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
bool granted;
struct hdd_station_ctx *sta_ctx = &adapter->session.station;
struct qdf_mac_addr *mac_addr;
struct qdf_mac_addr mac_addr;
struct qdf_mac_addr mac_addr_tx_allowed = QDF_MAC_ADDR_ZERO_INIT;
uint8_t pkt_type = 0;
bool is_arp = false;
@ -965,7 +965,7 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb,
++adapter->hdd_stats.tx_rx_stats.tx_called;
adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0;
mac_addr = (struct qdf_mac_addr *)skb->data;
qdf_mem_copy(mac_addr.bytes, skb->data, sizeof(mac_addr.bytes));
if (cds_is_driver_recovering() || cds_is_driver_in_bad_state() ||
cds_is_load_or_unload_in_progress()) {
@ -1024,7 +1024,7 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb,
goto drop_pkt;
}
hdd_get_tx_resource(adapter, mac_addr,
hdd_get_tx_resource(adapter, &mac_addr,
WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
/* Get TL AC corresponding to Qdisc queue index/AC. */
@ -1122,7 +1122,7 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb,
vdev = hdd_objmgr_get_vdev(adapter);
if (vdev) {
ucfg_tdls_update_tx_pkt_cnt(vdev, mac_addr);
ucfg_tdls_update_tx_pkt_cnt(vdev, &mac_addr);
hdd_objmgr_put_vdev(vdev);
}
@ -1180,7 +1180,7 @@ static void __hdd_hard_start_xmit(struct sk_buff *skb,
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
"%s: Failed to send packet to txrx for sta_id: "
QDF_MAC_ADDR_STR,
__func__, QDF_MAC_ADDR_ARRAY(mac_addr->bytes));
__func__, QDF_MAC_ADDR_ARRAY(mac_addr.bytes));
++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
goto drop_pkt_and_release_skb;
}