summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamon Kim <taekhun.kim@broadcom.com>2021-12-17 13:14:19 +0900
committerRoger Wang <wangroger@google.com>2021-12-22 04:17:11 +0000
commitc835c0483b7168e9582cb12e135d355de494d903 (patch)
tree77def538324d5a7cfe5297de72a5a0715e78ba93
parent1bdf26126fcb64aa491683b7c9f24ffec72da025 (diff)
downloadwlan-c835c0483b7168e9582cb12e135d355de494d903.tar.gz
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-xbcmdhd/wifi_hal/gscan.cpp41
-rw-r--r--bcmdhd/wifi_hal/rtt.cpp1
-rwxr-xr-xbcmdhd/wifi_hal/wifi_logger.cpp6
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;
}