Fix a crash in Broadcom's HAL
Vinit Deshpande [Tue, 5 Aug 2014 22:35:33 +0000 (15:35 -0700)]
Scan command registers for two events, but then unregisters only for one
leaving a dangling pointer which results in crashes.

Bug: 16820118

Change-Id: Ie5599a4928f3a122c3a3ef538db9ca31c7ca8a22

bcmdhd/wifi_hal/common.cpp
bcmdhd/wifi_hal/gscan.cpp

index 5739d4b..91d45dc 100644 (file)
@@ -105,7 +105,7 @@ void wifi_unregister_handler(wifi_handle handle, int cmd)
                     info->event_cb[i].cb_arg, info->event_cb[i].cb_func, cmd, i);
 
             memmove(&info->event_cb[i], &info->event_cb[i+1],
-                (info->num_event_cb - i) * sizeof(cb_info));
+                (info->num_event_cb - i - 1) * sizeof(cb_info));
             info->num_event_cb--;
             break;
         }
@@ -128,7 +128,7 @@ void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
             ALOGI("Successfully removed event handler %p:%p for vendor 0x%0x, subcmd 0x%0x from %d",
                     info->event_cb[i].cb_arg, info->event_cb[i].cb_func, id, subcmd, i);
             memmove(&info->event_cb[i], &info->event_cb[i+1],
-                (info->num_event_cb - i) * sizeof(cb_info));
+                (info->num_event_cb - i - 1) * sizeof(cb_info));
             info->num_event_cb--;
             break;
         }
@@ -203,7 +203,7 @@ void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd)
             int id = info->cmd[i].id;
             memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i) * sizeof(cmd_info));
             info->num_cmd--;
-            ALOGI("Successfully removed command %d: %p", id, cmd);
+            ALOGI("Successfully removed command %d: %p from %d", id, cmd, i);
             break;
         }
     }
index 61bef2f..844520e 100644 (file)
@@ -608,10 +608,10 @@ public:
         registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
         registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
 
-
         result = requestResponse(request);
         if (result != WIFI_SUCCESS) {
             ALOGE("failed to start scan; result = %d", result);
+            registerVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
             unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
             return result;
         }
@@ -634,6 +634,7 @@ public:
             }
         }
 
+        unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_COMPLETE_SCAN);
         unregisterVendorHandler(GOOGLE_OUI, GSCAN_EVENT_SCAN_RESULTS_AVAILABLE);
         disableFullScanResultsIfRequired();