2019-11-08 20:38:30

by Arnd Bergmann

[permalink] [raw]
Subject: [PATCH 0/8] y2038: bug fixes from y2038 work

I've gone through the remaining uses of time_t etc and come up with a
set of 90 patches of varying complexity and importance, to the point
of being able to remove the old time_t/timeval/timespec from the kernel
headers completely.

This set includes the eight patches that I think should be merged
right away and backported into stable kernels if possible.

Please apply individual patches to the respective maintainer trees
for either v5.4 or v5.5 as appropriate.

For reference, the full series of 90 patches can be found at
https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=y2038-endgame

Arnd

Arnd Bergmann (8):
y2038: timex: remove incorrect time_t truncation
timekeeping: optimize ns_to_timespec64
powerpc: fix vdso32 for ppc64le
ipmi: kill off 'timespec' usage again
netfilter: xt_time: use time64_t
lp: fix sparc64 LPSETTIMEOUT ioctl
ppdev: fix PPGETTIME/PPSETTIME ioctls
Input: input_event: fix struct padding on sparc64

arch/powerpc/kernel/vdso32/gettimeofday.S | 2 +-
drivers/char/ipmi/ipmi_si_intf.c | 40 ++++++++---------------
drivers/char/lp.c | 4 +++
drivers/char/ppdev.c | 16 ++++++---
drivers/input/evdev.c | 3 ++
drivers/input/misc/uinput.c | 3 ++
include/uapi/linux/input.h | 1 +
kernel/time/ntp.c | 2 +-
kernel/time/time.c | 21 +++++++-----
net/netfilter/xt_time.c | 19 ++++++-----
10 files changed, 61 insertions(+), 50 deletions(-)

Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Corey Minyard <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Sudip Mukherjee <[email protected]>
Cc: Dmitry Torokhov <[email protected]>
Cc: John Stultz <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Stephen Boyd <[email protected]>
Cc: Pablo Neira Ayuso <[email protected]>
Cc: Jozsef Kadlecsik <[email protected]>
Cc: Florian Westphal <[email protected]>
Cc: "David S. Miller" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

--
2.20.0


2019-11-08 20:39:37

by Arnd Bergmann

[permalink] [raw]
Subject: [PATCH 3/8] powerpc: fix vdso32 for ppc64le

On little-endian 32-bit application running on 64-bit kernels,
the current vdso would read the wrong half of the xtime seconds
field. Change it to return the lower half like it does on
big-endian.

Signed-off-by: Arnd Bergmann <[email protected]>
---
arch/powerpc/kernel/vdso32/gettimeofday.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index becd9f8767ed..4327665ad86f 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -13,7 +13,7 @@
#include <asm/unistd.h>

/* Offset for the low 32-bit part of a field of long type */
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PPC64) && defined(CONFIG_CPU_BIG_ENDIAN)
#define LOPART 4
#define TSPEC_TV_SEC TSPC64_TV_SEC+LOPART
#else
--
2.20.0

2019-11-08 20:40:04

by Arnd Bergmann

[permalink] [raw]
Subject: [PATCH 8/8] 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 add explicit initialization
to avoid leaking kernel stack data.

