summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2015-05-07 12:45:33 -0700
committerChris Dickens <christopher.a.dickens@gmail.com>2015-05-07 12:45:33 -0700
commit9b2c8abf134b96b6c1798615e0ed17991b8c0692 (patch)
tree5a17bfc01c67fbe0c58533fb94a87ecf3b03f517
parent02f7f859eec8aab0b680ad18d3aabd1fe24edb28 (diff)
downloadlibusb-9b2c8abf134b96b6c1798615e0ed17991b8c0692.tar.gz
core: Copy transfer timeout to local variable before using
The flying_transfers lock is taken in libusb_get_next_timeout() to find the transfer with the next timeout, but the transfer was being used outside of the lock, resulting in the possibility that the transfer had been removed from the list and freed at the time it was used. Issue reported by Michel Sanches. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--libusb/io.c13
-rw-r--r--libusb/version_nano.h2
2 files changed, 6 insertions, 9 deletions
diff --git a/libusb/io.c b/libusb/io.c
index c71a2a2..255eab0 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -2489,9 +2489,8 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
struct usbi_transfer *transfer;
struct timespec cur_ts;
struct timeval cur_tv;
- struct timeval *next_timeout;
+ struct timeval next_timeout = { 0, 0 };
int r;
- int found = 0;
USBI_GET_CONTEXT(ctx);
if (usbi_using_timerfd(ctx))
@@ -2513,18 +2512,16 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
if (!timerisset(&transfer->timeout))
break;
- found = 1;
+ next_timeout = transfer->timeout;
break;
}
usbi_mutex_unlock(&ctx->flying_transfers_lock);
- if (!found) {
+ if (!timerisset(&next_timeout)) {
usbi_dbg("no URB with timeout or all handled by OS; no timeout!");
return 0;
}
- next_timeout = &transfer->timeout;
-
r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
if (r < 0) {
usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);
@@ -2532,11 +2529,11 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
}
TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
- if (!timercmp(&cur_tv, next_timeout, <)) {
+ if (!timercmp(&cur_tv, &next_timeout, <)) {
usbi_dbg("first timeout already expired");
timerclear(tv);
} else {
- timersub(next_timeout, &cur_tv, tv);
+ timersub(&next_timeout, &cur_tv, tv);
usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec);
}
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 2db3257..11688fe 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10981
+#define LIBUSB_NANO 10982