diff options
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r-- | drivers/usb/core/devio.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index c88c4fb9459..71dc5d768fa 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -49,14 +49,14 @@ #include <linux/security.h> #include <linux/user_namespace.h> #include <linux/scatterlist.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/byteorder.h> #include <linux/moduleparam.h> #include "usb.h" #define USB_MAXBUS 64 -#define USB_DEVICE_MAX USB_MAXBUS * 128 +#define USB_DEVICE_MAX (USB_MAXBUS * 128) #define USB_SG_SIZE 16384 /* split-size for large txs */ /* Mutual exclusion for removal, open, and release */ @@ -725,15 +725,15 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, /* * check for the special corner case 'get_device_id' in the printer - * class specification, where wIndex is (interface << 8 | altsetting) - * instead of just interface + * class specification, which we always want to allow as it is used + * to query things like ink level, etc. */ if (requesttype == 0xa1 && request == 0) { alt_setting = usb_find_alt_setting(ps->dev->actconfig, index >> 8, index & 0xff); if (alt_setting && alt_setting->desc.bInterfaceClass == USB_CLASS_PRINTER) - index >>= 8; + return 0; } index &= 0xff; @@ -742,6 +742,22 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, if ((index & ~USB_DIR_IN) == 0) return 0; ret = findintfep(ps->dev, index); + if (ret < 0) { + /* + * Some not fully compliant Win apps seem to get + * index wrong and have the endpoint number here + * rather than the endpoint address (with the + * correct direction). Win does let this through, + * so we'll not reject it here but leave it to + * the device to not break KVM. But we warn. + */ + ret = findintfep(ps->dev, index ^ 0x80); + if (ret >= 0) + dev_info(&ps->dev->dev, + "%s: process %i (%s) requesting ep %02x but needs %02x\n", + __func__, task_pid_nr(current), + current->comm, index, index ^ 0x80); + } if (ret >= 0) ret = checkintf(ps, ret); break; @@ -1804,7 +1820,8 @@ static int proc_ioctl(struct dev_state *ps, struct usbdevfs_ioctl *ctl) /* alloc buffer */ if ((size = _IOC_SIZE(ctl->ioctl_code)) > 0) { - if ((buf = kmalloc(size, GFP_KERNEL)) == NULL) + buf = kmalloc(size, GFP_KERNEL); + if (buf == NULL) return -ENOMEM; if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) { if (copy_from_user(buf, ctl->data, size)) { |