Cc: [email protected]
Cc: "David S. Miller" <[email protected]>
Cc: [email protected]
Fixes: 141e5dcaa735 ("Input: input_event - fix the CONFIG_SPARC64 mixup")
Fixes: 2e746942ebac ("Input: input_event - provide override for sparc64")
Signed-off-by: Arnd Bergmann <[email protected]>
---
drivers/input/evdev.c | 3 +++
drivers/input/misc/uinput.c | 3 +++
include/uapi/linux/input.h | 1 +
3 files changed, 7 insertions(+)

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index d7dd6fcf2db0..24a90793caf0 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -228,6 +228,9 @@ static void __pass_event(struct evdev_client *client,
event->input_event_sec;
client->buffer[client->tail].input_event_usec =
event->input_event_usec;
+#ifdef CONFIG_SPARC64
+ client->buffer[client->tail].__pad = 0;
+#endif
client->buffer[client->tail].type = EV_SYN;
client->buffer[client->tail].code = SYN_DROPPED;
client->buffer[client->tail].value = 0;
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 84051f20b18a..1d8c09e9fd47 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -80,6 +80,9 @@ static int uinput_dev_event(struct input_dev *dev,
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;
+#ifdef CONFIG_SPARC64
+ udev->buff[udev->head].__pad = 0;
+#endif
udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;

wake_up_interruptible(&udev->waitq);
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index f056b2a00d5c..9a61c28ed3ae 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -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
--
2.20.0

2019-11-08 20:40:37

by Arnd Bergmann

[permalink] [raw]
Subject: [PATCH 7/8] ppdev: fix PPGETTIME/PPSETTIME ioctls

Going through the uses of timeval in the user space API,
I noticed two bugs in ppdev that were introduced in the y2038
conversion:

* The range check was accidentally moved from ppsettime to
ppgettime

* On sparc64, the microseconds are in the other half of the
64-bit word.

Fix both, and mark the fix for stable backports.

Cc: [email protected]
Fixes: 3b9ab374a1e6 ("ppdev: convert to y2038 safe")
Signed-off-by: Arnd Bergmann <[email protected]>
---
drivers/char/ppdev.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index c86f18aa8985..34bb88fe0b0a 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -619,20 +619,27 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (copy_from_user(time32, argp, sizeof(time32)))
return -EFAULT;

+ if ((time32[0] < 0) || (time32[1] < 0))
+ return -EINVAL;
+
return pp_set_timeout(pp->pdev, time32[0], time32[1]);

case PPSETTIME64:
if (copy_from_user(time64, argp, sizeof(time64)))
return -EFAULT;

+ if ((time64[0] < 0) || (time64[1] < 0))
+ return -EINVAL;
+
+ if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall())
+ time64[1] >>= 32;
+
return pp_set_timeout(pp->pdev, time64[0], time64[1]);

case PPGETTIME32:
jiffies_to_timespec64(pp->pdev->timeout, &ts);
time32[0] = ts.tv_sec;
time32[1] = ts.tv_nsec / NSEC_PER_USEC;
- if ((time32[0] < 0) || (time32[1] < 0))
- return -EINVAL;

if (copy_to_user(argp, time32, sizeof(time32)))
return -EFAULT;
@@ -643,8 +650,9 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
jiffies_to_timespec64(pp->pdev->timeout, &ts);
time64[0] = ts.tv_sec;
time64[1] = ts.tv_nsec / NSEC_PER_USEC;
- if ((time64[0] < 0) || (time64[1] < 0))
- return -EINVAL;
+
+ if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall())
+ time64[1] <<= 32;

if (copy_to_user(argp, time64, sizeof(time64)))
return -EFAULT;
--
2.20.0

2019-11-11 18:32:19

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [PATCH 8/8] Input: input_event: fix struct padding on sparc64

Hi Arnd,

On Fri, Nov 08, 2019 at 09:34:31PM +0100, Arnd Bergmann wrote:
> 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 add explicit initialization
> to avoid leaking kernel stack data.
>
> Cc: [email protected]
> Cc: "David S. Miller" <[email protected]>
> Cc: [email protected]
> Fixes: 141e5dcaa735 ("Input: input_event - fix the CONFIG_SPARC64 mixup")
> Fixes: 2e746942ebac ("Input: input_event - provide override for sparc64")
> Signed-off-by: Arnd Bergmann <[email protected]>
> ---
> drivers/input/evdev.c | 3 +++
> drivers/input/misc/uinput.c | 3 +++
> include/uapi/linux/input.h | 1 +
> 3 files changed, 7 insertions(+)
>
> diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
> index d7dd6fcf2db0..24a90793caf0 100644
> --- a/drivers/input/evdev.c
> +++ b/drivers/input/evdev.c
> @@ -228,6 +228,9 @@ static void __pass_event(struct evdev_client *client,
> event->input_event_sec;
> client->buffer[client->tail].input_event_usec =
> event->input_event_usec;
> +#ifdef CONFIG_SPARC64
> + client->buffer[client->tail].__pad = 0;
> +#endif
> client->buffer[client->tail].type = EV_SYN;
> client->buffer[client->tail].code = SYN_DROPPED;
> client->buffer[client->tail].value = 0;

I do not like ifdefs here, do you think we could write:

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,
};

to ensure all padded fields are initialized? This is not hot path as we
do not expect queue to overfill too often.

Thanks.

--
Dmitry

2019-11-11 19:21:47

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 8/8] Input: input_event: fix struct padding on sparc64

On Mon, Nov 11, 2019 at 7:28 PM Dmitry Torokhov
<[email protected]> wrote:

> I do not like ifdefs here, do you think we could write:
>
> 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,
> };
>
> to ensure all padded fields are initialized? This is not hot path as we
> do not expect queue to overfill too often.

Good idea, changed both instances now. Thanks for taking a look!

Arnd

2019-11-20 19:14:59

by Ben Hutchings

[permalink] [raw]
Subject: Re: [Y2038] [PATCH 3/8] powerpc: fix vdso32 for ppc64le

On Fri, 2019-11-08 at 21:34 +0100, Arnd Bergmann wrote:
> On little-endian 32-bit application running on 64-bit kernels,
> the current vdso would read the wrong half of the xtime seconds
> field. Change it to return the lower half like it does on
> big-endian.

ppc64le doesn't have 32-bit compat so this is only theoretical.

Ben.

