aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2011-02-11 04:10:45 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-02-21 04:02:28 -0500
commit4dfcc271d587465f0d181c7636453ba4d0ec8acc (patch)
treeb7f6de77ee9d63cc009c3e0011e3d3ca27d9fc16 /drivers
parent5d9d6e91b835796c21fbd7ce479880e5181be112 (diff)
Input: uinput - use memdup_user() and friends
Instead of open-coding copying of data structures from userspace use memdup_user() and strndup_user(). Note that this introduces change in behavior because driver used to truncate 'phys' longer than 1024 bytes, but now it will refuse to set 'phys' that long. Arguably trying to set such 'phys' is suspect anyways. Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/misc/uinput.c35
1 files changed, 10 insertions, 25 deletions
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index c0888e3d2fb4..7f8331f45bad 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -361,14 +361,9 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
361 361
362 dev = udev->dev; 362 dev = udev->dev;
363 363
364 user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL); 364 user_dev = memdup_user(buffer, sizeof(struct uinput_user_dev));
365 if (!user_dev) 365 if (!IS_ERR(user_dev))
366 return -ENOMEM; 366 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 367
373 udev->ff_effects_max = user_dev->ff_effects_max; 368 udev->ff_effects_max = user_dev->ff_effects_max;
374 369
@@ -621,7 +616,6 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
621 struct uinput_ff_upload ff_up; 616 struct uinput_ff_upload ff_up;
622 struct uinput_ff_erase ff_erase; 617 struct uinput_ff_erase ff_erase;
623 struct uinput_request *req; 618 struct uinput_request *req;
624 int length;
625 char *phys; 619 char *phys;
626 620
627 retval = mutex_lock_interruptible(&udev->mutex); 621 retval = mutex_lock_interruptible(&udev->mutex);
@@ -688,24 +682,15 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
688 retval = -EINVAL; 682 retval = -EINVAL;
689 goto out; 683 goto out;
690 } 684 }
691 length = strnlen_user(p, 1024); 685
692 if (length <= 0) { 686 phys = strndup_user(p, 1024);
693 retval = -EFAULT; 687 if (IS_ERR(phys)) {
694 break; 688 retval = PTR_ERR(phys);
689 goto out;
695 } 690 }
691
696 kfree(udev->dev->phys); 692 kfree(udev->dev->phys);
697 udev->dev->phys = phys = kmalloc(length, GFP_KERNEL); 693 udev->dev->phys = phys;
698 if (!phys) {
699 retval = -ENOMEM;
700 break;
701 }
702 if (copy_from_user(phys, p, length)) {
703 udev->dev->phys = NULL;
704 kfree(phys);
705 retval = -EFAULT;
706 break;
707 }
708 phys[length - 1] = '\0';
709 break; 694 break;
710 695
711 case UI_BEGIN_FF_UPLOAD: 696 case UI_BEGIN_FF_UPLOAD: