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
commit f1e255d60ae66a9f672ff9a207ee6cd8e33d2679 upstream.

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>

Signed-off-by: khusika <khusikadhamar@gmail.com>
  • Loading branch information
thejh authored and khusika committed Oct 13, 2018
1 parent b471ac9 commit 1cbee2d
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 @@ -413,35 +413,24 @@ static int yurex_release(struct inode *inode, struct file *file)
static ssize_t yurex_read(struct file *file, char *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_buffer, size_t count, loff_t *ppos)
Expand Down

0 comments on commit 1cbee2d

Please sign in to comment.