> Signed-off-by: Arnd Bergmann <[email protected]>
> ---
> arch/powerpc/kernel/vdso32/gettimeofday.S | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
> index becd9f8767ed..4327665ad86f 100644
> --- a/arch/powerpc/kernel/vdso32/gettimeofday.S
> +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
> @@ -13,7 +13,7 @@
> #include <asm/unistd.h>
>
> /* Offset for the low 32-bit part of a field of long type */
> -#ifdef CONFIG_PPC64
> +#if defined(CONFIG_PPC64) && defined(CONFIG_CPU_BIG_ENDIAN)
> #define LOPART 4
> #define TSPEC_TV_SEC TSPC64_TV_SEC+LOPART
> #else
--
Ben Hutchings, Software Developer Codethink Ltd
https://www.codethink.co.uk/ Dale House, 35 Dale Street
Manchester, M1 2HF, United Kingdom


2019-11-20 19:33:47

by Ben Hutchings

[permalink] [raw]
Subject: Re: [Y2038] [PATCH 7/8] ppdev: fix PPGETTIME/PPSETTIME ioctls

On Fri, 2019-11-08 at 21:34 +0100, Arnd Bergmann wrote:
> Going through the uses of timeval in the user space API,
> I noticed two bugs in ppdev that were introduced in the y2038
> conversion:
>
> * The range check was accidentally moved from ppsettime to
> ppgettime
>
> * On sparc64, the microseconds are in the other half of the
> 64-bit word.
>
> Fix both, and mark the fix for stable backports.

Like the patch for lpdev, this also doesn't completely fix sparc64.

Ben.

> Cc: [email protected]
> Fixes: 3b9ab374a1e6 ("ppdev: convert to y2038 safe")
> Signed-off-by: Arnd Bergmann <[email protected]>
> ---
> drivers/char/ppdev.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
> index c86f18aa8985..34bb88fe0b0a 100644
> --- a/drivers/char/ppdev.c
> +++ b/drivers/char/ppdev.c
> @@ -619,20 +619,27 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> if (copy_from_user(time32, argp, sizeof(time32)))
> return -EFAULT;
>
> + if ((time32[0] < 0) || (time32[1] < 0))
> + return -EINVAL;
> +
> return pp_set_timeout(pp->pdev, time32[0], time32[1]);
>
> case PPSETTIME64:
> if (copy_from_user(time64, argp, sizeof(time64)))
> return -EFAULT;
>
> + if ((time64[0] < 0) || (time64[1] < 0))
> + return -EINVAL;
> +
> + if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall())
> + time64[1] >>= 32;
> +
> return pp_set_timeout(pp->pdev, time64[0], time64[1]);
>
> case PPGETTIME32:
> jiffies_to_timespec64(pp->pdev->timeout, &ts);
> time32[0] = ts.tv_sec;
> time32[1] = ts.tv_nsec / NSEC_PER_USEC;
> - if ((time32[0] < 0) || (time32[1] < 0))
> - return -EINVAL;
>
> if (copy_to_user(argp, time32, sizeof(time32)))
> return -EFAULT;
> @@ -643,8 +650,9 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> jiffies_to_timespec64(pp->pdev->timeout, &ts);
> time64[0] = ts.tv_sec;
> time64[1] = ts.tv_nsec / NSEC_PER_USEC;
> - if ((time64[0] < 0) || (time64[1] < 0))
> - return -EINVAL;
> +
> + if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall())
> + time64[1] <<= 32;
>
> if (copy_to_user(argp, time64, sizeof(time64)))
> return -EFAULT;
--
Ben Hutchings, Software Developer Codethink Ltd
https://www.codethink.co.uk/ Dale House, 35 Dale Street
Manchester, M1 2HF, United Kingdom


2019-11-20 19:37:31

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [Y2038] [PATCH 3/8] powerpc: fix vdso32 for ppc64le

On Wed, Nov 20, 2019 at 8:13 PM Ben Hutchings
<[email protected]> wrote:
>
> On Fri, 2019-11-08 at 21:34 +0100, Arnd Bergmann wrote:
> > On little-endian 32-bit application running on 64-bit kernels,
> > the current vdso would read the wrong half of the xtime seconds
> > field. Change it to return the lower half like it does on
> > big-endian.
>
> ppc64le doesn't have 32-bit compat so this is only theoretical.

That is probably true. I only looked at the kernel, which today still
supports compat mode for ppc64le, but I saw the patches to disable
it, and I don't think anyone has even attempted building user space
for it.

Arnd

2019-11-20 21:51:48

by Ben Hutchings

[permalink] [raw]
Subject: Re: [Y2038] [PATCH 3/8] powerpc: fix vdso32 for ppc64le

