summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-05-30 12:14:30 +0200
committerHans de Goede <hdegoede@redhat.com>2014-05-30 12:36:11 +0200
commit4f347f01fa2745b7d00e6e336726c9a329bd6fbb (patch)
treeb6dfdf2427626814142925866e2bc36cc8ca24a9
parent507f6c7bdaf7da136663721c392fc6deef16fa49 (diff)
downloadlibusb-4f347f01fa2745b7d00e6e336726c9a329bd6fbb.tar.gz
libusb_submit_transfer: Fix possible deadlock
Fix a possible deadlock due to a lock ordering reversal, caught by Coverity: *** CID 62579: Thread deadlock (ORDER_REVERSAL) /libusb/io.c: 1451 in libusb_submit_transfer() 1445 r = calculate_timeout(itransfer); 1446 if (r < 0) { 1447 r = LIBUSB_ERROR_OTHER; 1448 goto out; 1449 } 1450 >>> CID 62579: Thread deadlock (ORDER_REVERSAL) >>> Calling "pthread_mutex_lock" acquires lock "libusb_context.flying_transfers_lock" while holding lock "usbi_transfer.lock" (count: 1 / 4). 1451 usbi_mutex_lock(&ctx->flying_transfers_lock); 1452 r = add_to_flying_list(itransfer); 1453 if (r == LIBUSB_SUCCESS) { 1454 r = usbi_backend->submit_transfer(itransfer); 1455 } 1456 if (r != LIBUSB_SUCCESS) { Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--libusb/io.c4
-rw-r--r--libusb/version_nano.h2
2 files changed, 3 insertions, 3 deletions
diff --git a/libusb/io.c b/libusb/io.c
index 6b95441..5c51d73 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -1439,6 +1439,7 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
int r;
int updated_fds;
+ usbi_mutex_lock(&ctx->flying_transfers_lock);
usbi_mutex_lock(&itransfer->lock);
itransfer->transferred = 0;
itransfer->flags = 0;
@@ -1448,7 +1449,6 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
goto out;
}
- usbi_mutex_lock(&ctx->flying_transfers_lock);
r = add_to_flying_list(itransfer);
if (r == LIBUSB_SUCCESS) {
r = usbi_backend->submit_transfer(itransfer);
@@ -1457,13 +1457,13 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer)
list_del(&itransfer->list);
arm_timerfd_for_next_timeout(ctx);
}
- usbi_mutex_unlock(&ctx->flying_transfers_lock);
/* keep a reference to this device */
libusb_ref_device(transfer->dev_handle->dev);
out:
updated_fds = (itransfer->flags & USBI_TRANSFER_UPDATED_FDS);
usbi_mutex_unlock(&itransfer->lock);
+ usbi_mutex_unlock(&ctx->flying_transfers_lock);
if (updated_fds)
usbi_fd_notification(ctx);
return r;
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index c742cf2..96ccb69 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10898
+#define LIBUSB_NANO 10899