Commit f729a1b0 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Dmitry Torokhov
Browse files

Input: input_event - fix struct padding on sparc64



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: 141e5dca ("Input: input_event - fix the CONFIG_SPARC64 mixup")
Fixes: 2e746942 ("Input: input_event - provide override for sparc64")
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20191213204936.3643476-2-arnd@arndb.de


Cc: stable@vger.kernel.org
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent add21809
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -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;
	}
+9 −5
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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