Input: evdev - fix evdev_write return value on partial writes

As was recently brought up on the busybox list
(http://lists.busybox.net/pipermail/busybox/2011-January/074565.html),
evdev_write doesn't properly check the count argument, which will
lead to a return value > count on partial writes if the remaining bytes
are accessible - causing userspace confusion.

Fix it by only handling each full input_event structure and return -EINVAL
if less than 1 struct was written, similar to how it is done in evdev_read.

Reported-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
Acked-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
Peter Korsgaard 2011-02-25 09:30:46 -08:00 committed by Dmitry Torokhov
parent 5063511539
commit 439581ec07

View file

@ -321,6 +321,9 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
struct input_event event; struct input_event event;
int retval; int retval;
if (count < input_event_size())
return -EINVAL;
retval = mutex_lock_interruptible(&evdev->mutex); retval = mutex_lock_interruptible(&evdev->mutex);
if (retval) if (retval)
return retval; return retval;
@ -330,17 +333,16 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
goto out; goto out;
} }
while (retval < count) { do {
if (input_event_from_user(buffer + retval, &event)) { if (input_event_from_user(buffer + retval, &event)) {
retval = -EFAULT; retval = -EFAULT;
goto out; goto out;
} }
retval += input_event_size();
input_inject_event(&evdev->handle, input_inject_event(&evdev->handle,
event.type, event.code, event.value); event.type, event.code, event.value);
retval += input_event_size(); } while (retval + input_event_size() <= count);
}
out: out:
mutex_unlock(&evdev->mutex); mutex_unlock(&evdev->mutex);