Re: [PATCH 00/25] Change time_t and clock_t to 64 bit

Joseph S. Myers
2014-05-18T13:46:30Z

On Sat, 17 May 2014, H. Peter Anvin wrote:

> > Adding snseconds_t to POSIX seems pointless when there is no need for this
> > field to store values that can't fit in "long". Even if it were added,
> > good practice would say that implementations should keep using "long"
> > whenever possible for compatibility with existing applications (just like
> > the ISO C recommendation "The types used for size_t and ptrdiff_t should
> > not have an integer conversion rank greater than that of signed long int
> > unless the implementation supports objects large enough to make this
> > necessary.").
>
> That is a very different thing, though.

It's advising against breaking compatibility with existing applications
(in that case, C90 applications that assume sizes can be cast to unsigned
long for printing, etc.) unless necessary.

Rich Felker suggests
<https://sourceware.org/bugzilla/show_bug.cgi?id=16438> there are similar
security risks from various types in the x32 ABI being wider than size_t.
That seems entirely plausible, if unconfirmed; I don't think there's been
much effort to look for such issues where applications expect types to be
no wider than size_t when there's no use to them being wider than size_t.
Most of those choices are valid but may be risky to existing software much
as IL32LLP64 can be risky to existing software.

> > If you were designing from scratch, no doubt a typedef such as snseconds_t
> > would be there, but with real-world APIs that have accumulated over time,
> > deviating from "long" now is a bad idea.
>
> Given that you already have a long long member of the same structure, it
> seems unlikely that adding another long long to this is a problem.
>
> Anyway, this was discussed back in 2011:
>
> https://lkml.org/lkml/2011/8/31/244

Just because one buggy port (I consider this quite clearly a bug at the
glibc level, whatever the kernel does, agreeing with Rich Felker in
<https://sourceware.org/bugzilla/show_bug.cgi?id=16437>) managed to get
into glibc does not mean any more should be added. glibc's function is to
provide POSIX (and other) interfaces on top of the underlying kernel,
which includes fixing any mismatch between the kernel and POSIX interfaces
(such as converting from userspace POSIX struct timespec to the form in
which times are passed to the kernel, by copying and zeroing padding, if
necessary). That's just like implementing POSIX threads on top of clone -
or, if future POSIX disallows newlines in filenames (something that's been
discussed for some time but doesn't seem to have seen much action lately)
but the Linux kernel doesn't follow, making such checks on filenames
before passing them to the kernel. Of course, one would hope that the
underlying kernel interfaces are designed to make it straightforward to
implement POSIX on top of them (as well as other things not envisaged by
POSIX).

The userspace ABI for struct timespec with 64-bit time_t and 32-bit long
should use long tv_nsec in any future ports, with appropriate conversion
code in glibc if the kernel interface is different (for ports that started
out with 32-bit time_t, conversion code will be needed anyway to convert
to the 32-bit structure if the new syscalls are unavailable at runtime and
so the old syscalls need to be used, but if the kernel's structure with
64-bit time_t is different from that in userspace then both old and new
kernels need conversion code). Given Rich Felker's bug reports, it seems
reasonable to suppose that musl will wish to do this as well as glibc.

--
Joseph S. Myers
joseph@codesourcery.com