Commit b2715801 authored by Reilly Grant's avatar Reilly Grant Committed by Commit Bot

[libusb] Fix racy UAF in libusb_get_next_timeout

The usbi_transfer object should not be accessed after dropping the
flying_transfers lock as it could be freed by another thread. The simple
fix is to copy the timeout from the transfer rather than holding a
pointer to it.

Bug: 1017020
Change-Id: I00c349caf2e87b79c8e6f89f35fda673cf47e9fa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1901355Reviewed-by: default avatarOvidio de Jesús Ruiz-Henríquez <odejesush@chromium.org>
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#713532}
parent e266bcd7
...@@ -2331,7 +2331,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx, ...@@ -2331,7 +2331,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
struct usbi_transfer *transfer; struct usbi_transfer *transfer;
struct timespec cur_ts; struct timespec cur_ts;
struct timeval cur_tv; struct timeval cur_tv;
struct timeval *next_timeout; struct timeval next_timeout;
int r; int r;
int found = 0; int found = 0;
...@@ -2356,6 +2356,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx, ...@@ -2356,6 +2356,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
continue; continue;
found = 1; found = 1;
next_timeout = transfer->timeout;
break; break;
} }
usbi_mutex_unlock(&ctx->flying_transfers_lock); usbi_mutex_unlock(&ctx->flying_transfers_lock);
...@@ -2365,8 +2366,6 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx, ...@@ -2365,8 +2366,6 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
return 0; return 0;
} }
next_timeout = &transfer->timeout;
r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts); r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts);
if (r < 0) { if (r < 0) {
usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno); usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);
...@@ -2374,11 +2373,11 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx, ...@@ -2374,11 +2373,11 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
} }
TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts); 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"); usbi_dbg("first timeout already expired");
timerclear(tv); timerclear(tv);
} else { } 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); usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment