diff options
| author | 2019-10-07 21:19:48 +0200 | |
|---|---|---|
| committer | 2019-10-07 21:19:48 +0200 | |
| commit | 7a1110f5c13e7249062da952e1ac4de1b56d4a4e (patch) | |
| tree | 7913b0d145b33268d084b3301d01035eab032b1a | |
| parent | 135ab5253879c197edae416b523e01aad4e13d98 (diff) | |
| download | usbmuxd-7a1110f5c13e7249062da952e1ac4de1b56d4a4e.tar.gz usbmuxd-7a1110f5c13e7249062da952e1ac4de1b56d4a4e.tar.bz2 | |
preflight: Prevent possible UaF if usb device is removed while preflight is in progress
The device serial number is only used by reference, however since the preflight helper
runs in a separate thread the usb device might be invalidated before the preflight operation
is complete, leading to a use-after-free when passing on the device info, followed by accessing
the device serial number. By copying the serial number this can be avoided.
| -rw-r--r-- | src/preflight.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/src/preflight.c b/src/preflight.c index f46786e..86a51cf 100644 --- a/src/preflight.c +++ b/src/preflight.c | |||
| @@ -337,6 +337,7 @@ leave: | |||
| 337 | if (dev) | 337 | if (dev) |
| 338 | idevice_free(dev); | 338 | idevice_free(dev); |
| 339 | 339 | ||
| 340 | free((char*)info->serial); | ||
| 340 | free(info); | 341 | free(info); |
| 341 | 342 | ||
| 342 | return NULL; | 343 | return NULL; |
| @@ -353,6 +354,9 @@ void preflight_worker_device_add(struct device_info* info) | |||
| 353 | struct device_info *infocopy = (struct device_info*)malloc(sizeof(struct device_info)); | 354 | struct device_info *infocopy = (struct device_info*)malloc(sizeof(struct device_info)); |
| 354 | 355 | ||
| 355 | memcpy(infocopy, info, sizeof(struct device_info)); | 356 | memcpy(infocopy, info, sizeof(struct device_info)); |
| 357 | if (info->serial) { | ||
| 358 | infocopy->serial = strdup(info->serial); | ||
| 359 | } | ||
| 356 | 360 | ||
| 357 | pthread_t th; | 361 | pthread_t th; |
| 358 | pthread_attr_t attr; | 362 | pthread_attr_t attr; |
| @@ -362,6 +366,7 @@ void preflight_worker_device_add(struct device_info* info) | |||
| 362 | 366 | ||
| 363 | int perr = pthread_create(&th, &attr, preflight_worker_handle_device_add, infocopy); | 367 | int perr = pthread_create(&th, &attr, preflight_worker_handle_device_add, infocopy); |
| 364 | if (perr != 0) { | 368 | if (perr != 0) { |
| 369 | free((char*)infocopy->serial); | ||
| 365 | free(infocopy); | 370 | free(infocopy); |
| 366 | 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); | 371 | 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); |
| 367 | client_device_add(info); | 372 | client_device_add(info); |
