diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-12-09 00:08:47 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-12-09 00:08:47 +0000 |
commit | cf4ee7481de4624ee87e5ae9030376cabc16645c (patch) | |
tree | 9b8784ce3ea705f26ebdb281516a63907d8da047 | |
parent | 9fd87f96ae60ee8981506e446d7a4e29f2971f0b (diff) | |
parent | 1bdf26126fcb64aa491683b7c9f24ffec72da025 (diff) | |
download | wlan-cf4ee7481de4624ee87e5ae9030376cabc16645c.tar.gz |
Snap for 7981408 from 1bdf26126fcb64aa491683b7c9f24ffec72da025 to sc-v2-release
Change-Id: I3c0268047acfced50450cc6f4837348114fc01cc
-rwxr-xr-x | bcmdhd/wifi_hal/common.cpp | 13 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/common.h | 1 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/cpp_bindings.h | 4 | ||||
-rwxr-xr-x | bcmdhd/wifi_hal/wifi_hal.cpp | 31 |
4 files changed, 44 insertions, 5 deletions
diff --git a/bcmdhd/wifi_hal/common.cpp b/bcmdhd/wifi_hal/common.cpp index 887b530..5a9d5ab 100755 --- a/bcmdhd/wifi_hal/common.cpp +++ b/bcmdhd/wifi_hal/common.cpp @@ -166,14 +166,11 @@ void wifi_unregister_handler(wifi_handle handle, int cmd) pthread_mutex_unlock(&info->cb_lock); } -void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd) +void wifi_unregister_vendor_handler_without_lock(wifi_handle handle, uint32_t id, int subcmd) { hal_info *info = (hal_info *)handle; - pthread_mutex_lock(&info->cb_lock); - for (int i = 0; i < info->num_event_cb; i++) { - if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR && info->event_cb[i].vendor_id == id && info->event_cb[i].vendor_subcmd == subcmd) { @@ -185,11 +182,17 @@ void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd) break; } } +} +void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd) +{ + hal_info *info = (hal_info *)handle; + + pthread_mutex_lock(&info->cb_lock); + wifi_unregister_vendor_handler_without_lock(handle, id, subcmd); pthread_mutex_unlock(&info->cb_lock); } - wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd) { hal_info *info = (hal_info *)handle; diff --git a/bcmdhd/wifi_hal/common.h b/bcmdhd/wifi_hal/common.h index d5bc971..9065802 100755 --- a/bcmdhd/wifi_hal/common.h +++ b/bcmdhd/wifi_hal/common.h @@ -424,6 +424,7 @@ wifi_error wifi_register_vendor_handler(wifi_handle handle, uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg); void wifi_unregister_handler(wifi_handle handle, int cmd); +void wifi_unregister_vendor_handler_without_lock(wifi_handle handle, uint32_t id, int subcmd); void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd); wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd); diff --git a/bcmdhd/wifi_hal/cpp_bindings.h b/bcmdhd/wifi_hal/cpp_bindings.h index 456f31c..8b5600a 100755 --- a/bcmdhd/wifi_hal/cpp_bindings.h +++ b/bcmdhd/wifi_hal/cpp_bindings.h @@ -347,6 +347,10 @@ protected: return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this); } + void unregisterVendorHandlerWithoutLock(uint32_t id, int subcmd) { + wifi_unregister_vendor_handler_without_lock(wifiHandle(), id, subcmd); + } + void unregisterVendorHandler(uint32_t id, int subcmd) { wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); } diff --git a/bcmdhd/wifi_hal/wifi_hal.cpp b/bcmdhd/wifi_hal/wifi_hal.cpp index d3ffe57..c83c482 100755 --- a/bcmdhd/wifi_hal/wifi_hal.cpp +++ b/bcmdhd/wifi_hal/wifi_hal.cpp @@ -1043,7 +1043,36 @@ public: : WifiCommand("SetRSSIMonitorCommand", handle, id), mMax_rssi(max_rssi), mMin_rssi (min_rssi), mHandler(eh) { + ALOGI("SetRSSIMonitorCommand %p created", this); + } + + virtual ~SetRSSIMonitorCommand() { + /* + * Mostly, this call will be no effect. However, this could be valid + * when object destroy without calling unregisterVendorHandler(). + * This is added to protect hal crash due to use-after-free. + */ + ALOGI("Try to remove event handler if exist, vendor 0x%0x, subcmd 0x%x", + GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT); + unregisterVendorHandlerWithoutLock(GOOGLE_OUI, GOOGLE_RSSI_MONITOR_EVENT); + ALOGI("SetRSSIMonitorCommand %p destroyed", this); + } + + virtual void addRef() { + int refs = __sync_add_and_fetch(&mRefs, 1); + ALOGI("addRef: WifiCommand %p has %d references", this, refs); + } + + virtual void releaseRef() { + int refs = __sync_sub_and_fetch(&mRefs, 1); + if (refs == 0) { + ALOGI("releaseRef: WifiCommand %p has deleted", this); + delete this; + } else { + ALOGI("releaseRef: WifiCommand %p has %d references", this, refs); } + } + int createRequest(WifiRequest& request, int enable) { int result = request.create(GOOGLE_OUI, WIFI_SUBCMD_SET_RSSI_MONITOR); if (result < 0) { @@ -1759,11 +1788,13 @@ static wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_ NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY); wifi_error result = wifi_register_cmd(handle, id, cmd); if (result != WIFI_SUCCESS) { + ALOGI("wifi_register_cmd() is failed %d", id); cmd->releaseRef(); return result; } result = (wifi_error)cmd->start(); if (result != WIFI_SUCCESS) { + ALOGI("start() is failed %d", id); wifi_unregister_cmd(handle, id); cmd->releaseRef(); return result; |