From 408aa0a1f81ab4d59c0c7891e59c3ed5256ee36b Mon Sep 17 00:00:00 2001 From: Roman Leonov Date: Wed, 14 Aug 2024 13:33:09 +0200 Subject: [PATCH] fix(usb_host_hid): Fixed using the memory after being freed --- host/class/hid/usb_host_hid/hid_host.c | 42 +++++--------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/host/class/hid/usb_host_hid/hid_host.c b/host/class/hid/usb_host_hid/hid_host.c index 650aa376..c1e4b242 100644 --- a/host/class/hid/usb_host_hid/hid_host.c +++ b/host/class/hid/usb_host_hid/hid_host.c @@ -514,35 +514,6 @@ static bool hid_host_device_init_attempt(uint8_t dev_addr) return is_hid_device; } -/** - * @brief USB device was removed we need to shutdown HID Interface - * - * @param[in] hid_dev_handle Handle of the HID device to close - * @return esp_err_t - */ -static esp_err_t hid_host_interface_shutdown(hid_host_device_handle_t hid_dev_handle) -{ - hid_iface_t *hid_iface = get_iface_by_handle(hid_dev_handle); - - HID_RETURN_ON_INVALID_ARG(hid_iface); - - if (hid_iface->user_cb) { - // Let user handle the remove process - hid_iface->state = HID_INTERFACE_STATE_WAIT_USER_DELETION; - hid_host_user_interface_callback(hid_iface, HID_HOST_INTERFACE_EVENT_DISCONNECTED); - } else { - // Remove HID Interface from the list right now - ESP_LOGD(TAG, "Remove addr %d, iface %d from list", - hid_iface->dev_params.addr, - hid_iface->dev_params.iface_num); - HID_ENTER_CRITICAL(); - _hid_host_remove_interface(hid_iface); - HID_EXIT_CRITICAL(); - } - - return ESP_OK; -} - /** * @brief Deinit USB device by handle * @@ -566,8 +537,6 @@ static esp_err_t hid_host_device_disconnected(usb_device_handle_t dev_hdl) if (hid_iface_curr->parent && (hid_iface_curr->parent->dev_addr == hid_device->dev_addr)) { HID_RETURN_ON_ERROR( hid_host_device_close(hid_iface_curr), "Unable to close device"); - HID_RETURN_ON_ERROR( hid_host_interface_shutdown(hid_iface_curr), - "Unable to shutdown interface"); } HID_ENTER_CRITICAL(); hid_iface_curr = hid_iface_next; @@ -1230,7 +1199,7 @@ esp_err_t hid_host_device_close(hid_host_device_handle_t hid_dev_handle) HID_RETURN_ON_INVALID_ARG(hid_iface); - ESP_LOGD(TAG, "Close addr %d, iface %d, state %d", + ESP_LOGI(TAG, "Close addr %d, iface %d, state %d", hid_iface->dev_params.addr, hid_iface->dev_params.iface_num, hid_iface->state); @@ -1249,12 +1218,17 @@ esp_err_t hid_host_device_close(hid_host_device_handle_t hid_dev_handle) hid_iface->report_desc = NULL; } - if (HID_INTERFACE_STATE_WAIT_USER_DELETION == hid_iface->state) { + if (hid_iface->user_cb && hid_iface->state != HID_INTERFACE_STATE_WAIT_USER_DELETION) { + // Let user handle the remove process and wait for next hid_host_device_close() call + hid_iface->state = HID_INTERFACE_STATE_WAIT_USER_DELETION; + hid_host_user_interface_callback(hid_iface, HID_HOST_INTERFACE_EVENT_DISCONNECTED); + } else { + // Second call hid_iface->user_cb = NULL; hid_iface->user_cb_arg = NULL; /* Remove Interface from the list */ - ESP_LOGD(TAG, "User Remove addr %d, iface %d from list", + ESP_LOGD(TAG, "Remove addr %d, iface %d from list", hid_iface->dev_params.addr, hid_iface->dev_params.iface_num); HID_ENTER_CRITICAL();