This is the mail archive of the
mailing list for the glibc project.
Re: Second draft of the Y2038 design document
- From: Arnd Bergmann <arnd at arndb dot de>
- To: Joseph Myers <joseph at codesourcery dot com>
- Cc: libc-alpha at sourceware dot org, Albert ARIBAUD <albert dot aribaud at 3adev dot fr>
- Date: Fri, 29 Jan 2016 17:26:48 +0100
- Subject: Re: Second draft of the Y2038 design document
- Authentication-results: sourceware.org; auth=none
- References: <20160128204114 dot 6c7dbbf7 dot albert dot aribaud at 3adev dot fr> <12761061 dot sGnHL6NOhT at wuerfel> <alpine dot DEB dot 2 dot 10 dot 1601291534150 dot 29026 at digraph dot polyomino dot org dot uk>
On Friday 29 January 2016 15:40:13 Joseph Myers wrote:
> On Fri, 29 Jan 2016, Arnd Bergmann wrote:
> > Should the kernel rely on the glibc-specific "_TIME_BITS" for this,
> > or do we define some other macro that the kernel can test for?
> Note that _TIME_BITS would not be tested directly in most glibc headers;
> it would be tested in features.h and used there to define __USE_* macros.
> (This is an observation, not an answer to your question.)
After thinking some more about it myself, I concluded that it should
be something other than _TIME_BITS: If a program sets _TIME_BITS=64
in source code but then gets built against new kernel headers and old
libc headers, we end up with a 32-bit time_t and a kernel expecting
a 64-bit time_t, and that won't work.
This means the kernel has to check for a macro that gets set by
the libc. However, we then run into a problem if the kernel header
is the first (or only) thing that gets included by the user source
code, and the macro won't be defined before it is checked.
I don't see a method that works 100% reliably here to solve those
two problems together, but maybe you or someone else has an idea.
> > __kernel_time_t, ...) and avoids namespace conflicts. In all the above
> > examples, the new structure is identical between 32-bit and 64-bit
> > architectures. [background: this lets us have a common syscall
> > implementation for 64-bit and new 32-bit interfaces, while the
> To reiterate on identical structures: where nanoseconds are involved in
> struct timespec or anything else where POSIX requires "long" to be the
> type, it's a pain for glibc if the kernel treats them as a 64-bit value
> when coming from a 32-bit process, as opposed to a 32-bit value with 32
> bits of padding, because then glibc needs to copy user-provided structures
> and sign-extend the nanoseconds value before passing it to the kernel.
Right, I'm well aware of this problem and I have no good answer here.
For the system calls that pass a timespec into the kernel (clock_settime,
clock_nanosleep, timer_settime, timerfd_settime, pselect6, ppoll,
io_getevents, recvmmsg, mq_timedsend, mq_timedreceive, semtimedop,
utimensat, rt_sigtimedwait and futex to be exact), we need some code
that sanitizes the input by clearing (sign-extending is not strictly
needed here but would not hurt) the upper 32 bits of the tv_nsec
field in the 64-bit structure.
This code can be either in glibc or in the kernel, and it's equally
ugly in both cases. The problem for the kernel is that we end up with
either an additional set of 16 system call entry points, or a runtime
check each time we copy a timespec into the kernel to see whether
we have a 32-bit or 64-bit task in order to correctly reject
My current patch series implements the runtime check method in the
kernel, but I expect to see requests to move the special case into
> (But for 64-bit processes, correct error checking requires that the value
> be treated as 64-bit.) (This doesn't apply to timeval because that uses
> suseconds_t for microseconds. But I'd also suppose that syscalls
> involving timeval would generally be considered deprecated and the 64-bit
> replacements would be using timespec.)
Correct: no system call passing timeval is currently allowed on a 32-bit
task when the kernel is configured with 32-bit time_t disabled.
For struct timex and struct rusage, there is still the open question
about how we want to handle them, as they embed a struct timeval.
At the moment, the replacement structures contain a different structure
with timeval semantics but a separate definition (struct
__kernel_timex_timeval and struct __kernel_rusage_timeval).