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

Commit 439581ec authored by Peter Korsgaard's avatar Peter Korsgaard Committed by Dmitry Torokhov
Browse files

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: default avatarBaruch Siach <baruch@tkos.co.il>
Signed-off-by: default avatarPeter Korsgaard <jacmet@sunsite.dk>
Acked-by: default avatarHenrik Rydberg <rydberg@euromail.se>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 50635115
Loading
Loading
Loading
Loading
+6 −4
Original line number Original line Diff line number Diff line
@@ -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);