From 3f649995a112b91754b49b7fff389385ce55f54f Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Sat, 27 Jul 2019 19:26:23 -0400 Subject: Remove access to legacy time zone support in gettimeofday etc. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gettimeofday and ftime are not quite fully implementable on systems that only provide a primitive equivalent to clock_gettime, because they can also report information about a system-wide time zone. This mechanism has been deprecated for many years because it can only be configured on a system-wide basis, and because it only supports the simplest kinds of daylight-savings rules, but we’ve supported it on a best-effort basis until now. This patch removes our support for it: * The type 'struct timezone' is still declared as a complete type in , but code that uses its fields (tz_minuteswest and tz_dsttime) will not compile. * Similarly, code that uses the 'timezone' and 'dstflag' fields of struct timeb will not compile anymore. (This is a willful violation of the older iterations of XPG that included sys/timeb.h; the relevant conformance tests are XFAILed.) * Old binaries that pass a non-NULL 'tzp' pointer to gettimeofday will always receive a 'struct timezone' whose tz_minuteswest and tz_dsttime fields are zero (as if the system were operating on UTC). * Similarly, old binaries that call ftime will always receive a 'struct timeb' whose timezone and dstflag fields are zero. * If the 'tzp' argument to settimeofday is not NULL, the call will fail and set errno to ENOSYS. (This was already the case on the Hurd.) * glibc will always pass a second argument of NULL when invoking a kernel-provided gettimeofday. * On Alpha, the compat symbols gettimeofday@GLIBC_2.0 and settimeofday@GLIBC_2.0 (which used 32-bit time_t) now convert their arguments and call system primitives that use 64-bit time_t, instead of invoking legacy “osf” system calls. ChangeLog: * time/sys/time.h (struct timezone): Remove tz_minuteswest and tz_dsttime fields; replace with padding to preserve the size. * time/sys/timeb.h (struct timeb): Remove timezone and dstflag fields; replace with padding to preserve the size. * conform/Makefile: XFAIL tests because struct timeb is no longer fully conformant with Unix98. * sysdeps/posix/gettimeofday.c * sysdeps/unix/sysv/linux/gettimeofday.c * sysdeps/unix/sysv/linux/aarch64/gettimeofday.c * sysdeps/unix/sysv/linux/powerpc/gettimeofday.c * sysdeps/unix/sysv/linux/x86/gettimeofday.c (gettimeofday): When ‘tz’ argument is not NULL, just clear it. Always pass a null pointer as the second argument to a gettimeofday (v)syscall. * sysdeps/unix/bsd/ftime.c: Unconditionally clear the memory that was formerly the ‘timezone’ and ‘dstflag’ fields of struct timeb. * sysdeps/unix/syscalls.list: Remove entry for settimeofday. * sysdeps/unix/settimeofday.c: New file. (settimeofday): Fail with ENOSYS if ‘tz’ argument is not NULL. * sysdeps/unix/sysv/linux/alpha/syscalls.list: Remove entries for osf_gettimeofday, osf_settimeofday, and settimeofday. * sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c: New file. Call the 64-bit gettimeofday, then convert to a 32-bit struct timeval. On overflow, saturate the struct timeval and fail with EOVERFLOW. * sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c: New file. Convert to a 64-bit struct timeval and call 64-bit settimeofday. Fail with ENOSYS if ‘tz’ argument is not NULL. * sunrpc/auth_des.c, sunrpc/auth_unix.c * sysdeps/posix/time.c, sysdeps/unix/stime.c: Remove unnecessary casts of NULL. * sysdeps/unix/sysv/linux/powerpc/time.c (time_syscall): Use (void *)0 instead of NULL when passing a null pointer as an untyped argument. * manual/time.texi: Remove documentation of fields of struct timezone. Revise text to further emphasize that the second argument to gettimeofday/settimeofday should always be a null pointer. --- NEWS | 49 +++++++++++++++ conform/Makefile | 7 +++ manual/time.texi | 76 ++++++++++-------------- sunrpc/auth_des.c | 4 +- sunrpc/auth_unix.c | 4 +- sunrpc/create_xid.c | 2 +- sunrpc/svcauth_des.c | 2 +- sysdeps/mach/gettimeofday.c | 4 +- sysdeps/posix/gettimeofday.c | 31 ++-------- sysdeps/posix/time.c | 2 +- sysdeps/unix/bsd/ftime.c | 10 ++-- sysdeps/unix/settimeofday.c | 36 +++++++++++ sysdeps/unix/stime.c | 2 +- sysdeps/unix/syscalls.list | 1 - sysdeps/unix/sysv/linux/aarch64/gettimeofday.c | 8 ++- sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c | 62 +++++++++++++++++++ sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c | 51 ++++++++++++++++ sysdeps/unix/sysv/linux/alpha/syscalls.list | 3 - sysdeps/unix/sysv/linux/gettimeofday.c | 5 +- sysdeps/unix/sysv/linux/powerpc/gettimeofday.c | 13 +++- sysdeps/unix/sysv/linux/powerpc/time.c | 2 +- sysdeps/unix/sysv/linux/x86/gettimeofday.c | 8 ++- time/sys/time.h | 4 +- time/sys/timeb.h | 5 +- 24 files changed, 290 insertions(+), 101 deletions(-) create mode 100644 sysdeps/unix/settimeofday.c create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c create mode 100644 sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c diff --git a/NEWS b/NEWS index ddc800ba59..f83312d276 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,55 @@ See the end for copying conditions. Please send GNU C library bug reports via using `glibc' in the "product" field. + +Version 2.31 + +Major new features: + +Deprecated and removed features, and other changes affecting compatibility: + +* The crude time zone support in ftime, gettimeofday, and settimeofday + has been removed. + + This 4.2-BSD-era feature has been deprecated for many years, as it cannot + handle the full complexity of the world's timezones, but hitherto we have + supported it on a best-effort basis. Changes required to support 64-bit + time_t on 32-bit architectures have made this no longer practical. + + In this release: + + * The type 'struct timezone' is still declared as a complete type in + , but code that uses its fields (tz_minuteswest and + tz_dsttime) will not compile. + + * Similarly, code that uses the 'timezone' and 'dstflag' fields of + struct timeb will not compile anymore. + + * Old binaries that pass a non-NULL 'tzp' pointer to gettimeofday will + always receive a 'struct timezone' whose tz_minuteswest and tz_dsttime + fields are zero (as if the system were operating on UTC). + + * Similarly, old binaries that call ftime will always receive a + 'struct timeb' whose timezone and dstflag fields are zero. + + * If the 'tzp' argument to settimeofday is not NULL, the call will fail + and set errno to ENOSYS. (This was already the case on the Hurd.) + + In a future release, 'struct timezone' will be completely removed from + ; the second argument to gettimeofday and settimeofday + will have type void *. (This is already the case when strict POSIX + conformance is requested.) We do not plan to change the behavior of + gettimeofday or ftime further. + +Changes to build and runtime requirements: + +Security related changes: + +The following bugs are resolved with this release: + + [The release manager will add the list generated by + scripts/list-fixed-bugs.py just before the release.] + Version 2.30 diff --git a/conform/Makefile b/conform/Makefile index 59d569c4c5..7a1b927b45 100644 --- a/conform/Makefile +++ b/conform/Makefile @@ -241,3 +241,10 @@ test-xfail-XPG42/ndbm.h/linknamespace = yes test-xfail-UNIX98/ndbm.h/linknamespace = yes test-xfail-XOPEN2K/ndbm.h/linknamespace = yes test-xfail-XOPEN2K8/ndbm.h/linknamespace = yes + +# Willful violation of older POSIX standards regarding the contents +# of struct timeb: the 'timezone' and 'dstflag' fields have been +# removed, intentionally, to flush out old programs that still use them. +test-xfail-UNIX98/sys/timeb.h/conform = yes +test-xfail-XOPEN2K/sys/timeb.h/conform = yes +test-xfail-XPG42/sys/timeb.h/conform = yes diff --git a/manual/time.texi b/manual/time.texi index bfa46dd45b..03d74c4ae7 100644 --- a/manual/time.texi +++ b/manual/time.texi @@ -461,46 +461,38 @@ declared in @file{sys/time.h}. @deftp {Data Type} {struct timezone} @standards{BSD, sys/time.h} -The @code{struct timezone} structure is used to hold minimal information -about the local time zone. It has the following members: - -@table @code -@item int tz_minuteswest -This is the number of minutes west of UTC. - -@item int tz_dsttime -If nonzero, Daylight Saving Time applies during some part of the year. -@end table - -The @code{struct timezone} type is obsolete and should never be used. -Instead, use the facilities described in @ref{Time Zone Functions}. +The @w{@code{struct timezone}} type is obsolete and should never be +used. @gnusystems{} do not support using @w{@code{struct timezone}} +to represent time zone information, because it cannot represent the +full complexity of real-world time zones. Instead, use the facilities +described in @ref{Time Zone Functions}. + +For backward compatibility, some functions take arguments of type +@w{@code{struct timezone *}}. New programs should invariably pass +a null pointer for any such argument. @end deftp @deftypefun int gettimeofday (struct timeval *@var{tp}, struct timezone *@var{tzp}) @standards{BSD, sys/time.h} @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} -@c On most GNU/Linux systems this is a direct syscall, but the posix/ -@c implementation (not used on GNU/Linux or GNU/Hurd) relies on time and -@c localtime_r, saving and restoring tzname in an unsafe manner. @c On some GNU/Linux variants, ifunc resolvers are used in shared libc @c for vdso resolution. ifunc-vdso-revisit. The @code{gettimeofday} function returns the current calendar time as the elapsed time since the epoch in the @code{struct timeval} structure indicated by @var{tp}. (@pxref{Elapsed Time} for a description of -@code{struct timeval}). Information about the time zone is returned in -the structure pointed to by @var{tzp}. If the @var{tzp} argument is a null -pointer, time zone information is ignored. +@code{struct timeval}). + +The @var{tzp} argument should always be a null pointer. If it is not +a null pointer, a crude representation of the time zone may be written +to the object it points to, or meaningless values may be written there +instead, or the call may fail. The return value is @code{0} on success and @code{-1} on failure. The following @code{errno} error condition is defined for this function: @table @code @item ENOSYS -The operating system does not support getting time zone information, and -@var{tzp} is not a null pointer. @gnusystems{} do not -support using @w{@code{struct timezone}} to represent time zone -information; that is an obsolete feature of 4.3 BSD. -Instead, use the facilities described in @ref{Time Zone Functions}. +@var{tzp} is not a null pointer. @end table @end deftypefun @@ -510,28 +502,27 @@ Instead, use the facilities described in @ref{Time Zone Functions}. @c On HURD, it calls host_set_time with a privileged port. On other @c unix systems, it's a syscall. The @code{settimeofday} function sets the current calendar time in the -system clock according to the arguments. As for @code{gettimeofday}, -the calendar time is represented as the elapsed time since the epoch. -As for @code{gettimeofday}, time zone information is ignored if -@var{tzp} is a null pointer. +system clock according to its arguments. You must be a privileged +user in order to use @code{settimeofday}. -You must be a privileged user in order to use @code{settimeofday}. - -Some kernels automatically set the system clock from some source such as -a hardware clock when they start up. Others, including Linux, place the -system clock in an ``invalid'' state (in which attempts to read the clock -fail). A call of @code{stime} removes the system clock from an invalid -state, and system startup scripts typically run a program that calls -@code{stime}. +Some operating systems automatically set the system clock from some +source such as a hardware clock when they start up. Others place the +system clock in an ``invalid'' state (in which attempts to read the +clock fail) when they start up. A call of @code{settimeofday} removes +the system clock from an invalid state. @code{settimeofday} causes a sudden jump forwards or backwards, which -can cause a variety of problems in a system. Use @code{adjtime} (below) -to make a smooth transition from one time to another by temporarily -speeding up or slowing down the clock. +can cause a variety of problems in a system. Use @code{adjtime} or +@code{adjtimex} (below) to make a smooth transition from one time to +another by temporarily speeding up or slowing down the clock. + +As with @code{gettimeofday}, the calendar time is represented as the +elapsed time since the epoch. -With a Linux kernel, @code{adjtimex} does the same thing and can also -make permanent changes to the speed of the system clock so it doesn't -need to be corrected as often. +As with @code{gettimeofday}, the @var{tzp} argument should always be a +null pointer. If it is not a null pointer, the call may fail, or the +object pointed to may be ignored, or it may have some effect on future +calls to @code{gettimeofday} with @var{tzp} not null. The return value is @code{0} on success and @code{-1} on failure. The following @code{errno} error conditions are defined for this function: @@ -541,7 +532,6 @@ following @code{errno} error conditions are defined for this function: This process cannot set the clock because it is not privileged. @item ENOSYS -The operating system does not support setting time zone information, and @var{tzp} is not a null pointer. @end table @end deftypefun diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c index 5b6f985bc2..d36c34006d 100644 --- a/sunrpc/auth_des.c +++ b/sunrpc/auth_des.c @@ -252,7 +252,7 @@ authdes_marshal (AUTH *auth, XDR *xdrs) * Figure out the "time", accounting for any time difference * with the server if necessary. */ - __gettimeofday (&tval, (struct timezone *) NULL); + __gettimeofday (&tval, 0); ad->ad_timestamp.tv_sec = tval.tv_sec + ad->ad_timediff.tv_sec; ad->ad_timestamp.tv_usec = tval.tv_usec + ad->ad_timediff.tv_usec; if (ad->ad_timestamp.tv_usec >= MILLION) @@ -453,7 +453,7 @@ synchronize (struct sockaddr *syncaddr, struct rpc_timeval *timep) if (rtime ((struct sockaddr_in *) syncaddr, timep, &timeout) < 0) return FALSE; - __gettimeofday (&mytime, (struct timezone *) NULL); + __gettimeofday (&mytime, 0); timep->tv_sec -= mytime.tv_sec; if (mytime.tv_usec > timep->tv_usec) { diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c index b035fdd870..d87e325712 100644 --- a/sunrpc/auth_unix.c +++ b/sunrpc/auth_unix.c @@ -122,7 +122,7 @@ no_memory: /* * fill in param struct from the given params */ - (void) __gettimeofday (&now, (struct timezone *) 0); + (void) __gettimeofday (&now, 0); aup.aup_time = now.tv_sec; aup.aup_machname = machname; aup.aup_uid = uid; @@ -297,7 +297,7 @@ authunix_refresh (AUTH *auth) goto done; /* update the time and serialize in place */ - (void) __gettimeofday (&now, (struct timezone *) 0); + (void) __gettimeofday (&now, 0); aup.aup_time = now.tv_sec; xdrs.x_op = XDR_ENCODE; XDR_SETPOS (&xdrs, 0); diff --git a/sunrpc/create_xid.c b/sunrpc/create_xid.c index a44187f07c..c209cd0b69 100644 --- a/sunrpc/create_xid.c +++ b/sunrpc/create_xid.c @@ -41,7 +41,7 @@ _create_xid (void) { struct timeval now; - __gettimeofday (&now, (struct timezone *) 0); + __gettimeofday (&now, 0); __srand48_r (now.tv_sec ^ now.tv_usec ^ pid, &__rpc_lrand48_data); is_initialized = pid; diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c index c5a512d6f8..a87ae68bcb 100644 --- a/sunrpc/svcauth_des.c +++ b/sunrpc/svcauth_des.c @@ -295,7 +295,7 @@ _svcauth_des (register struct svc_req *rqst, register struct rpc_msg *msg) debug ("timestamp before last seen"); return AUTH_REJECTEDVERF; /* replay */ } - __gettimeofday (¤t, (struct timezone *) NULL); + __gettimeofday (¤t, 0); current.tv_sec -= window; /* allow for expiration */ if (!BEFORE (¤t, ×tamp)) { diff --git a/sysdeps/mach/gettimeofday.c b/sysdeps/mach/gettimeofday.c index 8d0dfbb7dc..f8c9b7ce3f 100644 --- a/sysdeps/mach/gettimeofday.c +++ b/sysdeps/mach/gettimeofday.c @@ -28,8 +28,8 @@ __gettimeofday (struct timeval *tv, struct timezone *tz) { kern_return_t err; - if (tz != NULL) - *tz = (struct timezone){0, 0}; /* XXX */ + if (tz) + memset (tz, 0, sizeof (struct timezone)); if (err = __host_get_time (__mach_host_self (), (time_value_t *) tv)) { diff --git a/sysdeps/posix/gettimeofday.c b/sysdeps/posix/gettimeofday.c index 6ba625e13e..f5c462e11b 100644 --- a/sysdeps/posix/gettimeofday.c +++ b/sysdeps/posix/gettimeofday.c @@ -31,34 +31,11 @@ __gettimeofday (struct timeval *tv, struct timezone *tz) return -1; } - tv->tv_sec = (long int) time ((time_t *) NULL); - tv->tv_usec = 0L; + if (tz) + memset (tz, 0, sizeof (struct timezone)); - if (tz != NULL) - { - const time_t timer = tv->tv_sec; - struct tm tm; - const struct tm *tmp; - - const long int save_timezone = __timezone; - const long int save_daylight = __daylight; - char *save_tzname[2]; - save_tzname[0] = __tzname[0]; - save_tzname[1] = __tzname[1]; - - tmp = localtime_r (&timer, &tm); - - tz->tz_minuteswest = __timezone / 60; - tz->tz_dsttime = __daylight; - - __timezone = save_timezone; - __daylight = save_daylight; - __tzname[0] = save_tzname[0]; - __tzname[1] = save_tzname[1]; - - if (tmp == NULL) - return -1; - } + tv->tv_usec = 0; + tv->tv_sec = time (0); return 0; } diff --git a/sysdeps/posix/time.c b/sysdeps/posix/time.c index e1b3bc8d4c..2f7f7a6f3c 100644 --- a/sysdeps/posix/time.c +++ b/sysdeps/posix/time.c @@ -28,7 +28,7 @@ time (time_t *t) struct timeval tv; time_t result; - if (__gettimeofday (&tv, (struct timezone *) NULL)) + if (__gettimeofday (&tv, 0)) result = (time_t) -1; else result = (time_t) tv.tv_sec; diff --git a/sysdeps/unix/bsd/ftime.c b/sysdeps/unix/bsd/ftime.c index 3a1c6e9b01..32ce84e662 100644 --- a/sysdeps/unix/bsd/ftime.c +++ b/sysdeps/unix/bsd/ftime.c @@ -17,14 +17,14 @@ #include #include +#include int ftime (struct timeb *timebuf) { struct timeval tv; - struct timezone tz; - if (__gettimeofday (&tv, &tz) < 0) + if (__gettimeofday (&tv, 0) < 0) return -1; timebuf->time = tv.tv_sec; @@ -34,7 +34,9 @@ ftime (struct timeb *timebuf) ++timebuf->time; timebuf->millitm = 0; } - timebuf->timezone = tz.tz_minuteswest; - timebuf->dstflag = tz.tz_dsttime; + + memset (timebuf->__preserve_historic_size, 0, + sizeof timebuf->__preserve_historic_size); + return 0; } diff --git a/sysdeps/unix/settimeofday.c b/sysdeps/unix/settimeofday.c new file mode 100644 index 0000000000..741493b470 --- /dev/null +++ b/sysdeps/unix/settimeofday.c @@ -0,0 +1,36 @@ +/* settimeofday -- Set the current time of day. Unix version. + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +/* Set the current time of day and timezone information. + This call is restricted to the super-user. */ +int +__settimeofday (const struct timeval *tv, const struct timezone *tz) +{ + if (tz) + { + __set_errno (ENOSYS); + return -1; + } + return INLINE_SYSCALL_CALL (settimeofday, tv, (void *)0); +} +weak_alias (__settimeofday, settimeofday); diff --git a/sysdeps/unix/stime.c b/sysdeps/unix/stime.c index b0809be400..554b3efa60 100644 --- a/sysdeps/unix/stime.c +++ b/sysdeps/unix/stime.c @@ -35,5 +35,5 @@ stime (const time_t *when) tv.tv_sec = *when; tv.tv_usec = 0; - return __settimeofday (&tv, (struct timezone *) 0); + return __settimeofday (&tv, 0); } diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list index 61e5360b4d..5fedd5733d 100644 --- a/sysdeps/unix/syscalls.list +++ b/sysdeps/unix/syscalls.list @@ -76,7 +76,6 @@ setreuid - setreuid i:ii __setreuid setreuid setrlimit - setrlimit i:ip __setrlimit setrlimit setsid - setsid i: __setsid setsid setsockopt - setsockopt i:iiibn setsockopt __setsockopt -settimeofday - settimeofday i:PP __settimeofday settimeofday setuid - setuid i:i __setuid setuid shutdown - shutdown i:ii shutdown sigaction - sigaction i:ipp __sigaction sigaction diff --git a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c index 9180b50bf7..47330e2f83 100644 --- a/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c +++ b/sysdeps/unix/sysv/linux/aarch64/gettimeofday.c @@ -35,7 +35,9 @@ static int __gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz) { - return INLINE_VSYSCALL (gettimeofday, 2, tv, tz); + if (tz) + memset (tz, 0, sizeof (struct timezone)); + return INLINE_VSYSCALL (gettimeofday, 2, tv, (void *)0); } /* PREPARE_VERSION_KNOWN will need an __LP64__ ifdef when ILP32 support @@ -61,7 +63,9 @@ __hidden_ver1 (__gettimeofday_vsyscall, __GI___gettimeofday, int __gettimeofday (struct timeval *tv, struct timezone *tz) { - return INLINE_SYSCALL (gettimeofday, 2, tv, tz); + if (tz) + memset (tz, 0, sizeof (struct timezone)); + return INLINE_SYSCALL (gettimeofday, 2, tv, (void *)0); } libc_hidden_def (__gettimeofday) diff --git a/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c new file mode 100644 index 0000000000..8e57727887 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/osf_gettimeofday.c @@ -0,0 +1,62 @@ +/* gettimeofday -- Get the current time of day. Linux/Alpha/tv32 version. + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +struct timeval32 +{ + int tv_sec, tv_usec; +}; + +/* Get the current time of day and timezone information. */ +int +attribute_compat_text_section +__gettimeofday_tv32 (struct timeval32 *tv32, + struct timezone *tz) +{ + struct timeval tv64; + if (__gettimeofday (&tv64, tz)) + return -1; + + /* The tv_sec field of a 64-bit struct timeval will overflow the + range representable by 'int' at 2038-01-19 03:14:07 +0000. */ + if (tv64.tv_sec > (time_t)INT_MAX) + { + tv32.tv_sec = INT_MAX; + tv32.tv_usec = 0; + __set_errno (EOVERFLOW); + return -1; + } + tv32.tv_sec = (int)tv64.tv_sec; + + /* The tv_usec field of a 64-bit struct timeval may be a 64-bit + type, but it never contains a value outside the range [0, 999999], + so this cast is guaranteed not to lose information. */ + tv32.tv_usec = (int)tv64.tv_usec; + + return 0; +} + +compat_symbol (libc, __gettimeofday_tv32, gettimeofday, GLIBC_2_0); +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c new file mode 100644 index 0000000000..2ab2f8163d --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c @@ -0,0 +1,51 @@ +/* settimeofday -- Set the current time of day. Linux/Alpha/tv32 version. + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) + +struct timeval32 +{ + int tv_sec, tv_usec; +}; + +/* Set the current time of day and timezone information. + This call is restricted to the super-user. */ +int +attribute_compat_text_section +__settimeofday_tv32 (const struct timeval32 *tv32, + const struct timezone *tz) +{ + if (tz) + { + __set_errno (ENOSYS); + return -1; + } + + struct timeval tv64; + tv64.tv_sec = tv32.tv_sec; + tv64.tv_usec = tv32.tv_usec; + return INLINE_SYSCALL_CALL (settimeofday, tv, (void *)0); +} + +compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0); +#endif diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list index 12cd021b60..8244f941b8 100644 --- a/sysdeps/unix/sysv/linux/alpha/syscalls.list +++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list @@ -23,8 +23,6 @@ pciconfig_write EXTRA pciconfig_write 5 pciconfig_write pciconfig_iobase EXTRA pciconfig_iobase 3 __pciconfig_iobase pciconfig_iobase # support old timeval32 entry points -osf_gettimeofday - osf_gettimeofday 2 __gettimeofday_tv32 __gettimeofday@GLIBC_2.0 gettimeofday@GLIBC_2.0 -osf_settimeofday - osf_settimeofday 2 __settimeofday_tv32 settimeofday@GLIBC_2.0 osf_getitimer - osf_getitimer 2 __getitimer_tv32 getitimer@GLIBC_2.0 osf_setitimer - osf_setitimer 3 __setitimer_tv32 setitimer@GLIBC_2.0 osf_utimes - osf_utimes 2 __utimes_tv32 utimes@GLIBC_2.0 @@ -33,7 +31,6 @@ osf_wait4 - osf_wait4 4 __wait4_tv32 wait4@GLIBC_2.0 # support new timeval64 entry points gettimeofday - gettimeofday 2 __GI___gettimeofday gettimeofday@@GLIBC_2.1 __gettimeofday@@GLIBC_2.1 -settimeofday - settimeofday 2 __settimeofday settimeofday@@GLIBC_2.1 getitimer - getitimer 2 __getitimer getitimer@@GLIBC_2.1 setitimer - setitimer 3 __setitimer setitimer@@GLIBC_2.1 utimes - utimes 2 __utimes utimes@@GLIBC_2.1 diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c index a74f03825a..3509ca9530 100644 --- a/sysdeps/unix/sysv/linux/gettimeofday.c +++ b/sysdeps/unix/sysv/linux/gettimeofday.c @@ -18,6 +18,7 @@ #include #include +#include #undef __gettimeofday @@ -32,7 +33,9 @@ int __gettimeofday (struct timeval *tv, struct timezone *tz) { - return INLINE_VSYSCALL (gettimeofday, 2, tv, tz); + if (tz) + memset (tz, 0, sizeof (struct timezone)); + return INLINE_VSYSCALL (gettimeofday, 2, tv, (void *)0); } libc_hidden_def (__gettimeofday) weak_alias (__gettimeofday, gettimeofday) diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c index 463b678ad9..e798a80ee0 100644 --- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c +++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c @@ -22,6 +22,7 @@ #endif #include +#include #ifdef SHARED @@ -35,7 +36,9 @@ int __gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz) { - return INLINE_VSYSCALL (gettimeofday, 2, tv, tz); + if (tz) + memset (tz, 0, sizeof (struct timezone)); + return INLINE_VSYSCALL (gettimeofday, 2, tv, (void *)0); } /* __GI___gettimeofday is defined as hidden and for ppc32 it enables the @@ -54,7 +57,9 @@ __gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz) static int __gettimeofday_syscall (struct timeval *tv, struct timezone *tz) { - return INLINE_SYSCALL (gettimeofday, 2, tv, tz); + if (tz) + memset (tz, 0, sizeof (struct timezone)); + return INLINE_SYSCALL (gettimeofday, 2, tv, (void *)0); } # define INIT_ARCH() \ @@ -76,7 +81,9 @@ libc_hidden_def (__gettimeofday) int __gettimeofday (struct timeval *tv, struct timezone *tz) { - return INLINE_SYSCALL (gettimeofday, 2, tv, tz); + if (tz) + memset (tz, 0, sizeof (struct timezone)); + return INLINE_SYSCALL (gettimeofday, 2, tv, (void *)0); } libc_hidden_def (__gettimeofday) diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c index cb3e8b9a73..42b0d2d562 100644 --- a/sysdeps/unix/sysv/linux/powerpc/time.c +++ b/sysdeps/unix/sysv/linux/powerpc/time.c @@ -56,7 +56,7 @@ time_syscall (time_t *t) struct timeval tv; time_t result; - if (INLINE_VSYSCALL (gettimeofday, 2, &tv, NULL) < 0) + if (INLINE_VSYSCALL (gettimeofday, 2, &tv, (void *)0) < 0) result = (time_t) -1; else result = (time_t) tv.tv_sec; diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c index 8886ccd707..58a8763ef9 100644 --- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c +++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c @@ -26,7 +26,9 @@ static int __gettimeofday_syscall (struct timeval *tv, struct timezone *tz) { - return INLINE_SYSCALL (gettimeofday, 2, tv, tz); + if (tz) + memset (tz, 0, sizeof (struct timezone)); + return INLINE_SYSCALL (gettimeofday, 2, tv, (void *)0); } # ifndef __gettimeofday_type @@ -52,7 +54,9 @@ libc_hidden_def (__gettimeofday) int __gettimeofday (struct timeval *tv, struct timezone *tz) { - return INLINE_SYSCALL (gettimeofday, 2, tv, tz); + if (tz) + memset (tz, 0, sizeof (struct timezone)); + return INLINE_SYSCALL (gettimeofday, 2, tv, (void *)0); } libc_hidden_def (__gettimeofday) diff --git a/time/sys/time.h b/time/sys/time.h index 5dbc7fc627..2d5984204f 100644 --- a/time/sys/time.h +++ b/time/sys/time.h @@ -51,8 +51,8 @@ __BEGIN_DECLS This is obsolete and should never be used. */ struct timezone { - int tz_minuteswest; /* Minutes west of GMT. */ - int tz_dsttime; /* Nonzero if DST is ever in effect. */ + /* Formerly: int tz_minuteswest; int tz_dsttime; */ + char __preserve_historic_size [2 * sizeof (int)]; }; typedef struct timezone *__restrict __timezone_ptr_t; diff --git a/time/sys/timeb.h b/time/sys/timeb.h index 6333e8074d..11f47e9d6b 100644 --- a/time/sys/timeb.h +++ b/time/sys/timeb.h @@ -30,8 +30,9 @@ struct timeb { time_t time; /* Seconds since epoch, as from `time'. */ unsigned short int millitm; /* Additional milliseconds. */ - short int timezone; /* Minutes west of GMT. */ - short int dstflag; /* Nonzero if Daylight Savings Time used. */ + + /* Formerly: short int timezone; short int dstflag; */ + char __preserve_historic_size [2 * sizeof (short int)]; }; /* Fill in TIMEBUF with information about the current time. */ -- cgit v1.2.3