2013-09-17 22:55:54

by Ryan Mallon

[permalink] [raw]
Subject: [PATCH 1/2] input: Return the number of bytes written so far on evdev write failure

If input_event_from_user() fails in evdev write() and at least one
event has been written successfully then return the number of bytes
written. If no events have been written, then the EFAULT error is
returned.

Signed-off-by: Ryan Mallon <[email protected]>
---
drivers/input/evdev.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index d2b34fb..b0dec2ba 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -437,7 +437,8 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer,
while (retval + input_event_size() <= count) {

if (input_event_from_user(buffer + retval, &event)) {
- retval = -EFAULT;
+ if (retval == 0)
+ retval = -EFAULT;
goto out;
}
retval += input_event_size();
--
1.7.9.7


2013-09-17 22:56:01

by Ryan Mallon

[permalink] [raw]
Subject: [PATCH 2/2] uinput: Support injecting multiple events in one write() call

Rework the code in uinput_inject_event so that it matches the code in
evdev_write and allows injecting more than one event, or zero events.

Signed-off-by: Ryan Mallon <[email protected]>
---
drivers/input/misc/uinput.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index a0a4bba..0247a8a 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -434,16 +434,24 @@ static ssize_t uinput_inject_event(struct uinput_device *udev,
const char __user *buffer, size_t count)
{
struct input_event ev;
+ size_t bytes = 0;

- if (count < input_event_size())
+ if (count != 0 && count < input_event_size())
return -EINVAL;

- if (input_event_from_user(buffer, &ev))
- return -EFAULT;
+ while (bytes + input_event_size() <= count) {
+ if (input_event_from_user(buffer + bytes, &ev)) {
+ if (!bytes)
+ bytes = -EFAULT;
+ goto out;
+ }

- input_event(udev->dev, ev.type, ev.code, ev.value);
+ input_event(udev->dev, ev.type, ev.code, ev.value);
+ bytes += input_event_size();
+ }

- return input_event_size();
+ out:
+ return bytes;
}

static ssize_t uinput_write(struct file *file, const char __user *buffer,
--
1.7.9.7

2013-09-18 19:48:13

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH 2/2] uinput: Support injecting multiple events in one write() call

Hi Ryan,

On Wed, Sep 18, 2013 at 08:55:44AM +1000, Ryan Mallon wrote:
> Rework the code in uinput_inject_event so that it matches the code in
> evdev_write and allows injecting more than one event, or zero events.

After some thinking I went back to the original version of your patch.
For justification see 46f49b7a223ac7493e7cf619fb583d11edefc2c2:

"When copy_to/from_user fails in the middle of transfer we should not
report to the user that read/write partially succeeded but rather
report -EFAULT right away, so that application will know that it got
its buffers all wrong.

If application messed up its buffers we can't trust the data fetched
from userspace and successfully written to the device or if data read
from the device and transferred to userspace ended up where application
expected it to end."

Thanks.

--
Dmitry

2013-09-18 21:35:43

by Ryan Mallon

[permalink] [raw]
Subject: Re: [PATCH 2/2] uinput: Support injecting multiple events in one write() call

On 19/09/13 05:48, Dmitry Torokhov wrote:

> Hi Ryan,
>
> On Wed, Sep 18, 2013 at 08:55:44AM +1000, Ryan Mallon wrote:
>> Rework the code in uinput_inject_event so that it matches the code in
>> evdev_write and allows injecting more than one event, or zero events.
>
> After some thinking I went back to the original version of your patch.
> For justification see 46f49b7a223ac7493e7cf619fb583d11edefc2c2:
>
> "When copy_to/from_user fails in the middle of transfer we should not
> report to the user that read/write partially succeeded but rather
> report -EFAULT right away, so that application will know that it got
> its buffers all wrong.
>
> If application messed up its buffers we can't trust the data fetched
> from userspace and successfully written to the device or if data read
> from the device and transferred to userspace ended up where application
> expected it to end."


Okay, so patch 1 is obviously dropped. Do you want me to resend a fixed
version of this one, or have you already modified it?

Thanks,
~Ryan

2013-09-18 22:15:15

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH 2/2] uinput: Support injecting multiple events in one write() call

Ryan Mallon <[email protected]> wrote:
>On 19/09/13 05:48, Dmitry Torokhov wrote:
>
>> Hi Ryan,
>>
>> On Wed, Sep 18, 2013 at 08:55:44AM +1000, Ryan Mallon wrote:
>>> Rework the code in uinput_inject_event so that it matches the code
>in
>>> evdev_write and allows injecting more than one event, or zero
>events.
>>
>> After some thinking I went back to the original version of your
>patch.
>> For justification see 46f49b7a223ac7493e7cf619fb583d11edefc2c2:
>>
>> "When copy_to/from_user fails in the middle of transfer we should not
>> report to the user that read/write partially succeeded but rather
>> report -EFAULT right away, so that application will know that it got
>> its buffers all wrong.
>>
>> If application messed up its buffers we can't trust the data fetched
>> from userspace and successfully written to the device or if data read
>> from the device and transferred to userspace ended up where
>application
>> expected it to end."
>
>
>Okay, so patch 1 is obviously dropped. Do you want me to resend a fixed
>
>version of this one, or have you already modified it?

I took your original version - is does the right thing.

Thanks.

--
Dmitry