The linux kernel now supports variants of various syscalls that take a "bigger" timeval/time_t/timespec to solve the year 2038 issue on 32bit architectures. glibc 2.31 will prefer calling these syscalls. Fedora rawhide already uses a glibc prerelease (2.30.9000) which causes lots of failing testcases on arm and x86. 403 clock_gettime64 404 clock_settime64 405 clock_adjtime64 406 clock_getres_time64 407 clock_nanosleep_time64 408 timer_gettime64 409 timer_settime64 410 timerfd_gettime64 411 timerfd_settime64 412 utimensat_time64 413 pselect6_time64 414 ppoll_time64 416 io_pgetevents_time64 417 recvmmsg_time64 418 mq_timedsend_time64 419 mq_timedreceiv_time64 420 semtimedop_time64 421 rt_sigtimedwait_time64 422 futex_time64 423 sched_rr_get_interval_time64
Created attachment 126478 [details] Add 32bit time64 syscalls for arm, mips32, ppc32 and x86. I am testing the attached patch.
The patch works, but it does catch some issues with uninitialized fields in the new timespec64 (but that proves it works!). That is because glibc uses its own definition of timespec64: /* The glibc Y2038-proof struct __timespec64 structure for a time value. To keep things Posix-ish, we keep the nanoseconds field a 32-bit signed long, but since the Linux field is a 64-bit signed int, we pad our tv_nsec with a 32-bit unnamed bit-field padding. As a general rule the Linux kernel is ignoring upper 32 bits of tv_nsec field. */ struct __timespec64 { __time64_t tv_sec; /* Seconds */ # if BYTE_ORDER == BIG_ENDIAN __int32_t :32; /* Padding */ __int32_t tv_nsec; /* Nanoseconds */ # else __int32_t tv_nsec; /* Nanoseconds */ __int32_t :32; /* Padding */ # endif }; We'll have to use the same layout as glibc uses here and only check the tv_sec and tv_nsec field, not the whole struct, to avoid warning for the uninitialized padding.
Created attachment 126504 [details] Add 32bit time64 syscalls for arm, mips32, ppc32 and x86 This patch adds sycall wrappers for the following syscalls which use a 64bit time_t on 32bit arches: gettime64, settime64, clock_getres_time64, clock_nanosleep_time64, timer_gettime64, timer_settime64, timerfd_gettime64, timerfd_settime64, utimensat_time64, pselect6_time64, ppoll_time64, recvmmsg_time64, mq_timedsend_time64, mq_timedreceive_time64, semtimedop_time64, rt_sigtimedwait_time64, futex_time64 and sched_rr_get_interval_time64. Still missing are clock_adjtime64 and io_pgetevents_time64. For the more complicated syscalls futex[_time64], pselect6[_time64] and ppoll[_time64] there are shared pre and/or post helper functions. Other functions just have their own PRE and POST handler. Note that the vki_timespec64 struct really is the struct as used by by glibc (it internally translates a 32bit timespec struct to a 64bit timespec64 struct before passing it to any of the time64 syscalls). The kernel uses a 64-bit signed int, but is ignoring the upper 32 bits of the tv_nsec field. It does always write the full struct though. So avoid checking the padding is only needed for PRE_MEM_READ. There are two helper pre_read_timespec64 and pre_read_itimerspec64 to check the new structs. Tested on i686, armv7hl, ppc64le, aarch64, s390x and x86_64 (only the first 2 have the new time64 syscalls).
Hi Mark, Any reason not to land this as-is? Or do you prefer to have them all fixed before landing anything?
(In reply to Julian Seward from comment #4) > Any reason not to land this as-is? Or do you prefer to have them all fixed > before landing anything? I just wanted to see if someone would yell and scream about the patch. But it seems people think it is reasonable and it does fix issues with the latest linux kernel/glibc combo on 32bit arches. The 2 missing syscalls are clock_adjtime64 which is complicated, probably never really used and I suspect our time32 version is not 100% correct (or really old, the struct we are checking is missing some fields that are in the kernel version), the other io_pgetevents_time64 we don't implement the "time32" version either. commit 3d6a8157d52f18261f2c1a0888c2cfd3289b371e Author: Mark Wielaard <mark@klomp.org> Date: Fri Feb 28 13:36:31 2020 +0100 Add 32bit time64 syscalls for arm, mips32, ppc32 and x86. This patch adds sycall wrappers for the following syscalls which use a 64bit time_t on 32bit arches: gettime64, settime64, clock_getres_time64, clock_nanosleep_time64, timer_gettime64, timer_settime64, timerfd_gettime64, timerfd_settime64, utimensat_time64, pselect6_time64, ppoll_time64, recvmmsg_time64, mq_timedsend_time64, mq_timedreceive_time64, semtimedop_time64, rt_sigtimedwait_time64, futex_time64 and sched_rr_get_interval_time64. Still missing are clock_adjtime64 and io_pgetevents_time64. For the more complicated syscalls futex[_time64], pselect6[_time64] and ppoll[_time64] there are shared pre and/or post helper functions. Other functions just have their own PRE and POST handler. Note that the vki_timespec64 struct really is the struct as used by by glibc (it internally translates a 32bit timespec struct to a 64bit timespec64 struct before passing it to any of the time64 syscalls). The kernel uses a 64-bit signed int, but is ignoring the upper 32 bits of the tv_nsec field. It does always write the full struct though. So avoid checking the padding is only needed for PRE_MEM_READ. There are two helper pre_read_timespec64 and pre_read_itimerspec64 to check the new structs. https://bugs.kde.org/show_bug.cgi?id=416753
*** Bug 447386 has been marked as a duplicate of this bug. ***