summaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/uinput.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/misc/uinput.c')
-rw-r--r--drivers/input/misc/uinput.c54
1 files changed, 21 insertions, 33 deletions
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 82542a1c109..736056897e5 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -302,10 +302,14 @@ static int uinput_validate_absbits(struct input_dev *dev)
int retval = 0;
for (cnt = 0; cnt < ABS_CNT; cnt++) {
+ int min, max;
if (!test_bit(cnt, dev->absbit))
continue;
- if (input_abs_get_max(dev, cnt) <= input_abs_get_min(dev, cnt)) {
+ min = input_abs_get_min(dev, cnt);
+ max = input_abs_get_max(dev, cnt);
+
+ if ((min != 0 || max != 0) && max <= min) {
printk(KERN_DEBUG
"%s: invalid abs[%02x] min:%d max:%d\n",
UINPUT_NAME, cnt,
@@ -347,8 +351,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
{
struct uinput_user_dev *user_dev;
struct input_dev *dev;
- char *name;
- int i, size;
+ int i;
int retval;
if (count != sizeof(struct uinput_user_dev))
@@ -362,30 +365,25 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
dev = udev->dev;
- user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL);
- if (!user_dev)
- return -ENOMEM;
-
- if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
- retval = -EFAULT;
- goto exit;
- }
+ user_dev = memdup_user(buffer, sizeof(struct uinput_user_dev));
+ if (IS_ERR(user_dev))
+ return PTR_ERR(user_dev);
udev->ff_effects_max = user_dev->ff_effects_max;
- size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
- if (!size) {
+ /* Ensure name is filled in */
+ if (!user_dev->name[0]) {
retval = -EINVAL;
goto exit;
}
kfree(dev->name);
- dev->name = name = kmalloc(size, GFP_KERNEL);
- if (!name) {
+ dev->name = kstrndup(user_dev->name, UINPUT_MAX_NAME_SIZE,
+ GFP_KERNEL);
+ if (!dev->name) {
retval = -ENOMEM;
goto exit;
}
- strlcpy(name, user_dev->name, size);
dev->id.bustype = user_dev->id.bustype;
dev->id.vendor = user_dev->id.vendor;
@@ -622,7 +620,6 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
struct uinput_ff_upload ff_up;
struct uinput_ff_erase ff_erase;
struct uinput_request *req;
- int length;
char *phys;
retval = mutex_lock_interruptible(&udev->mutex);
@@ -689,24 +686,15 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
retval = -EINVAL;
goto out;
}
- length = strnlen_user(p, 1024);
- if (length <= 0) {
- retval = -EFAULT;
- break;
+
+ phys = strndup_user(p, 1024);
+ if (IS_ERR(phys)) {
+ retval = PTR_ERR(phys);
+ goto out;
}
+
kfree(udev->dev->phys);
- udev->dev->phys = phys = kmalloc(length, GFP_KERNEL);
- if (!phys) {
- retval = -ENOMEM;
- break;
- }
- if (copy_from_user(phys, p, length)) {
- udev->dev->phys = NULL;
- kfree(phys);
- retval = -EFAULT;
- break;
- }
- phys[length - 1] = '\0';
+ udev->dev->phys = phys;
break;
case UI_BEGIN_FF_UPLOAD: