diff options
author | Hans de Goede <hdegoede@redhat.com> | 2014-05-30 12:14:30 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2014-05-30 12:36:11 +0200 |
commit | 4f347f01fa2745b7d00e6e336726c9a329bd6fbb (patch) | |
tree | b6dfdf2427626814142925866e2bc36cc8ca24a9 | |
parent | 507f6c7bdaf7da136663721c392fc6deef16fa49 (diff) | |
download | libusb-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.c | 4 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
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 |