diff --git a/NEWS b/NEWS index 8727b5e7f0..b066c75db3 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,30 @@ Deprecated and removed features, and other changes affecting compatibility: binaries and it has been removed from header. This function has been deprecated in favor of clock_settime. +* The settimeofday function can still be used to set a system-wide time + zone when the operating system supports it. This is because the Linux + kernel reused the API, on some architectures, to describe a system-wide + time-zone-like offset between the software clock maintained by the kernel, + and the "RTC" clock that keeps time when the system is shut down. + + However, to reduce the odds of this offset being set by accident, + settimeofday can no longer be used to set the time and the offset + simultaneously. If both of its two arguments are non-null, the call + will fail (setting errno to EINVAL). + + Callers attempting to set this offset should also be prepared for the call + to fail and set errno to ENOSYS; this already happens on the Hurd and on + some Linux architectures. The Linux kernel maintainers are discussing a + more principled replacement for the reused API. After a replacement + becomes available, we will change settimeofday to fail with ENOSYS on all + platforms when its 'tzp' argument is not a null pointer. + + Note that settimeofday itself is obsolescent according to POSIX. + Programs that set the system time should use clock_settime and/or + the adjtime family of functions instead. We may also cease to make + settimeofday available to newly linked binaries after there is a + replacement for Linux's time-zone-like offset API. + Changes to build and runtime requirements: [Add changes to build and runtime requirements here] diff --git a/include/sys/time.h b/include/sys/time.h index 57208afa82..c0e30e70fb 100644 --- a/include/sys/time.h +++ b/include/sys/time.h @@ -24,8 +24,7 @@ extern int __gettimeofday (struct timeval *__tv, struct timezone *__tz); libc_hidden_proto (__gettimeofday) libc_hidden_proto (gettimeofday) -extern int __settimeofday (const struct timeval *__tv, - const struct timezone *__tz) +extern int __settimezone (const struct timezone *__tz) attribute_hidden; extern int __adjtime (const struct timeval *__delta, struct timeval *__olddelta); diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/mach/hurd/clock_settime.c similarity index 64% rename from sysdeps/unix/clock_settime.c rename to sysdeps/mach/hurd/clock_settime.c index 54c917949f..a69fdca46a 100644 --- a/sysdeps/unix/clock_settime.c +++ b/sysdeps/mach/hurd/clock_settime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2019 Free Software Foundation, Inc. +/* Copyright (C) 1991-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 @@ -17,38 +17,32 @@ #include #include -#include +#include +#include #include -/* Set CLOCK to value TP. */ +/* Set the current time of day. + This call is restricted to the super-user. */ int -__clock_settime (clockid_t clock_id, const struct timespec *tp) +__clock_settime (clockid_t clock_id, const struct timespec *ts) { - int retval = -1; + error_t err; + mach_port_t hostpriv; + time_value_t tv; - /* Make sure the time cvalue is OK. */ - if (! valid_nanoseconds (tp->tv_nsec)) - { - __set_errno (EINVAL); - return -1; - } + if (clock_id != CLOCK_REALTIME + || ! valid_nanoseconds (ts->tv_nsec)) + return __hurd_fail (EINVAL); - switch (clock_id) - { - case CLOCK_REALTIME: - { - struct timeval tv; - TIMESPEC_TO_TIMEVAL (&tv, tp); - retval = __settimeofday (&tv, NULL); - } - break; + err = __get_privileged_ports (&hostpriv, NULL); + if (err) + return __hurd_fail (EPERM); - default: - __set_errno (EINVAL); - break; - } + TIMESPEC_TO_TIME_VALUE (&tv, ts); + err = __host_set_time (hostpriv, tv); + __mach_port_deallocate (__mach_task_self (), hostpriv); - return retval; + return __hurd_fail (err); } libc_hidden_def (__clock_settime) 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/alpha/osf_settimeofday.c b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c index 22de7b510c..48eef67429 100644 --- a/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c +++ b/sysdeps/unix/sysv/linux/alpha/osf_settimeofday.c @@ -32,8 +32,18 @@ attribute_compat_text_section __settimeofday_tv32 (const struct timeval32 *tv32, const struct timezone *tz) { - struct timeval tv = valid_timeval_to_timeval64 (*tv32); - return __settimeofday (&tv, tz); + if (__glibc_unlikely (tz != 0)) + { + if (tv32 != 0) + { + __set_errno (EINVAL); + return -1; + } + return __settimezone (tz); + } + + struct timespec ts = valid_timeval32_to_timespec (*tv32); + return __clock_settime (CLOCK_REALTIME, &ts); } compat_symbol (libc, __settimeofday_tv32, settimeofday, GLIBC_2_0); diff --git a/sysdeps/unix/sysv/linux/alpha/settimeofday.c b/sysdeps/unix/sysv/linux/alpha/settimeofday.c new file mode 100644 index 0000000000..36a6901e4e --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/settimeofday.c @@ -0,0 +1,22 @@ +/* settimeofday -- Set the current time of day. Linux/Alpha/tv64 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 + . */ + +/* We can use the generic implementation, but we have to override its + default symbol version. */ +#define VERSION_settimeofday GLIBC_2.1 +#include