[PATCH] usb-devio: Properly do access_ok() checks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



access_ok() checks must be done on every part of the userspace structure that
is accessed. If access_ok() on one part of the struct succeeded, it does not imply
it will succeed on other parts of the struct. (Does depend on the architecture
implementation of access_ok()).

This changes the __get_user() users to first check access_ok() on the data structure.

Signed-off-by: Michael Buesch <mb@xxxxxxxxx>
Cc: stable@xxxxxxxxxx

---
 drivers/usb/core/devio.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

--- linux-2.6.orig/drivers/usb/core/devio.c
+++ linux-2.6/drivers/usb/core/devio.c
@@ -1314,21 +1314,22 @@ static int proc_reapurbnonblock(struct d
 		return -EAGAIN;
 	return processcompl(as, (void __user * __user *)arg);
 }
 
 #ifdef CONFIG_COMPAT
 
 static int get_urb32(struct usbdevfs_urb *kurb,
 		     struct usbdevfs_urb32 __user *uurb)
 {
 	__u32  uptr;
-	if (get_user(kurb->type, &uurb->type) ||
+	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))
 		return -EFAULT;
@@ -1529,22 +1530,23 @@ static int proc_ioctl_default(struct dev
 }
 
 #ifdef CONFIG_COMPAT
 static int proc_ioctl_compat(struct dev_state *ps, compat_uptr_t arg)
 {
 	struct usbdevfs_ioctl32 __user *uioc;
 	struct usbdevfs_ioctl ctrl;
 	u32 udata;
 
 	uioc = compat_ptr((long)arg);
-	if (get_user(ctrl.ifno, &uioc->ifno) ||
-	    get_user(ctrl.ioctl_code, &uioc->ioctl_code) ||
+	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))
 		return -EFAULT;
 	ctrl.data = compat_ptr(udata);
 
 	return proc_ioctl(ps, &ctrl);
 }
 #endif
 
 /*
  * NOTE:  All requests here that have interface numbers as parameters


-- 
Greetings, Michael.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux