summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-12-09 00:08:47 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-12-09 00:08:47 +0000
commitcf4ee7481de4624ee87e5ae9030376cabc16645c (patch)
tree9b8784ce3ea705f26ebdb281516a63907d8da047
parent9fd87f96ae60ee8981506e446d7a4e29f2971f0b (diff)
parent1bdf26126fcb64aa491683b7c9f24ffec72da025 (diff)
downloadwlan-cf4ee7481de4624ee87e5ae9030376cabc16645c.tar.gz
Snap for 7981408 from 1bdf26126fcb64aa491683b7c9f24ffec72da025 to sc-v2-release
Change-Id: I3c0268047acfced50450cc6f4837348114fc01cc
-rwxr-xr-xbcmdhd/wifi_hal/common.cpp13
-rwxr-xr-xbcmdhd/wifi_hal/common.h1
-rwxr-xr-xbcmdhd/wifi_hal/cpp_bindings.h4
-rwxr-xr-xbcmdhd/wifi_hal/wifi_hal.cpp31
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;