Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57d292bd authored by Jiri Kosina's avatar Jiri Kosina Committed by Linus Torvalds
Browse files

HID: fix HIDIOCGRDESC memory access in hidraw



Fix bogus copying of data into userspace when HIDIOCGRDESC is issued.
HID-transport layer makes sure that dev->hid->rdesc is not larger than
HID_MAX_DESCRIPTOR_SIZE.

Noticed-by: default avatarAl Viro <viro@ftp.linux.org.uk>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 23fd5045
Loading
Loading
Loading
Loading
+9 −3
Original line number Original line Diff line number Diff line
@@ -229,9 +229,15 @@ static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd


				if (get_user(len, (int __user *)arg))
				if (get_user(len, (int __user *)arg))
					return -EFAULT;
					return -EFAULT;
				if (copy_to_user(*((__u8 **)(user_arg +

							sizeof(__u32))),
				if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
							dev->hid->rdesc, len))
					return -EINVAL;

				if (copy_to_user(user_arg + offsetof(
								struct hidraw_report_descriptor,
								value[0]),
							dev->hid->rdesc,
							min(dev->hid->rsize, len)))
						return -EFAULT;
						return -EFAULT;
				return 0;
				return 0;
			}
			}
+12 −8
Original line number Original line Diff line number Diff line
@@ -29,13 +29,6 @@
 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
 */
 */


#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/input.h>

/*
/*
 * USB HID (Human Interface Device) interface class code
 * USB HID (Human Interface Device) interface class code
 */
 */
@@ -69,6 +62,17 @@
#define HID_DT_REPORT			(USB_TYPE_CLASS | 0x02)
#define HID_DT_REPORT			(USB_TYPE_CLASS | 0x02)
#define HID_DT_PHYSICAL			(USB_TYPE_CLASS | 0x03)
#define HID_DT_PHYSICAL			(USB_TYPE_CLASS | 0x03)


#define HID_MAX_DESCRIPTOR_SIZE		4096

#ifdef __KERNEL__

#include <linux/types.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/input.h>

/*
/*
 * We parse each description item into this structure. Short items data
 * We parse each description item into this structure. Short items data
 * values are expanded to 32-bit signed int, long items contain a pointer
 * values are expanded to 32-bit signed int, long items contain a pointer
@@ -311,7 +315,6 @@ struct hid_global {
 * This is the local environment. It is persistent up the next main-item.
 * This is the local environment. It is persistent up the next main-item.
 */
 */


#define HID_MAX_DESCRIPTOR_SIZE		4096
#define HID_MAX_USAGES			8192
#define HID_MAX_USAGES			8192
#define HID_DEFAULT_NUM_COLLECTIONS	16
#define HID_DEFAULT_NUM_COLLECTIONS	16


@@ -560,4 +563,5 @@ static inline int hid_ff_init(struct hid_device *hid) { return -1; }
#define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
#define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
		__FILE__ , ## arg)
		__FILE__ , ## arg)
#endif
#endif
#endif
+3 −3
Original line number Original line Diff line number Diff line
@@ -15,9 +15,11 @@
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 */
 */


#include <linux/hid.h>

struct hidraw_report_descriptor {
struct hidraw_report_descriptor {
	__u32 size;
	__u32 size;
	__u8 *value;
	__u8 value[HID_MAX_DESCRIPTOR_SIZE];
};
};


struct hidraw_devinfo {
struct hidraw_devinfo {
@@ -40,8 +42,6 @@ struct hidraw_devinfo {
/* kernel-only API declarations */
/* kernel-only API declarations */
#ifdef __KERNEL__
#ifdef __KERNEL__


#include <linux/hid.h>

struct hidraw {
struct hidraw {
	unsigned int minor;
	unsigned int minor;
	int exist;
	int exist;