Input: input_event - fix struct padding on sparc64
authorArnd Bergmann <arnd@arndb.de>
Fri, 13 Dec 2019 22:06:58 +0000 (14:06 -0800)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 13 Dec 2019 23:00:36 +0000 (15:00 -0800)
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: 141e5dcaa735 ("Input: input_event - fix the CONFIG_SPARC64 mixup")
Fixes: 2e746942ebac ("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>
drivers/input/evdev.c
drivers/input/misc/uinput.c
include/uapi/linux/input.h

index d7dd6fcf2db05a8841e60a4089dd71212d15c476..f918fca9ada3206b45dfef02a0a69b834107f071 100644 (file)
@@ -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;
        }
index 0bb456015d8f4a997528c57fd57e0a6ab8a43a1d..f2593133e5247a8fbc6cebfc296a2aedeb0c87ff 100644 (file)
@@ -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);
index f056b2a00d5c7695a69826786b5e2336c79c3c31..9a61c28ed3ae48cf2107ffc8b9ea0647e9ccb4f8 100644 (file)
@@ -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