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

Unified Diff: device/devices_app/usb/device_impl.cc

Issue 1369643002: Add configuration and interface permission checks to DeviceImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add new method ot Android USB mocks. Created 5 years, 3 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
Index: device/devices_app/usb/device_impl.cc
diff --git a/device/devices_app/usb/device_impl.cc b/device/devices_app/usb/device_impl.cc
index 1516c76fd14af7b520c74542c070f7297c70aad0..7f64cc6d3e3537de68d28d138e9f8acd0ed2bd9b 100644
--- a/device/devices_app/usb/device_impl.cc
+++ b/device/devices_app/usb/device_impl.cc
@@ -31,38 +31,26 @@ base::Callback<void(Args...)> WrapMojoCallback(
return base::Bind(&CallMojoCallback<Args...>, callback);
}
+void OnPermissionCheckComplete(
+ const base::Callback<void(bool)>& callback,
+ const base::Callback<void(const base::Callback<void(bool)>&)>& action,
+ bool allowed) {
+ if (allowed)
+ action.Run(callback);
+ else
+ callback.Run(false);
+}
+
scoped_refptr<net::IOBuffer> CreateTransferBuffer(size_t size) {
scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(
std::max(static_cast<size_t>(1u), static_cast<size_t>(size)));
return buffer;
}
-} // namespace
-
-DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device,
- mojo::InterfaceRequest<Device> request)
- : binding_(this, request.Pass()), device_(device), weak_factory_(this) {}
-
-DeviceImpl::~DeviceImpl() {
- CloseHandle();
-}
-
-void DeviceImpl::CloseHandle() {
- if (device_handle_)
- device_handle_->Close();
- device_handle_ = nullptr;
-}
-
-void DeviceImpl::OnOpen(const OpenCallback& callback,
- scoped_refptr<UsbDeviceHandle> handle) {
- device_handle_ = handle;
- callback.Run(handle ? OPEN_DEVICE_ERROR_OK : OPEN_DEVICE_ERROR_ACCESS_DENIED);
-}
-
-void DeviceImpl::OnTransferIn(const MojoTransferInCallback& callback,
- UsbTransferStatus status,
- scoped_refptr<net::IOBuffer> buffer,
- size_t buffer_size) {
+void OnTransferIn(const DeviceImpl::MojoTransferInCallback& callback,
+ UsbTransferStatus status,
+ scoped_refptr<net::IOBuffer> buffer,
+ size_t buffer_size) {
mojo::Array<uint8_t> data;
if (buffer) {
// TODO(rockot/reillyg): We should change UsbDeviceHandle to use a
@@ -75,15 +63,58 @@ void DeviceImpl::OnTransferIn(const MojoTransferInCallback& callback,
callback.Run(mojo::ConvertTo<TransferStatus>(status), data.Pass());
}
-void DeviceImpl::OnTransferOut(const MojoTransferOutCallback& callback,
- UsbTransferStatus status,
- scoped_refptr<net::IOBuffer> buffer,
- size_t buffer_size) {
+void OnControlTransferInPermissionCheckComplete(
+ scoped_refptr<UsbDeviceHandle> device_handle,
+ ControlTransferParamsPtr params,
+ int length,
+ int timeout,
+ const Device::ControlTransferInCallback& callback,
+ bool allowed) {
+ if (allowed) {
+ scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length);
+ device_handle->ControlTransfer(
+ USB_DIRECTION_INBOUND,
+ mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type),
+ mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient),
+ params->request, params->value, params->index, buffer, length, timeout,
+ base::Bind(&OnTransferIn, callback));
+ } else {
+ mojo::Array<uint8_t> data;
+ callback.Run(TRANSFER_STATUS_PERMISSION_DENIED, data.Pass());
+ }
+}
+
+void OnTransferOut(const DeviceImpl::MojoTransferOutCallback& callback,
+ UsbTransferStatus status,
+ scoped_refptr<net::IOBuffer> buffer,
+ size_t buffer_size) {
callback.Run(mojo::ConvertTo<TransferStatus>(status));
}
-void DeviceImpl::OnIsochronousTransferIn(
- const IsochronousTransferInCallback& callback,
+void OnControlTransferOutPermissionCheckComplete(
+ scoped_refptr<UsbDeviceHandle> device_handle,
+ ControlTransferParamsPtr params,
+ mojo::Array<uint8_t> data,
+ int timeout,
+ const Device::ControlTransferOutCallback& callback,
+ bool allowed) {
+ if (allowed) {
+ scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size());
+ const std::vector<uint8_t>& storage = data.storage();
+ std::copy(storage.begin(), storage.end(), buffer->data());
+ device_handle->ControlTransfer(
+ USB_DIRECTION_OUTBOUND,
+ mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type),
+ mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient),
+ params->request, params->value, params->index, buffer, data.size(),
+ timeout, base::Bind(&OnTransferOut, callback));
+ } else {
+ callback.Run(TRANSFER_STATUS_PERMISSION_DENIED);
+ }
+}
+
+void OnIsochronousTransferIn(
+ const Device::IsochronousTransferInCallback& callback,
uint32_t packet_size,
UsbTransferStatus status,
scoped_refptr<net::IOBuffer> buffer,
@@ -102,14 +133,81 @@ void DeviceImpl::OnIsochronousTransferIn(
callback.Run(mojo::ConvertTo<TransferStatus>(status), packets.Pass());
}
-void DeviceImpl::OnIsochronousTransferOut(
- const MojoTransferOutCallback& callback,
+void OnIsochronousTransferOut(
+ const Device::IsochronousTransferOutCallback& callback,
UsbTransferStatus status,
scoped_refptr<net::IOBuffer> buffer,
size_t buffer_size) {
callback.Run(mojo::ConvertTo<TransferStatus>(status));
}
+} // namespace
+
+DeviceImpl::DeviceImpl(scoped_refptr<UsbDevice> device,
+ PermissionProviderPtr permission_provider,
+ mojo::InterfaceRequest<Device> request)
+ : binding_(this, request.Pass()),
+ device_(device),
+ permission_provider_(permission_provider.Pass()),
+ weak_factory_(this) {
+ // This object owns itself and will be destroyed if either the message pipe
+ // it is bound to is closed or the PermissionProvider it depends on is
+ // unavailable.
+ binding_.set_connection_error_handler([this]() { delete this; });
+ permission_provider_.set_connection_error_handler([this]() { delete this; });
+}
+
+DeviceImpl::~DeviceImpl() {
+ CloseHandle();
+}
+
+void DeviceImpl::CloseHandle() {
+ if (device_handle_)
+ device_handle_->Close();
+ device_handle_ = nullptr;
+}
+
+void DeviceImpl::HasControlTransferPermission(
+ ControlTransferRecipient recipient,
+ uint16_t index,
+ const base::Callback<void(bool)>& callback) {
+ DCHECK(device_handle_);
+ const UsbConfigDescriptor* config = device_->GetActiveConfiguration();
+
+ if (recipient == CONTROL_TRANSFER_RECIPIENT_INTERFACE ||
+ recipient == CONTROL_TRANSFER_RECIPIENT_ENDPOINT) {
+ if (!config) {
+ callback.Run(false);
+ return;
+ }
+
+ uint8_t interface_number = index & 0xff;
+ if (recipient == CONTROL_TRANSFER_RECIPIENT_ENDPOINT) {
+ if (!device_handle_->FindInterfaceByEndpoint(index & 0xff,
+ &interface_number)) {
+ callback.Run(false);
+ return;
+ }
+ }
+
+ permission_provider_->HasInterfacePermission(
+ interface_number, config->configuration_value,
+ DeviceInfo::From(*device_), callback);
+ } else if (config) {
+ permission_provider_->HasConfigurationPermission(
+ config->configuration_value, DeviceInfo::From(*device_), callback);
+ } else {
+ // Client must already have device permission to have gotten this far.
+ callback.Run(true);
+ }
+}
+
+void DeviceImpl::OnOpen(const OpenCallback& callback,
+ scoped_refptr<UsbDeviceHandle> handle) {
+ device_handle_ = handle;
+ callback.Run(handle ? OPEN_DEVICE_ERROR_OK : OPEN_DEVICE_ERROR_ACCESS_DENIED);
+}
+
void DeviceImpl::GetDeviceInfo(const GetDeviceInfoCallback& callback) {
callback.Run(DeviceInfo::From(*device_));
}
@@ -136,7 +234,12 @@ void DeviceImpl::SetConfiguration(uint8_t value,
return;
}
- device_handle_->SetConfiguration(value, WrapMojoCallback(callback));
+ auto set_configuration =
+ base::Bind(&UsbDeviceHandle::SetConfiguration, device_handle_, value);
+ permission_provider_->HasConfigurationPermission(
+ value, DeviceInfo::From(*device_),
+ base::Bind(&OnPermissionCheckComplete, WrapMojoCallback(callback),
+ set_configuration));
}
void DeviceImpl::ClaimInterface(uint8_t interface_number,
@@ -146,7 +249,18 @@ void DeviceImpl::ClaimInterface(uint8_t interface_number,
return;
}
- device_handle_->ClaimInterface(interface_number, WrapMojoCallback(callback));
+ const UsbConfigDescriptor* config = device_->GetActiveConfiguration();
+ if (!config) {
+ callback.Run(false);
+ return;
+ }
+
+ auto claim_interface = base::Bind(&UsbDeviceHandle::ClaimInterface,
+ device_handle_, interface_number);
+ permission_provider_->HasInterfacePermission(
+ interface_number, config->configuration_value, DeviceInfo::From(*device_),
+ base::Bind(&OnPermissionCheckComplete, WrapMojoCallback(callback),
+ claim_interface));
}
void DeviceImpl::ReleaseInterface(uint8_t interface_number,
@@ -200,14 +314,12 @@ void DeviceImpl::ControlTransferIn(ControlTransferParamsPtr params,
return;
}
- scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length);
- device_handle_->ControlTransfer(
- USB_DIRECTION_INBOUND,
- mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type),
- mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient),
- params->request, params->value, params->index, buffer, length, timeout,
- base::Bind(&DeviceImpl::OnTransferIn, weak_factory_.GetWeakPtr(),
- callback));
+ ControlTransferRecipient recipient = params->recipient;
+ uint16_t index = params->index;
+ HasControlTransferPermission(
+ recipient, index,
+ base::Bind(&OnControlTransferInPermissionCheckComplete, device_handle_,
+ base::Passed(&params), length, timeout, callback));
}
void DeviceImpl::ControlTransferOut(
@@ -220,16 +332,12 @@ void DeviceImpl::ControlTransferOut(
return;
}
- scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size());
- const std::vector<uint8_t>& storage = data.storage();
- std::copy(storage.begin(), storage.end(), buffer->data());
- device_handle_->ControlTransfer(
- USB_DIRECTION_OUTBOUND,
- mojo::ConvertTo<UsbDeviceHandle::TransferRequestType>(params->type),
- mojo::ConvertTo<UsbDeviceHandle::TransferRecipient>(params->recipient),
- params->request, params->value, params->index, buffer, data.size(),
- timeout, base::Bind(&DeviceImpl::OnTransferOut,
- weak_factory_.GetWeakPtr(), callback));
+ ControlTransferRecipient recipient = params->recipient;
+ uint16_t index = params->index;
+ HasControlTransferPermission(
+ recipient, index, base::Bind(&OnControlTransferOutPermissionCheckComplete,
+ device_handle_, base::Passed(&params),
+ base::Passed(&data), timeout, callback));
}
void DeviceImpl::GenericTransferIn(uint8_t endpoint_number,
@@ -243,10 +351,9 @@ void DeviceImpl::GenericTransferIn(uint8_t endpoint_number,
uint8_t endpoint_address = endpoint_number | 0x80;
scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(length);
- device_handle_->GenericTransfer(
- USB_DIRECTION_INBOUND, endpoint_address, buffer, length, timeout,
- base::Bind(&DeviceImpl::OnTransferIn, weak_factory_.GetWeakPtr(),
- callback));
+ device_handle_->GenericTransfer(USB_DIRECTION_INBOUND, endpoint_address,
+ buffer, length, timeout,
+ base::Bind(&OnTransferIn, callback));
}
void DeviceImpl::GenericTransferOut(
@@ -263,10 +370,9 @@ void DeviceImpl::GenericTransferOut(
scoped_refptr<net::IOBuffer> buffer = CreateTransferBuffer(data.size());
const std::vector<uint8_t>& storage = data.storage();
std::copy(storage.begin(), storage.end(), buffer->data());
- device_handle_->GenericTransfer(
- USB_DIRECTION_OUTBOUND, endpoint_address, buffer, data.size(), timeout,
- base::Bind(&DeviceImpl::OnTransferOut, weak_factory_.GetWeakPtr(),
- callback));
+ device_handle_->GenericTransfer(USB_DIRECTION_OUTBOUND, endpoint_address,
+ buffer, data.size(), timeout,
+ base::Bind(&OnTransferOut, callback));
}
void DeviceImpl::IsochronousTransferIn(
@@ -286,8 +392,7 @@ void DeviceImpl::IsochronousTransferIn(
device_handle_->IsochronousTransfer(
USB_DIRECTION_INBOUND, endpoint_address, buffer, transfer_size,
num_packets, packet_length, timeout,
- base::Bind(&DeviceImpl::OnIsochronousTransferIn,
- weak_factory_.GetWeakPtr(), callback, packet_length));
+ base::Bind(&OnIsochronousTransferIn, callback, packet_length));
}
void DeviceImpl::IsochronousTransferOut(
@@ -318,8 +423,7 @@ void DeviceImpl::IsochronousTransferOut(
device_handle_->IsochronousTransfer(
USB_DIRECTION_OUTBOUND, endpoint_address, buffer, transfer_size,
static_cast<uint32_t>(packets.size()), packet_size, timeout,
- base::Bind(&DeviceImpl::OnIsochronousTransferOut,
- weak_factory_.GetWeakPtr(), callback));
+ base::Bind(&OnIsochronousTransferOut, callback));
}
} // namespace usb

Powered by Google App Engine
This is Rietveld 408576698