Re: [PATCH] y2038: uapi: use 64-bit __kernel_old_timespec::tv_nsec on x32

From: Arnd Bergmann

Date: Fri Feb 27 2026 - 04:08:05 EST


On Fri, Feb 27, 2026, at 08:18, Thomas Weißschuh wrote:
> 'struct __kernel_old_timespec' represents the 'native' time ABI of the
> kernel. On 32-bit systems it uses 32-bit fields and on 64-bit systems
> it uses 64-bit fields.
> However the x86 x32 ABI uses the 64-bit time ABI natively.
> This is correctly handled for the 'tv_sec' fields, through the typedefs
> of '__kernel_old_time_t' -> '__kernel_long_t' -> 'long long'. The same
> treatment was missed for 'tv_nsec'.

Not sure about this patch, the choice of 'long' was clearly deliberate
here because that is what POSIX mandates for 'struct timespec', and what
glibc uses as well. Any access to an actual userspec timespec
is supposed to go through get_timespec64(), which handles the padding
like this

int get_timespec64(struct timespec64 *ts,
const struct __kernel_timespec __user *uts)
{
struct __kernel_timespec kts;
int ret;

ret = copy_from_user(&kts, uts, sizeof(kts));
if (ret)
return -EFAULT;

ts->tv_sec = kts.tv_sec;

/* Zero out the padding in compat mode */
if (in_compat_syscall())
kts.tv_nsec &= 0xFFFFFFFFUL;

/* In 32-bit mode, this drops the padding */
ts->tv_nsec = kts.tv_nsec;

return 0;
}

If there are any code paths that are missing this, they are likely
also broken for all other compat tasks in the time64 syscalls

> @@ -30,7 +30,7 @@ struct __kernel_old_timeval {
>
> struct __kernel_old_timespec {
> __kernel_old_time_t tv_sec; /* seconds */
> - long tv_nsec; /* nanoseconds */
> + __kernel_long_t tv_nsec; /* nanoseconds */
> };

I think the hidden padding is an actual problem here, but I
would address that with extra padding, similar to what glibc
has, e.g.

struct __kernel_old_timespec {
__kernel_old_time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
#if defined(__x86_64__) && defined(__ILP32__)
long :32; /* pad to alignment */
#endif
};

It may be better to duplicate the structure definition and keep
the x32 hack in arch/x86/uapi/asm/posix_types.h, the same way
we do for the sparc64 __kernel_old_timeval, which has a very
similar issue.

Arnd