On Wed, 2019-11-20 at 20:35 +0100, Arnd Bergmann wrote:
> On Wed, Nov 20, 2019 at 8:13 PM Ben Hutchings
> <[email protected]> wrote:
> > On Fri, 2019-11-08 at 21:34 +0100, Arnd Bergmann wrote:
> > > On little-endian 32-bit application running on 64-bit kernels,
> > > the current vdso would read the wrong half of the xtime seconds
> > > field. Change it to return the lower half like it does on
> > > big-endian.
> >
> > ppc64le doesn't have 32-bit compat so this is only theoretical.
>
> That is probably true. I only looked at the kernel, which today still
> supports compat mode for ppc64le, but I saw the patches to disable
> it, and I don't think anyone has even attempted building user space
> for it.

COMPAT is still enabled for some reason, but VDSO32 isn't (since 4.2).

Ben.

--
Ben Hutchings, Software Developer Codethink Ltd
https://www.codethink.co.uk/ Dale House, 35 Dale Street
Manchester, M1 2HF, United Kingdom


2019-11-21 10:04:40

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [Y2038] [PATCH 3/8] powerpc: fix vdso32 for ppc64le

On Wed, Nov 20, 2019 at 10:49 PM Ben Hutchings
<[email protected]> wrote:
> On Wed, 2019-11-20 at 20:35 +0100, Arnd Bergmann wrote:
> > On Wed, Nov 20, 2019 at 8:13 PM Ben Hutchings
> > <[email protected]> wrote:
> > > On Fri, 2019-11-08 at 21:34 +0100, Arnd Bergmann wrote:
> > > > On little-endian 32-bit application running on 64-bit kernels,
> > > > the current vdso would read the wrong half of the xtime seconds
> > > > field. Change it to return the lower half like it does on
> > > > big-endian.
> > >
> > > ppc64le doesn't have 32-bit compat so this is only theoretical.
> >
> > That is probably true. I only looked at the kernel, which today still
> > supports compat mode for ppc64le, but I saw the patches to disable
> > it, and I don't think anyone has even attempted building user space
> > for it.
>
> COMPAT is still enabled for some reason, but VDSO32 isn't (since 4.2).

Ok, I had missed that detail. Should I just drop my patch then?

Arnd

2019-11-21 14:09:42

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [Y2038] [PATCH 7/8] ppdev: fix PPGETTIME/PPSETTIME ioctls

On Wed, Nov 20, 2019 at 8:29 PM Ben Hutchings
<[email protected]> wrote:
>
> On Fri, 2019-11-08 at 21:34 +0100, Arnd Bergmann wrote:
> > Going through the uses of timeval in the user space API,
> > I noticed two bugs in ppdev that were introduced in the y2038
> > conversion:
> >
> > * The range check was accidentally moved from ppsettime to
> > ppgettime
> >
> > * On sparc64, the microseconds are in the other half of the
> > 64-bit word.
> >
> > Fix both, and mark the fix for stable backports.
>
> Like the patch for lpdev, this also doesn't completely fix sparc64.

I think the same applies as in the other patch:

- it actually works correctly because of the alignment
- it's already merged in linux-next
- if you wish, I can add another cleanup patch on top, but I'd
prefer to just leave it as it is.

Arnd

2019-11-21 15:58:37

by Ben Hutchings

[permalink] [raw]
Subject: Re: [Y2038] [PATCH 3/8] powerpc: fix vdso32 for ppc64le

On Thu, 2019-11-21 at 11:02 +0100, Arnd Bergmann wrote:
> On Wed, Nov 20, 2019 at 10:49 PM Ben Hutchings
> <[email protected]> wrote:
> > On Wed, 2019-11-20 at 20:35 +0100, Arnd Bergmann wrote:
> > > On Wed, Nov 20, 2019 at 8:13 PM Ben Hutchings
> > > <[email protected]> wrote:
> > > > On Fri, 2019-11-08 at 21:34 +0100, Arnd Bergmann wrote:
> > > > > On little-endian 32-bit application running on 64-bit kernels,
> > > > > the current vdso would read the wrong half of the xtime seconds
> > > > > field. Change it to return the lower half like it does on
> > > > > big-endian.
> > > >
> > > > ppc64le doesn't have 32-bit compat so this is only theoretical.
> > >
> > > That is probably true. I only looked at the kernel, which today still
> > > supports compat mode for ppc64le, but I saw the patches to disable
> > > it, and I don't think anyone has even attempted building user space
> > > for it.
> >
> > COMPAT is still enabled for some reason, but VDSO32 isn't (since 4.2).
>
> Ok, I had missed that detail. Should I just drop my patch then?

I think so.

Ben.

--
Ben Hutchings, Software Developer Codethink Ltd
https://www.codethink.co.uk/ Dale House, 35 Dale Street
Manchester, M1 2HF, United Kingdom