Skip to content

Commit

Permalink
Input: input_event - fix struct padding on sparc64
Browse files Browse the repository at this point in the history
Going through all uses of timeval, I noticed that we screwed up
input_event in the previous attempts to fix it:

The time fields now match between kernel and user space, but all following
fields are in the wrong place.

Add the required padding that is implied by the glibc timeval definition
to fix the layout, and use a struct initializer to avoid leaking kernel
stack data.

Fixes: 141e5dc ("Input: input_event - fix the CONFIG_SPARC64 mixup")
Fixes: 2e74694 ("Input: input_event - provide override for sparc64")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20191213204936.3643476-2-arnd@arndb.de
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
  • Loading branch information
Arnd Bergmann authored and Dmitry Torokhov committed Dec 13, 2019
1 parent add2180 commit f729a1b
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 12 deletions.
14 changes: 7 additions & 7 deletions drivers/input/evdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,13 @@ static void __pass_event(struct evdev_client *client,
*/
client->tail = (client->head - 2) & (client->bufsize - 1);

client->buffer[client->tail].input_event_sec =
event->input_event_sec;
client->buffer[client->tail].input_event_usec =
event->input_event_usec;
client->buffer[client->tail].type = EV_SYN;
client->buffer[client->tail].code = SYN_DROPPED;
client->buffer[client->tail].value = 0;
client->buffer[client->tail] = (struct input_event) {
.input_event_sec = event->input_event_sec,
.input_event_usec = event->input_event_usec,
.type = EV_SYN,
.code = SYN_DROPPED,
.value = 0,
};

client->packet_head = client->tail;
}
Expand Down
14 changes: 9 additions & 5 deletions drivers/input/misc/uinput.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,16 @@ static int uinput_dev_event(struct input_dev *dev,
struct uinput_device *udev = input_get_drvdata(dev);
struct timespec64 ts;

udev->buff[udev->head].type = type;
udev->buff[udev->head].code = code;
udev->buff[udev->head].value = value;
ktime_get_ts64(&ts);
udev->buff[udev->head].input_event_sec = ts.tv_sec;
udev->buff[udev->head].input_event_usec = ts.tv_nsec / NSEC_PER_USEC;

udev->buff[udev->head] = (struct input_event) {
.input_event_sec = ts.tv_sec,
.input_event_usec = ts.tv_nsec / NSEC_PER_USEC,
.type = type,
.code = code,
.value = value,
};

udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;

wake_up_interruptible(&udev->waitq);
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct input_event {
__kernel_ulong_t __sec;
#if defined(__sparc__) && defined(__arch64__)
unsigned int __usec;
unsigned int __pad;
#else
__kernel_ulong_t __usec;
#endif
Expand Down

0 comments on commit f729a1b

Please sign in to comment.