From aca90a9e9ee16d10d7a23b3b4f5da3b7d6aabb40 Mon Sep 17 00:00:00 2001 From: Giuseppe Piscitelli Date: Wed, 7 Oct 2026 17:09:50 +0200 Subject: [PATCH] preflight: serialize device visibility and notifications Publish device visibility and the attached notification under device_list_mutex, then acquire client_list_mutex in the same order as device removal. Do not notify clients if preflight completes after the device has disappeared. Assisted-by: OpenAI Codex --- src/client.c | 1 - src/device.c | 5 +++-- src/device.h | 2 +- src/preflight.c | 22 +++++++++++----------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/client.c b/src/client.c index 2ac04bfd..96ab5072 100644 --- a/src/client.c +++ b/src/client.c @@ -988,7 +988,6 @@ void client_device_add(struct device_info *dev) { mutex_lock(&client_list_mutex); usbmuxd_log(LL_DEBUG, "client_device_add: id %d, location 0x%x, serial %s", dev->id, dev->location, dev->serial); - device_set_visible(dev->id); FOREACH(struct mux_client *client, &client_list) { if(client->state == CLIENT_LISTEN) send_device_add(client, dev); diff --git a/src/device.c b/src/device.c index ce73718d..66d84db4 100644 --- a/src/device.c +++ b/src/device.c @@ -888,12 +888,13 @@ void device_remove(struct usb_device *usbdev) usbmuxd_log(LL_WARNING, "Cannot find device entry while removing USB device %p on location 0x%x", usbdev, usb_get_location(usbdev)); } -void device_set_visible(int device_id) +void device_set_visible(struct device_info *info) { mutex_lock(&device_list_mutex); FOREACH(struct mux_device *dev, &device_list) { - if(dev->id == device_id) { + if(dev->id == info->id) { dev->visible = 1; + client_device_add(info); break; } } ENDFOREACH diff --git a/src/device.h b/src/device.h index 85703e43..f4a44e2c 100644 --- a/src/device.h +++ b/src/device.h @@ -40,7 +40,7 @@ int device_start_connect(int device_id, uint16_t port, struct mux_client *client void device_client_process(int device_id, struct mux_client *client, short events); void device_abort_connect(int device_id, struct mux_client *client); -void device_set_visible(int device_id); +void device_set_visible(struct device_info *info); void device_set_preflight_cb_data(int device_id, void* data); int device_get_count(int include_hidden); diff --git a/src/preflight.c b/src/preflight.c index 9c57e98b..5715625e 100644 --- a/src/preflight.c +++ b/src/preflight.c @@ -170,7 +170,7 @@ static void* preflight_worker_handle_device_add(void* userdata) // make restore mode devices visible free(type); usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); - client_device_add(info); + device_set_visible(info); goto leave; } free(type); @@ -185,7 +185,7 @@ static void* preflight_worker_handle_device_add(void* userdata) if (lerr == LOCKDOWN_E_SUCCESS) { usbmuxd_log(LL_INFO, "%s: StartSession success for device %s", __func__, _dev->udid); usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); - client_device_add(info); + device_set_visible(info); goto leave; } @@ -260,7 +260,7 @@ static void* preflight_worker_handle_device_add(void* userdata) /* if device is still showing the setup screen it will pair even without trust dialog */ usbmuxd_log(LL_INFO, "%s: Pair success for device %s", __func__, _dev->udid); usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); - client_device_add(info); + device_set_visible(info); goto leave; } } @@ -270,7 +270,7 @@ static void* preflight_worker_handle_device_add(void* userdata) if (lerr != LOCKDOWN_E_SUCCESS) { /* even though we failed, simple mode should still work, so only warn of an error */ usbmuxd_log(LL_INFO, "%s: ERROR: Could not start insecure_notification_proxy on %s, lockdown error %d", __func__, _dev->udid, lerr); - client_device_add(info); + device_set_visible(info); goto leave; } @@ -304,7 +304,7 @@ static void* preflight_worker_handle_device_add(void* userdata) usbmuxd_log(LL_INFO, "%s: Waiting for user to trust this computer on device %s", __func__, _dev->udid); /* make device visible anyways */ - client_device_add(info); + device_set_visible(info); while (cbdata.np && cbdata.is_device_connected && !cbdata.is_finished) { sleep(1); @@ -330,7 +330,7 @@ static void* preflight_worker_handle_device_add(void* userdata) usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); /* make device visible anyways */ - client_device_add(info); + device_set_visible(info); goto leave; } @@ -353,7 +353,7 @@ static void* preflight_worker_handle_device_add(void* userdata) usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); /* emit device added event and thus make device visible to clients */ - client_device_add(info); + device_set_visible(info); } leave: @@ -378,7 +378,7 @@ void preflight_device_remove_cb(void *data) void preflight_worker_device_add(struct device_info* info) { if (info->pid == PID_APPLE_T2_COPROCESSOR || no_preflight == 1) { - client_device_add(info); + device_set_visible(info); return; } @@ -395,12 +395,12 @@ void preflight_worker_device_add(struct device_info* info) if (perr != 0) { free((char*)infocopy->serial); free(infocopy); - usbmuxd_log(LL_ERROR, "ERROR: failed to start preflight worker thread for device %s: %s (%d). Invoking client_device_add() directly but things might not work as expected.", info->serial, strerror(perr), perr); - client_device_add(info); + usbmuxd_log(LL_ERROR, "ERROR: failed to start preflight worker thread for device %s: %s (%d). Invoking device_set_visible() directly but things might not work as expected.", info->serial, strerror(perr), perr); + device_set_visible(info); } else { thread_detach(th); } #else - client_device_add(info); + device_set_visible(info); #endif }