From e87e930251cb1445ad6f03911cc1fe70ae17aa98 Mon Sep 17 00:00:00 2001 From: Gabriel Biren Date: Wed, 18 Oct 2023 16:23:58 +0000 Subject: Add a lock around the wificond death handler and teardownInterfaces in WifiNl80211Manager. Prevents a specific race condition when the wificond service dies at the same time as the Vendor HAL (whose death handler calls into teardownInterfaces). No other race conditions have been observed in this file, so we can limit the locks to these 2 methods. Bug: 273175980 Test: atest WifiNl80211ManagerTest Change-Id: Ib3936ed8ddb3c0dc5fb25a56e535ab27a28cfa65 --- .../net/wifi/nl80211/WifiNl80211Manager.java | 53 ++++++++++++---------- 1 file changed, 29 insertions(+), 24 deletions(-) (limited to 'wifi/java/src') diff --git a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java index 2a199d27a60e..58638e8e1af4 100644 --- a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java +++ b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java @@ -113,6 +113,7 @@ public class WifiNl80211Manager { private HashMap mPnoScanEventHandlers = new HashMap<>(); private HashMap mApInterfaceListeners = new HashMap<>(); private Runnable mDeathEventHandler; + private Object mLock = new Object(); /** * Ensures that no more than one sendMgmtFrame operation runs concurrently. */ @@ -625,13 +626,15 @@ public class WifiNl80211Manager { @VisibleForTesting public void binderDied() { mEventHandler.post(() -> { - Log.e(TAG, "Wificond died!"); - clearState(); - // Invalidate the global wificond handle on death. Will be refreshed - // on the next setup call. - mWificond = null; - if (mDeathEventHandler != null) { - mDeathEventHandler.run(); + synchronized (mLock) { + Log.e(TAG, "Wificond died!"); + clearState(); + // Invalidate the global wificond handle on death. Will be refreshed + // on the next setup call. + mWificond = null; + if (mDeathEventHandler != null) { + mDeathEventHandler.run(); + } } }); } @@ -867,26 +870,28 @@ public class WifiNl80211Manager { * @return Returns true on success. */ public boolean tearDownInterfaces() { - Log.d(TAG, "tearing down interfaces in wificond"); - // Explicitly refresh the wificodn handler because |tearDownInterfaces()| - // could be used to cleanup before we setup any interfaces. - if (!retrieveWificondAndRegisterForDeath()) { - return false; - } + synchronized (mLock) { + Log.d(TAG, "tearing down interfaces in wificond"); + // Explicitly refresh the wificond handler because |tearDownInterfaces()| + // could be used to cleanup before we setup any interfaces. + if (!retrieveWificondAndRegisterForDeath()) { + return false; + } - try { - for (Map.Entry entry : mWificondScanners.entrySet()) { - entry.getValue().unsubscribeScanEvents(); - entry.getValue().unsubscribePnoScanEvents(); + try { + for (Map.Entry entry : mWificondScanners.entrySet()) { + entry.getValue().unsubscribeScanEvents(); + entry.getValue().unsubscribePnoScanEvents(); + } + mWificond.tearDownInterfaces(); + clearState(); + return true; + } catch (RemoteException e) { + Log.e(TAG, "Failed to tear down interfaces due to remote exception"); } - mWificond.tearDownInterfaces(); - clearState(); - return true; - } catch (RemoteException e) { - Log.e(TAG, "Failed to tear down interfaces due to remote exception"); - } - return false; + return false; + } } /** Helper function to look up the interface handle using name */ -- cgit v1.2.3-59-g8ed1b