diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/input/misc/uinput.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/input/misc/uinput.c')
-rw-r--r-- | drivers/input/misc/uinput.c | 63 |
1 files changed, 28 insertions, 35 deletions
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 360698553eb5..736056897e50 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/fs.h> | 37 | #include <linux/fs.h> |
38 | #include <linux/miscdevice.h> | 38 | #include <linux/miscdevice.h> |
39 | #include <linux/uinput.h> | 39 | #include <linux/uinput.h> |
40 | #include <linux/input/mt.h> | ||
40 | #include "../input-compat.h" | 41 | #include "../input-compat.h" |
41 | 42 | ||
42 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 43 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
@@ -301,10 +302,14 @@ static int uinput_validate_absbits(struct input_dev *dev) | |||
301 | int retval = 0; | 302 | int retval = 0; |
302 | 303 | ||
303 | for (cnt = 0; cnt < ABS_CNT; cnt++) { | 304 | for (cnt = 0; cnt < ABS_CNT; cnt++) { |
305 | int min, max; | ||
304 | if (!test_bit(cnt, dev->absbit)) | 306 | if (!test_bit(cnt, dev->absbit)) |
305 | continue; | 307 | continue; |
306 | 308 | ||
307 | if (input_abs_get_max(dev, cnt) <= input_abs_get_min(dev, cnt)) { | 309 | min = input_abs_get_min(dev, cnt); |
310 | max = input_abs_get_max(dev, cnt); | ||
311 | |||
312 | if ((min != 0 || max != 0) && max <= min) { | ||
308 | printk(KERN_DEBUG | 313 | printk(KERN_DEBUG |
309 | "%s: invalid abs[%02x] min:%d max:%d\n", | 314 | "%s: invalid abs[%02x] min:%d max:%d\n", |
310 | UINPUT_NAME, cnt, | 315 | UINPUT_NAME, cnt, |
@@ -346,8 +351,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
346 | { | 351 | { |
347 | struct uinput_user_dev *user_dev; | 352 | struct uinput_user_dev *user_dev; |
348 | struct input_dev *dev; | 353 | struct input_dev *dev; |
349 | char *name; | 354 | int i; |
350 | int i, size; | ||
351 | int retval; | 355 | int retval; |
352 | 356 | ||
353 | if (count != sizeof(struct uinput_user_dev)) | 357 | if (count != sizeof(struct uinput_user_dev)) |
@@ -361,30 +365,25 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
361 | 365 | ||
362 | dev = udev->dev; | 366 | dev = udev->dev; |
363 | 367 | ||
364 | user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL); | 368 | user_dev = memdup_user(buffer, sizeof(struct uinput_user_dev)); |
365 | if (!user_dev) | 369 | if (IS_ERR(user_dev)) |
366 | return -ENOMEM; | 370 | return PTR_ERR(user_dev); |
367 | |||
368 | if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) { | ||
369 | retval = -EFAULT; | ||
370 | goto exit; | ||
371 | } | ||
372 | 371 | ||
373 | udev->ff_effects_max = user_dev->ff_effects_max; | 372 | udev->ff_effects_max = user_dev->ff_effects_max; |
374 | 373 | ||
375 | size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; | 374 | /* Ensure name is filled in */ |
376 | if (!size) { | 375 | if (!user_dev->name[0]) { |
377 | retval = -EINVAL; | 376 | retval = -EINVAL; |
378 | goto exit; | 377 | goto exit; |
379 | } | 378 | } |
380 | 379 | ||
381 | kfree(dev->name); | 380 | kfree(dev->name); |
382 | dev->name = name = kmalloc(size, GFP_KERNEL); | 381 | dev->name = kstrndup(user_dev->name, UINPUT_MAX_NAME_SIZE, |
383 | if (!name) { | 382 | GFP_KERNEL); |
383 | if (!dev->name) { | ||
384 | retval = -ENOMEM; | 384 | retval = -ENOMEM; |
385 | goto exit; | 385 | goto exit; |
386 | } | 386 | } |
387 | strlcpy(name, user_dev->name, size); | ||
388 | 387 | ||
389 | dev->id.bustype = user_dev->id.bustype; | 388 | dev->id.bustype = user_dev->id.bustype; |
390 | dev->id.vendor = user_dev->id.vendor; | 389 | dev->id.vendor = user_dev->id.vendor; |
@@ -406,8 +405,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu | |||
406 | goto exit; | 405 | goto exit; |
407 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { | 406 | if (test_bit(ABS_MT_SLOT, dev->absbit)) { |
408 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; | 407 | int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1; |
409 | input_mt_create_slots(dev, nslot); | 408 | input_mt_init_slots(dev, nslot); |
410 | input_set_events_per_packet(dev, 6 * nslot); | ||
411 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { | 409 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { |
412 | input_set_events_per_packet(dev, 60); | 410 | input_set_events_per_packet(dev, 60); |
413 | } | 411 | } |
@@ -622,7 +620,6 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, | |||
622 | struct uinput_ff_upload ff_up; | 620 | struct uinput_ff_upload ff_up; |
623 | struct uinput_ff_erase ff_erase; | 621 | struct uinput_ff_erase ff_erase; |
624 | struct uinput_request *req; | 622 | struct uinput_request *req; |
625 | int length; | ||
626 | char *phys; | 623 | char *phys; |
627 | 624 | ||
628 | retval = mutex_lock_interruptible(&udev->mutex); | 625 | retval = mutex_lock_interruptible(&udev->mutex); |
@@ -680,29 +677,24 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd, | |||
680 | retval = uinput_set_bit(arg, swbit, SW_MAX); | 677 | retval = uinput_set_bit(arg, swbit, SW_MAX); |
681 | break; | 678 | break; |
682 | 679 | ||
680 | case UI_SET_PROPBIT: | ||
681 | retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX); | ||
682 | break; | ||
683 | |||
683 | case UI_SET_PHYS: | 684 | case UI_SET_PHYS: |
684 | if (udev->state == UIST_CREATED) { | 685 | if (udev->state == UIST_CREATED) { |
685 | retval = -EINVAL; | 686 | retval = -EINVAL; |
686 | goto out; | 687 | goto out; |
687 | } | 688 | } |
688 | length = strnlen_user(p, 1024); | 689 | |
689 | if (length <= 0) { | 690 | phys = strndup_user(p, 1024); |
690 | retval = -EFAULT; | 691 | if (IS_ERR(phys)) { |
691 | break; | 692 | retval = PTR_ERR(phys); |
693 | goto out; | ||
692 | } | 694 | } |
695 | |||
693 | kfree(udev->dev->phys); | 696 | kfree(udev->dev->phys); |
694 | udev->dev->phys = phys = kmalloc(length, GFP_KERNEL); | 697 | udev->dev->phys = phys; |
695 | if (!phys) { | ||
696 | retval = -ENOMEM; | ||
697 | break; | ||
698 | } | ||
699 | if (copy_from_user(phys, p, length)) { | ||
700 | udev->dev->phys = NULL; | ||
701 | kfree(phys); | ||
702 | retval = -EFAULT; | ||
703 | break; | ||
704 | } | ||
705 | phys[length - 1] = '\0'; | ||
706 | break; | 698 | break; |
707 | 699 | ||
708 | case UI_BEGIN_FF_UPLOAD: | 700 | case UI_BEGIN_FF_UPLOAD: |
@@ -811,6 +803,7 @@ static const struct file_operations uinput_fops = { | |||
811 | #ifdef CONFIG_COMPAT | 803 | #ifdef CONFIG_COMPAT |
812 | .compat_ioctl = uinput_compat_ioctl, | 804 | .compat_ioctl = uinput_compat_ioctl, |
813 | #endif | 805 | #endif |
806 | .llseek = no_llseek, | ||
814 | }; | 807 | }; |
815 | 808 | ||
816 | static struct miscdevice uinput_misc = { | 809 | static struct miscdevice uinput_misc = { |