#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>
void __user *userbuffer;
void __user *userurb;
struct urb *urb;
+ u32 secid;
};
static int usbfs_snoop = 0;
}
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;
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);
{
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;
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;
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)
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;
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;
}
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);