diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-27 17:46:06 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-29 18:17:52 -0400 |
commit | cc1a7c4bae28215d042fb9f00dcb77dd65abafdf (patch) | |
tree | eca5e1a56ff3e344048b5a50f72f9b3bf5e488a5 /drivers/usb/core/devio.c | |
parent | 30138384dae74cdd5694615c098a19af984a3dda (diff) | |
download | linux-cc1a7c4bae28215d042fb9f00dcb77dd65abafdf.tar.bz2 |
usbdevfs: get rid of field-by-field copyin
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r-- | drivers/usb/core/devio.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index cfc3cff6e8d5..b2316c03f330 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1966,27 +1966,21 @@ static int proc_disconnectsignal_compat(struct usb_dev_state *ps, void __user *a static int get_urb32(struct usbdevfs_urb *kurb, struct usbdevfs_urb32 __user *uurb) { - __u32 uptr; - if (!access_ok(VERIFY_READ, uurb, sizeof(*uurb)) || - __get_user(kurb->type, &uurb->type) || - __get_user(kurb->endpoint, &uurb->endpoint) || - __get_user(kurb->status, &uurb->status) || - __get_user(kurb->flags, &uurb->flags) || - __get_user(kurb->buffer_length, &uurb->buffer_length) || - __get_user(kurb->actual_length, &uurb->actual_length) || - __get_user(kurb->start_frame, &uurb->start_frame) || - __get_user(kurb->number_of_packets, &uurb->number_of_packets) || - __get_user(kurb->error_count, &uurb->error_count) || - __get_user(kurb->signr, &uurb->signr)) + struct usbdevfs_urb32 urb32; + if (copy_from_user(&urb32, uurb, sizeof(*uurb))) return -EFAULT; - - if (__get_user(uptr, &uurb->buffer)) - return -EFAULT; - kurb->buffer = compat_ptr(uptr); - if (__get_user(uptr, &uurb->usercontext)) - return -EFAULT; - kurb->usercontext = compat_ptr(uptr); - + kurb->type = urb32.type; + kurb->endpoint = urb32.endpoint; + kurb->status = urb32.status; + kurb->flags = urb32.flags; + kurb->buffer = compat_ptr(urb32.buffer); + kurb->buffer_length = urb32.buffer_length; + kurb->actual_length = urb32.actual_length; + kurb->start_frame = urb32.start_frame; + kurb->number_of_packets = urb32.number_of_packets; + kurb->error_count = urb32.error_count; + kurb->signr = urb32.signr; + kurb->usercontext = compat_ptr(urb32.usercontext); return 0; } @@ -2198,18 +2192,14 @@ static int proc_ioctl_default(struct usb_dev_state *ps, void __user *arg) #ifdef CONFIG_COMPAT static int proc_ioctl_compat(struct usb_dev_state *ps, compat_uptr_t arg) { - struct usbdevfs_ioctl32 __user *uioc; + struct usbdevfs_ioctl32 ioc32; struct usbdevfs_ioctl ctrl; - u32 udata; - uioc = compat_ptr((long)arg); - if (!access_ok(VERIFY_READ, uioc, sizeof(*uioc)) || - __get_user(ctrl.ifno, &uioc->ifno) || - __get_user(ctrl.ioctl_code, &uioc->ioctl_code) || - __get_user(udata, &uioc->data)) + if (copy_from_user(&ioc32, compat_ptr(arg), sizeof(ioc32))) return -EFAULT; - ctrl.data = compat_ptr(udata); - + ctrl.ifno = ioc32.ifno; + ctrl.ioctl_code = ioc32.ioctl_code; + ctrl.data = compat_ptr(ioc32.data); return proc_ioctl(ps, &ctrl); } #endif |