From ceb1dc9f8deed7997d7346c00c27eb33bc5e5b15 Mon Sep 17 00:00:00 2001 From: Jinwei Chen Date: Tue, 11 Aug 2020 01:35:59 -0700 Subject: [PATCH] qcacld-3.0: fix invalid accessing to freed in_ifaddr The in_ifaddr in in_dev->ifa_list which stores IP info is freed maybe due to lifetime hit/wlan interface re-connect, etc. In the meantime, lot ARP request frame is pending in DP RX thread and still try to do local ARP check in function hdd_is_arp_local(), this function will go through in_dev->ifa_list but no lock protection, use after free happened due to race condition. Add lock protection in hdd_is_arp_local(). Change-Id: Iaa97d445d3c4c0b79b5b9f63362df2601f62af5b CRs-Fixed: 2751469 --- core/hdd/src/wlan_hdd_tx_rx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index adab904200c8..346f02040077 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -1540,6 +1540,7 @@ static bool hdd_is_arp_local(struct sk_buff *skb) arp = (struct arphdr *)skb->data; if (arp->ar_op == htons(ARPOP_REQUEST)) { + rtnl_lock(); in_dev = __in_dev_get_rtnl(skb->dev); if (in_dev) { for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; @@ -1556,9 +1557,12 @@ static bool hdd_is_arp_local(struct sk_buff *skb) memcpy(&tip, arp_ptr, 4); hdd_debug("ARP packet: local IP: %x dest IP: %x", ifa->ifa_local, tip); - if (ifa->ifa_local == tip) + if (ifa->ifa_local == tip) { + rtnl_unlock(); return true; + } } + rtnl_unlock(); } return false;