Skip to content

Commit

Permalink
USB: yurex: fix out-of-bounds uaccess in read handler
Browse files Browse the repository at this point in the history
In general, accessing userspace memory beyond the length of the supplied
buffer in VFS read/write handlers can lead to both kernel memory corruption
(via kernel_read()/kernel_write(), which can e.g. be triggered via
sys_splice()) and privilege escalation inside userspace.

Fix it by using simple_read_from_buffer() instead of custom logic.

Fixes: 6bc235a ("USB: add driver for Meywa-Denki & Kayac YUREX")
Signed-off-by: Jann Horn <jannh@google.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
thejh authored and gregkh committed Jul 6, 2018
1 parent bba57ed commit f1e255d
Showing 1 changed file with 6 additions and 17 deletions.
23 changes: 6 additions & 17 deletions drivers/usb/misc/yurex.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,35 +396,24 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,
loff_t *ppos)
{
struct usb_yurex *dev;
int retval = 0;
int bytes_read = 0;
int len = 0;
char in_buffer[20];
unsigned long flags;

dev = file->private_data;

mutex_lock(&dev->io_mutex);
if (!dev->interface) { /* already disconnected */
retval = -ENODEV;
goto exit;
mutex_unlock(&dev->io_mutex);
return -ENODEV;
}

spin_lock_irqsave(&dev->lock, flags);
bytes_read = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
len = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
spin_unlock_irqrestore(&dev->lock, flags);

if (*ppos < bytes_read) {
if (copy_to_user(buffer, in_buffer + *ppos, bytes_read - *ppos))
retval = -EFAULT;
else {
retval = bytes_read - *ppos;
*ppos += bytes_read;
}
}

exit:
mutex_unlock(&dev->io_mutex);
return retval;

return simple_read_from_buffer(buffer, count, ppos, in_buffer, len);
}

static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
Expand Down

0 comments on commit f1e255d

Please # to comment.