MTD: Fix bug in fixup_convert_atmel_pri
[linux-2.6-microblaze.git] / drivers / usb / core / devio.c
index 2b68998..218621b 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/usbdevice_fs.h>
 #include <linux/cdev.h>
 #include <linux/notifier.h>
+#include <linux/security.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 #include <linux/moduleparam.h>
@@ -68,6 +69,7 @@ struct async {
        void __user *userbuffer;
        void __user *userurb;
        struct urb *urb;
+       u32 secid;
 };
 
 static int usbfs_snoop = 0;
@@ -134,26 +136,21 @@ static ssize_t usbdev_read(struct file *file, char __user *buf, size_t nbytes, l
        }
 
        if (pos < sizeof(struct usb_device_descriptor)) {
-               struct usb_device_descriptor *desc = kmalloc(sizeof(*desc), GFP_KERNEL);
-               if (!desc) {
-                       ret = -ENOMEM;
-                       goto err;
-               }
-               memcpy(desc, &dev->descriptor, sizeof(dev->descriptor));
-               le16_to_cpus(&desc->bcdUSB);
-               le16_to_cpus(&desc->idVendor);
-               le16_to_cpus(&desc->idProduct);
-               le16_to_cpus(&desc->bcdDevice);
+               struct usb_device_descriptor temp_desc ; /* 18 bytes - fits on the stack */
+
+               memcpy(&temp_desc, &dev->descriptor, sizeof(dev->descriptor));
+               le16_to_cpus(&temp_desc.bcdUSB);
+               le16_to_cpus(&temp_desc.idVendor);
+               le16_to_cpus(&temp_desc.idProduct);
+               le16_to_cpus(&temp_desc.bcdDevice);
 
                len = sizeof(struct usb_device_descriptor) - pos;
                if (len > nbytes)
                        len = nbytes;
-               if (copy_to_user(buf, ((char *)desc) + pos, len)) {
-                       kfree(desc);
+               if (copy_to_user(buf, ((char *)&temp_desc) + pos, len)) {
                        ret = -EFAULT;
                        goto err;
                }
-               kfree(desc);
 
                *ppos += len;
                buf += len;
@@ -317,7 +314,7 @@ static void async_completed(struct urb *urb, struct pt_regs *regs)
                sinfo.si_code = SI_ASYNCIO;
                sinfo.si_addr = as->userurb;
                kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, 
-                                     as->euid);
+                                     as->euid, as->secid);
        }
        snoop(&urb->dev->dev, "urb complete\n");
        snoop_urb(urb, as->userurb);
@@ -498,7 +495,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig
 {
        int ret = 0;
 
-       if (ps->dev->state != USB_STATE_CONFIGURED)
+       if (ps->dev->state != USB_STATE_ADDRESS
+        && ps->dev->state != USB_STATE_CONFIGURED)
                return -EHOSTUNREACH;
        if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
                return 0;
@@ -576,6 +574,7 @@ static int usbdev_open(struct inode *inode, struct file *file)
        ps->disc_euid = current->euid;
        ps->disccontext = NULL;
        ps->ifclaimed = 0;
+       security_task_getsecid(current, &ps->secid);
        wmb();
        list_add_tail(&ps->list, &dev->filelist);
        file->private_data = ps;
@@ -827,8 +826,7 @@ static int proc_connectinfo(struct dev_state *ps, void __user *arg)
 
 static int proc_resetdevice(struct dev_state *ps)
 {
-       return usb_reset_device(ps->dev);
-
+       return usb_reset_composite_device(ps->dev, NULL);
 }
 
 static int proc_setintf(struct dev_state *ps, void __user *arg)
@@ -927,8 +925,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
                                != USB_ENDPOINT_XFER_CONTROL)
                        return -EINVAL;
-               /* min 8 byte setup packet, max arbitrary */
-               if (uurb->buffer_length < 8 || uurb->buffer_length > PAGE_SIZE)
+               /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */
+               if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE))
                        return -EINVAL;
                if (!(dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL)))
                        return -ENOMEM;
@@ -986,7 +984,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                        return -EFAULT;
                }
                for (totlen = u = 0; u < uurb->number_of_packets; u++) {
-                       if (isopkt[u].length > 1023) {
+                       /* arbitrary limit, sufficient for USB 2.0 high-bandwidth iso */
+                       if (isopkt[u].length > 8192) {
                                kfree(isopkt);
                                return -EINVAL;
                        }
@@ -1057,6 +1056,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        as->pid = current->pid;
        as->uid = current->uid;
        as->euid = current->euid;
+       security_task_getsecid(current, &as->secid);
        if (!(uurb->endpoint & USB_DIR_IN)) {
                if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) {
                        free_async(as);