aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2013-08-06 13:16:16 -0700
committerNathan Hjelm <hjelmn@me.com>2013-08-07 20:45:43 -0600
commitc848e5b72a1670a33eb84f210b951177a3de19e9 (patch)
tree724d37088082fc8979f8bd8e0c4a77ff15b55722
parent69d88b7fef75aef4ab99b1086c5be84626aedceb (diff)
downloadandroid_external_libusbx-c848e5b72a1670a33eb84f210b951177a3de19e9.tar.gz
android_external_libusbx-c848e5b72a1670a33eb84f210b951177a3de19e9.tar.bz2
android_external_libusbx-c848e5b72a1670a33eb84f210b951177a3de19e9.zip
Core: Fix potential segfault caused by using freed memory
When a transfer is submitted, the device is referenced in libusb_submit_transfer() and unreferenced in usbi_handle_transfer_completion(). This transfer could potentially be freed by any user callback, or is freed by libusb if LIBUSB_TRANSFER_FREE_TRANSFER is set in the flags. The call to unreference the device uses this potentially freed memory. Reading the device handle beforehand will prevent this disaster.
-rw-r--r--libusb/io.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/libusb/io.c b/libusb/io.c
index 64712c2..d766ccf 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -1524,6 +1524,7 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
struct libusb_transfer *transfer =
USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
struct libusb_context *ctx = TRANSFER_CTX(transfer);
+ struct libusb_device_handle *handle = transfer->dev_handle;
uint8_t flags;
int r = 0;
@@ -1564,7 +1565,7 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer,
usbi_mutex_lock(&ctx->event_waiters_lock);
usbi_cond_broadcast(&ctx->event_waiters_cond);
usbi_mutex_unlock(&ctx->event_waiters_lock);
- libusb_unref_device(transfer->dev_handle->dev);
+ libusb_unref_device(handle->dev);
return 0;
}