Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(721)

Unified Diff: chrome/browser/extensions/api/usb/usb_api.cc

Issue 11926005: Fix transfer length validation in Usb Api. (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/extensions/api/usb/usb_apitest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/extensions/api/usb/usb_api.cc
===================================================================
--- chrome/browser/extensions/api/usb/usb_api.cc (revision 177716)
+++ chrome/browser/extensions/api/usb/usb_api.cc (working copy)
@@ -62,7 +62,10 @@
static const char* kErrorNoDevice = "No such device.";
static const char* kErrorPermissionDenied =
"Permission to access device was denied";
+static const char* kErrorInvalidTransferLength = "Transfer length must be a "
+ "positive number less than 104,857,600.";
+static const size_t kMaxTransferLength = 100 * 1024 * 1024;
static UsbDevice* device_for_test_ = NULL;
static bool ConvertDirection(const Direction& input,
@@ -129,7 +132,8 @@
static bool GetTransferSize(const T& input, size_t* output) {
if (input.direction == usb::DIRECTION_IN) {
const int* length = input.length.get();
- if (length) {
+ if (length && *length >= 0 &&
+ static_cast<size_t>(*length) < kMaxTransferLength) {
*output = *length;
return true;
}
@@ -143,9 +147,10 @@
}
template<class T>
-static scoped_refptr<net::IOBuffer> CreateBufferForTransfer(const T& input) {
- size_t size = 0;
- if (!GetTransferSize(input, &size))
+static scoped_refptr<net::IOBuffer> CreateBufferForTransfer(
+ const T& input, UsbDevice::TransferDirection direction, size_t size) {
+
+ if (size > kMaxTransferLength)
return NULL;
// Allocate a |size|-bytes buffer, or a one-byte buffer if |size| is 0. This
@@ -153,11 +158,17 @@
// cannot represent a zero-length buffer, while an URB can.
scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(std::max(
static_cast<size_t>(1), size));
- if (!input.data.get())
+
+ if (direction == UsbDevice::INBOUND) {
return buffer;
-
- memcpy(buffer->data(), input.data->data(), size);
- return buffer;
+ } else if (direction == UsbDevice::OUTBOUND) {
+ if (input.data.get() && size <= input.data->size()) {
+ memcpy(buffer->data(), input.data->data(), size);
+ return buffer;
+ }
+ }
+ NOTREACHED();
+ return NULL;
}
static const char* ConvertTransferStatusToErrorString(
@@ -475,8 +486,7 @@
UsbDevice::TransferDirection direction;
UsbDevice::TransferRequestType request_type;
UsbDevice::TransferRecipient recipient;
- size_t size;
- scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(transfer);
+ size_t size = 0;
if (!ConvertDirectionSafely(transfer.direction, &direction) ||
!ConvertRequestTypeSafely(transfer.request_type, &request_type) ||
@@ -485,7 +495,14 @@
return;
}
- if (!GetTransferSize(transfer, &size) || !buffer) {
+ if (!GetTransferSize(transfer, &size)) {
+ CompleteWithError(kErrorInvalidTransferLength);
+ return;
+ }
+
+ scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
+ transfer, direction, size);
+ if (!buffer) {
CompleteWithError(kErrorMalformedParameters);
return;
}
@@ -516,15 +533,21 @@
const GenericTransferInfo& transfer = parameters_->transfer_info;
UsbDevice::TransferDirection direction;
- size_t size;
- scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(transfer);
+ size_t size = 0;
if (!ConvertDirectionSafely(transfer.direction, &direction)) {
AsyncWorkCompleted();
return;
}
- if (!GetTransferSize(transfer, &size) || !buffer) {
+ if (!GetTransferSize(transfer, &size)) {
+ CompleteWithError(kErrorInvalidTransferLength);
+ return;
+ }
+
+ scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
+ transfer, direction, size);
+ if (!buffer) {
CompleteWithError(kErrorMalformedParameters);
return;
}
@@ -554,15 +577,21 @@
const GenericTransferInfo& transfer = parameters_->transfer_info;
UsbDevice::TransferDirection direction;
- size_t size;
- scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(transfer);
+ size_t size = 0;
if (!ConvertDirectionSafely(transfer.direction, &direction)) {
AsyncWorkCompleted();
return;
}
- if (!GetTransferSize(transfer, &size) || !buffer) {
+ if (!GetTransferSize(transfer, &size)) {
+ CompleteWithError(kErrorInvalidTransferLength);
+ return;
+ }
+
+ scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
+ transfer, direction, size);
+ if (!buffer) {
CompleteWithError(kErrorMalformedParameters);
return;
}
@@ -592,21 +621,26 @@
const IsochronousTransferInfo& transfer = parameters_->transfer_info;
const GenericTransferInfo& generic_transfer = transfer.transfer_info;
- size_t size;
+ size_t size = 0;
UsbDevice::TransferDirection direction;
- scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
- generic_transfer);
if (!ConvertDirectionSafely(generic_transfer.direction, &direction)) {
AsyncWorkCompleted();
return;
}
- if (!GetTransferSize(generic_transfer, &size) || !buffer) {
- CompleteWithError(kErrorNoDevice);
+ if (!GetTransferSize(generic_transfer, &size)) {
+ CompleteWithError(kErrorInvalidTransferLength);
return;
}
+ scoped_refptr<net::IOBuffer> buffer = CreateBufferForTransfer(
+ generic_transfer, direction, size);
+ if (!buffer) {
+ CompleteWithError(kErrorMalformedParameters);
+ return;
+ }
+
device->device()->IsochronousTransfer(direction, generic_transfer.endpoint,
buffer, size, transfer.packets, transfer.packet_length, 0, base::Bind(
&UsbIsochronousTransferFunction::OnCompleted, this));
« no previous file with comments | « no previous file | chrome/browser/extensions/api/usb/usb_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698