When working in PCuABI, user space pointers are capabilities that carry metadata such as bounds and read/write permissions.
In the scenario of the user space submitting a USB Request Block, data transfer between host and device may be handled with DMA. As a consequence, all of the memory accesses bypass the kernel and the user space buffer's capability used to submit the URB is not checked.
This commit adds an explicit capability check for DMA transfers, to ensure that user space has the right permissions and bounds to submit the URB.
Signed-off-by: Luca Vizzarro Luca.Vizzarro@arm.com --- drivers/usb/core/devio.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6972829ec6b5..7bdc309c0420 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1591,7 +1591,6 @@ find_memory_area(struct usb_dev_state *ps, const struct usbdevfs_urb *uurb) { struct usb_memory *usbm = NULL, *iter; unsigned long flags; - /* TODO [PCuABI] - capability checks for uaccess */ unsigned long uurb_start = user_ptr_addr(uurb->buffer);
spin_lock_irqsave(&ps->lock, flags); @@ -1786,6 +1785,13 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb goto error; }
+ if (as->usbm && ( + (is_in && !check_user_ptr_write(uurb->buffer, uurb->buffer_length)) || + (!is_in && !check_user_ptr_read(uurb->buffer, uurb->buffer_length)))) { + ret = -EFAULT; + goto error; + } + /* do not use SG buffers when memory mapped segments * are in use */