Bug 416753 - new 32bit time syscalls for 2038+
Summary: new 32bit time syscalls for 2038+
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Mark Wielaard
URL:
Keywords:
: 447386 (view as bug list)
Depends on:
Blocks:
 
Reported: 2020-01-25 15:47 UTC by Mark Wielaard
Modified: 2022-01-26 15:15 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
Add 32bit time64 syscalls for arm, mips32, ppc32 and x86. (37.41 KB, text/plain)
2020-02-28 12:50 UTC, Mark Wielaard
Details
Add 32bit time64 syscalls for arm, mips32, ppc32 and x86 (39.12 KB, text/plain)
2020-02-29 21:30 UTC, Mark Wielaard
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Wielaard 2020-01-25 15:47:09 UTC
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
Comment 1 Mark Wielaard 2020-02-28 12:50:50 UTC
Created attachment 126478 [details]
Add 32bit time64 syscalls for arm, mips32, ppc32 and x86.

I am testing the attached patch.
Comment 2 Mark Wielaard 2020-02-28 18:05:47 UTC
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.
Comment 3 Mark Wielaard 2020-02-29 21:30:01 UTC
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).
Comment 4 Julian Seward 2020-03-04 11:20:14 UTC
Hi Mark,

Any reason not to land this as-is?  Or do you prefer to have them all fixed
before landing anything?
Comment 5 Mark Wielaard 2020-03-04 14:12:45 UTC
(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
Comment 6 Mark Wielaard 2021-12-22 14:14:28 UTC
*** Bug 447386 has been marked as a duplicate of this bug. ***
Comment 7 Mark Wielaard 2022-01-26 15:15:29 UTC
*** Bug 447386 has been marked as a duplicate of this bug. ***