diff options
author | Damon Kim <taekhun.kim@broadcom.com> | 2021-12-17 13:14:19 +0900 |
---|---|---|
committer | Roger Wang <wangroger@google.com> | 2021-12-22 04:17:11 +0000 |
commit | c835c0483b7168e9582cb12e135d355de494d903 (patch) | |
tree | 77def538324d5a7cfe5297de72a5a0715e78ba93 | |
parent | 1bdf26126fcb64aa491683b7c9f24ffec72da025 (diff) | |
download | wlan-c835c0483b7168e9582cb12e135d355de494d903.tar.gz |
HAL: Fixed vendor HAL crash due to missing unregisterVendorHandler() in some failure caseandroid-12.1.0_r9android-12.1.0_r8android-12.1.0_r7android-12.1.0_r22android-12.1.0_r21android-12.1.0_r20android-12.1.0_r19android-12.1.0_r11android-12.1.0_r10android12L-devandroid12-qpr3-s7-releaseandroid12-qpr3-s6-releaseandroid12-qpr3-s5-releaseandroid12-qpr3-s4-releaseandroid12-qpr3-s3-releaseandroid12-qpr3-s2-releaseandroid12-qpr3-s1-releaseandroid12-qpr3-release
WifiNative Failure(HAL crash) happened in vendor hal library due to FORTIFY abort.
According to the FORTIFY message, it caused by pthread_mutex_destroy called on a destroyed mutex.
The situation is as follows:
-----------------------
1. RTT cmd failed, so that cmd unregistered, cmd object destroyed. But, vendor handler is still exist in the related list.
2. RTT event received. It handled in internal_valid_message_handler() since the record of RTT vendor handler is still exist.
3. Finally, FORTIFY abort detected when pthread_mutext_destroy() on destroyed memory during releaseRef()
|- internal_valid_message_handler()
|- cmd->releaseRef()
|- destructor chains called
|- ...
|- ~Condition() /* crashed here when try to destroy mMutex member */
-----------------------
Hence, this won't be happened if unregisterVendorhandler() called properly in some failure cases.
In case of RTT cmd failure, unregisterVendorhandler() should be called before wifi_unregister_cmd() & object destroyed.
In addition, all places with this pattern have been fixed together.
Bug: 210167945
Test: Local build done for Hikey960/Android 12(S), basic Wi-Fi functions worked well.
Test: passed sanity test
Change-Id: Icf4354c4eee74cac3ebedcaba1116320e750b2a3
Merged-In: Icf4354c4eee74cac3ebedcaba1116320e750b2a3
(cherry picked from commit 9d4683f3e3304848b3bfd883ade0649bb024573b)
-rwxr-xr-x | bcmdhd/wifi_hal/gscan.cpp | 41 | ||||
-rw-r--r-- | bcmdhd/wifi_hal/rtt.cpp | 1 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/wifi_logger.cpp | 6 |
3 files changed, 32 insertions, 16 deletions
diff --git a/bcmdhd/wifi_hal/gscan.cpp b/bcmdhd/wifi_hal/gscan.cpp index f012423..995c989 100755 --- a/bcmdhd/wifi_hal/gscan.cpp +++ b/bcmdhd/wifi_hal/gscan.cpp @@ -404,8 +404,8 @@ public: result = requestResponse(request); if (result != WIFI_SUCCESS) { - ALOGE("failed to enable full scan results; result = %d", result); unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); + ALOGE("failed to enable full scan results; result = %d", result); return result; } @@ -566,6 +566,12 @@ public: return createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 0); } + void unregisterVendorHandlerAll() { + unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); + unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); + unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); + } + int start() { ALOGV("GSCAN start"); WifiRequest request(familyId(), ifaceId()); @@ -581,6 +587,7 @@ public: result = requestResponse(request); if (result != WIFI_SUCCESS) { + unregisterVendorHandlerAll(); ALOGE("failed to configure setup; result = %d", result); return result; } @@ -589,12 +596,14 @@ public: result = createScanConfigRequest(request); if (result != WIFI_SUCCESS) { + unregisterVendorHandlerAll(); ALOGE("failed to create scan config request; result = %d", result); return result; } result = requestResponse(request); if (result != WIFI_SUCCESS) { + unregisterVendorHandlerAll(); ALOGE("failed to configure scan; result = %d", result); return result; } @@ -603,16 +612,15 @@ public: result = createStartRequest(request); if (result != WIFI_SUCCESS) { + unregisterVendorHandlerAll(); ALOGE("failed to create start request; result = %d", result); return result; } result = requestResponse(request); if (result != WIFI_SUCCESS) { + unregisterVendorHandlerAll(); ALOGE("failed to start scan; result = %d", result); - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); return result; } return result; @@ -632,9 +640,7 @@ public: } } - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN); - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE); - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_FULL_SCAN_RESULTS); + unregisterVendorHandlerAll(); return WIFI_SUCCESS; } @@ -1057,6 +1063,11 @@ public: return result; } + void unregisterVendorHandlerAll() { + unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); + unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); + } + int start() { ALOGI("Executing hotlist setup request, num = %d", mParams.num_bssid); WifiRequest request(familyId(), ifaceId()); @@ -1070,22 +1081,21 @@ public: result = requestResponse(request); if (result < 0) { + unregisterVendorHandlerAll(); ALOGI("Failed to execute hotlist setup request, result = %d", result); - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); return result; } ALOGI("Successfully set %d APs in the hotlist ", mParams.num_bssid); result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); if (result < 0) { + unregisterVendorHandlerAll(); return result; } result = requestResponse(request); if (result < 0) { - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); + unregisterVendorHandlerAll(); return result; } @@ -1095,8 +1105,7 @@ public: virtual int cancel() { /* unregister event handler */ - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_FOUND); - unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_HOTLIST_RESULTS_LOST); + unregisterVendorHandlerAll(); /* create set hotlist message with empty hotlist */ WifiRequest request(familyId(), ifaceId()); int result = createTeardownRequest(request); @@ -1288,8 +1297,8 @@ public: registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT); result = requestResponse(request); if (result < 0) { - ALOGI("Failed to execute ePNO setup request, result = %d", result); unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_EPNO_EVENT); + ALOGI("Failed to execute ePNO setup request, result = %d", result); return result; } @@ -1496,6 +1505,7 @@ public: result = requestResponse(request); if (result < 0) { + unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); ALOGI("failed to set significant wifi change config %d", result); return result; } @@ -1504,6 +1514,7 @@ public: result = createFeatureRequest(request, GSCAN_SUBCMD_ENABLE_GSCAN, 1); if (result < 0) { + unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS); return result; } @@ -1891,8 +1902,8 @@ public: result = requestResponse(request); if (result != WIFI_SUCCESS) { - ALOGE("failed to set ANQPO networks; result = %d", result); unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_ANQPO_HOTSPOT_MATCH); + ALOGE("failed to set ANQPO networks; result = %d", result); return result; } diff --git a/bcmdhd/wifi_hal/rtt.cpp b/bcmdhd/wifi_hal/rtt.cpp index 43a49e8..6bb0a49 100644 --- a/bcmdhd/wifi_hal/rtt.cpp +++ b/bcmdhd/wifi_hal/rtt.cpp @@ -488,6 +488,7 @@ public: registerVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE); result = requestResponse(request); if (result != WIFI_SUCCESS) { + unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE); ALOGE("failed to configure RTT setup; result = %d", result); return result; } diff --git a/bcmdhd/wifi_hal/wifi_logger.cpp b/bcmdhd/wifi_hal/wifi_logger.cpp index 6870ee6..85cf0e7 100755 --- a/bcmdhd/wifi_hal/wifi_logger.cpp +++ b/bcmdhd/wifi_hal/wifi_logger.cpp @@ -654,7 +654,6 @@ public: ALOGV("Register loghandler"); int result; uint32_t event_sock_pid = getpid() + (WIFI_HAL_EVENT_SOCK_PORT << 22); - registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); WifiRequest request(familyId(), ifaceId()); @@ -664,14 +663,18 @@ public: ALOGV("Failed to set Hal preInit; result = %d", result); return result; } + registerVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); + nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA); result = request.put_u32(SET_HAL_START_ATTRIBUTE_EVENT_SOCK_PID, event_sock_pid); if (result != WIFI_SUCCESS) { + unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); ALOGV("Hal preInit Failed to put pic = %d", result); return result; } if (result != WIFI_SUCCESS) { + unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); ALOGV("Hal preInit Failed to put pid= %d", result); return result; } @@ -680,6 +683,7 @@ public: result = requestResponse(request); if (result != WIFI_SUCCESS) { + unregisterVendorHandler(GOOGLE_OUI, GOOGLE_DEBUG_RING_EVENT); ALOGE("Failed to register set Hal preInit; result = %d", result); return result; } |