Hi Arnd,
On Wed, 29 Jun 2016 16:02:13 +0200, Arnd Bergmann arnd@arndb.de wrote :
On Wednesday, June 29, 2016 1:16:11 PM CEST Albert ARIBAUD wrote:
On Wed, 22 Jun 2016 13:55:16 +0200, Arnd Bergmann arnd@arndb.de wrote :
On your note "The implementation needs further thinking about, as application code defining _TIME_BITS=64 and gets built against new kernel headers and old GLIBC headers, then GLIBC will use 32-bit time_t and kernel will expect 64-bit time_t, and there is no way to ensure detection of this case.", I think that is covered by having the kernel headers check __USE_TIME_BITS64 instead of _TIME_BITS=64, as I described above.
What about application source code which includes kernel headers before including any GLIBC header? The kernel header will see __TIME_BITS=64 but it won't see _USE_TIME_BITS64, and will make the wrong decision. Don't we consider this a possible scenario?
Good point, I think you are right that this is a problem. In particular, the normal rule for kernel headers is that they should explictly not include any libc headers or rely on them to be included first. We have some exceptions from those rules for historic reasons.
Do you have any other ideas for how to solve it? We probably only need a handful of those, so we could look at them case-by-case to see what kind of exception we can make.
I don't think there is a perfect, or even good enough, compile-time solution where header could be included in any order while keeping kernel headers from referencing GLIBC macros.
But we can at least detect and explicitly flag bad kernel/glibc/app time size combinations at runtime:
- make Y2038-safe kernel provide a new syscall which tells at run time what features the kernel supports, e.g. does it support 64-bit time, 32-bit time, both? [the need could be more generic than just time support, so I tought such a syscall already existed, but I have not found any in the current syscalls list -- I might have missed it though]
- make Y2038-safe GLIBC use the syscall existence and returned value(s) to determine at runtime whether the running kernel, running GLIBC and running application all agree on 32-bit or 64-bit time.
- make Y2038-safe GLIBC unconditionally define a symbol to announce itself as such -- regardless from whether or not it is built for 64-bit time.
A Y2038-safe GLIBC would thus detect when it runs on a non-Y2038-safe kernel (syscall absent or returning a value which amounts to 'no 64-bit time support built in kernel') and could bail out with an explicit message.
A Y2038-safe GLIBC on a kernel which supports the syscall (or syscall extension) could compare the macros defined by the application code at compile time with the actually supported kernel features and bail out explicitly on mismatches.
Plus, *if it decides to, an application aspiring to be Y2038-safe would be able to verify at build timethat the GLIBC it is compiling against is indeed Y2038-safe, thus allowing detection of the scenario above with new kernel headers and old GLIBC header. Of course, if the application code does not check the macro, this will be missed -- one can bring the horse to the river, etc. That will be a matter of good practice.
Does this make any sense?
Cordialement, Albert ARIBAUD 3ADEV