From 36b55e065a2ed59337a81b78a44a147cb8fc5ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Fri, 15 Jan 2021 19:04:54 +0100 Subject: [PATCH] usb_host: check ep pointer before using it The Usb session allows for submitting packets even when the interface in question is not yet enabled. Enabling an interface will configure the udev members properly and is normally done implicitly during processing of an 'ALT_SETTING' packet. In case the interface was not enabled this leads to a page-fault in the USB host-controller driver as 'ep' is NULL. Fixes #3999. --- repos/dde_linux/src/drivers/usb/raw/raw.cc | 15 +++++++++++++++ repos/dde_linux/src/drivers/usb_host/raw.cc | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/repos/dde_linux/src/drivers/usb/raw/raw.cc b/repos/dde_linux/src/drivers/usb/raw/raw.cc index efa86bf29b..564fea4aeb 100644 --- a/repos/dde_linux/src/drivers/usb/raw/raw.cc +++ b/repos/dde_linux/src/drivers/usb/raw/raw.cc @@ -341,6 +341,14 @@ class Usb::Worker : public Genode::Weak_object usb_host_endpoint *ep = read ? _device->udev->ep_in[p.transfer.ep & 0x0f] : _device->udev->ep_out[p.transfer.ep & 0x0f]; + + if (!ep) { + error("could not get ep: ", p.transfer.ep); + dma_free(buf); + p.error = Usb::Packet_descriptor::SUBMIT_ERROR; + return false; + } + polling_interval = ep->desc.bInterval; } else @@ -382,6 +390,13 @@ class Usb::Worker : public Genode::Weak_object Genode::memcpy(buf, _sink->packet_content(p), p.size()); } + if (!ep) { + error("could not get ep: ", p.transfer.ep); + dma_free(buf); + p.error = Usb::Packet_descriptor::SUBMIT_ERROR; + return false; + } + urb *urb = usb_alloc_urb(p.transfer.number_of_packets, GFP_KERNEL); if (!urb) { error("Failed to allocate isochronous URB"); diff --git a/repos/dde_linux/src/drivers/usb_host/raw.cc b/repos/dde_linux/src/drivers/usb_host/raw.cc index 4aa4b213d6..1d3b87684c 100644 --- a/repos/dde_linux/src/drivers/usb_host/raw.cc +++ b/repos/dde_linux/src/drivers/usb_host/raw.cc @@ -352,6 +352,14 @@ class Usb::Worker : public Genode::Weak_object usb_host_endpoint *ep = read ? _device->udev->ep_in[p.transfer.ep & 0x0f] : _device->udev->ep_out[p.transfer.ep & 0x0f]; + + if (!ep) { + error("could not get ep: ", p.transfer.ep); + dma_free(buf); + p.error = Usb::Packet_descriptor::SUBMIT_ERROR; + return false; + } + polling_interval = ep->desc.bInterval; } else @@ -393,6 +401,13 @@ class Usb::Worker : public Genode::Weak_object Genode::memcpy(buf, _sink->packet_content(p), p.size()); } + if (!ep) { + error("could not get ep: ", p.transfer.ep); + dma_free(buf); + p.error = Usb::Packet_descriptor::SUBMIT_ERROR; + return false; + } + urb *urb = usb_alloc_urb(p.transfer.number_of_packets, GFP_KERNEL); if (!urb) { error("Failed to allocate isochronous URB");