[PATCHv2] evdev: fix evdev_write return value on partial writes

Subsystems: input (keyboard, mouse, joystick, touchscreen) drivers, the rest

2 messages, 2 authors, 2011-01-27 · open the first message on its own page

[PATCHv2] evdev: fix evdev_write return value on partial writes

From: Peter Korsgaard <jacmet@sunsite.dk>
Date: 2011-01-27 10:03:50

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.

Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
---
 Changes since v1:
 - Return -EINVAL on writes of length < sizeof(struct input_event), similar
   to how it's done in evdev_read.

 drivers/input/evdev.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index c8471a2..1ee7d0f 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -321,6 +321,9 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
 	struct input_event event;
 	int retval;
 
+	if (count < input_event_size())
+		return -EINVAL;
+
 	retval = mutex_lock_interruptible(&evdev->mutex);
 	if (retval)
 		return retval;
@@ -330,7 +333,7 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
 		goto out;
 	}
 
-	while (retval < count) {
+	while ((retval + input_event_size()) <= count) {
 
 		if (input_event_from_user(buffer + retval, &event)) {
 			retval = -EFAULT;
-- 
1.7.2.3

Re: [PATCHv2] evdev: fix evdev_write return value on partial writes

From: Henrik Rydberg <hidden>
Date: 2011-01-27 11:02:50

Hi Peter,
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.

Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
Why not add the Reported-by here yourself?
quoted hunk
@@ -321,6 +321,9 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
 	struct input_event event;
 	int retval;
 
+	if (count < input_event_size())
+		return -EINVAL;
+
This assumes that write will only ever be called with sufficient
data. It is not an error to write (and report) less data than
specified, so perhaps the above will yield unpleasant surprises.
quoted hunk
 	retval = mutex_lock_interruptible(&evdev->mutex);
 	if (retval)
 		return retval;
@@ -330,7 +333,7 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
 		goto out;
 	}
 
-	while (retval < count) {
+	while ((retval + input_event_size()) <= count) {
Too many parenthesis.
 
 		if (input_event_from_user(buffer + retval, &event)) {
 			retval = -EFAULT;
Thanks,
Henrik
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help