1. Introduction[edit source]
The Year 2038 problem is a time formatting bug in computer systems with representing times after 03:14:07 UTC on 19 January 2038. To summarize, this bug will happen on Unix-like system (so on Linux) because on 32 bits platform the time is coded on 32 bits and at 03:14:07 UTC on 19 January 2038 it will loop and then be understood as 20:45:52 UTC on 13 December 1901.
2. Behavior[edit source]
On OpenSTLinux, in the event of that problem, a watchdog will be fired.
Tue Jan 19 03:14:07 UTC 2038 [ 164.856181] systemd-journald[283]: Assertion 'clock_gettime(map_clock_id(clo. Thu Jan 1 00:00:01 UTC 1970 [ 165.428314] watchdog: watchdog0: watchdog did not stop! Thu Jan 1 00:00:01 UTC 1970 Thu Jan 1 00:00:01 UTC 1970 Thu Jan 1 00:00:01 UTC 1970 [ 172.837733] systemd-coredump[1036]: Process 283 (systemd-journal) of user 0 . [ 172.844733] systemd-coredump[1036]: Coredump diverted to /var/lib/systemd/coz Thu Jan 1 00:00:01 UTC 1970 [ 183.125664] systemd-coredump[1037]: Failed to log coredump: Connection refusd Thu Jan 1 00:00:01 UTC 1970 Thu Jan 1 00:00:01 UTC 1970 INFO: CPU 0 IT Watchdog 2 INFO: CPU : 0
3. BSP side[edit source]
3.1. OP-TEE OS[edit source]
OP-TEE OS already supports time on 64 bits instead of 32bits.
3.2. TF-A[edit source]
TF-A already supports time on 64 bits instead of 32bits.
3.3. U-Boot[edit source]
U-Boot already supports time on 64 bits instead of 32bits.
3.4. Linux kernel[edit source]
The Linux kernel already supports time on 64 bits instead of 32 bits.
4. User space[edit source]
There is no universal solution to fix that issue.
4.1. Gnu LibC[edit source]
Since the version 2.34, the support of the time on 64 bits is already implemented. But by default, to keep compatibility, all application build with the Gnu LibC use a time on 32 bits. So, to use a time format on 64 bits, two defines must be set on build line for application: _TIME_BITS=64 and _FILE_OFFSET_BITS=64.
4.2. User space applications[edit source]
As stated above, to build applications for using a time coded on 64 bits, two defines must be specified.
4.2.1. get_date.c (an example)[edit source]
Let's try with following example:
// Code based on example found here: https://www.blaess.fr/christophe/2038/ #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { time_t now; struct tm *tm_now; char line[1024]; printf("sizeof(int): %d\n",sizeof(int)); printf("sizeof(long long int): %d\n",sizeof(long long int)); printf("sizeof(time_t): %d\n",sizeof(time_t)); time(&now); tm_now = gmtime(&now); strftime(line, 1023, "%x %X", tm_now); printf("%s\n", line); return 0; }
- Cross-compile it without the defines
$CC -Wall get_date.c -o get_date_32b
Execute it on the platform
./get_date_32b sizeof(int): 4 sizeof(long long int): 8 sizeof(time_t): 4 01/19/38 03:14:07 ./get_date_32b sizeof(int): 4 sizeof(long long int): 8 sizeof(time_t): 4 01/01/70 00:00:00 ./get_date_32b sizeof(int): 4 sizeof(long long int): 8 sizeof(time_t): 4 01/01/70 00:00:00
- Cross-compile it with the defines
$CC -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 -Wall get_date.c -o get_date_64b
Execute it on the platform
./get_date_64b sizeof(int): 4 sizeof(long long int): 8 sizeof(time_t): 8 01/19/38 03:14:07 ./get_date_64b sizeof(int): 4 sizeof(long long int): 8 sizeof(time_t): 8 01/19/38 03:14:08 ./get_date_64b sizeof(int): 4 sizeof(long long int): 8 sizeof(time_t): 8 01/19/38 03:14:09
The first executable cannot read correctly the time, whereas the second can.
4.2.2. Other applications[edit source]
When building application with these two defines, behavior can be different:
- successful if the application does not deal with time or already ported to support time format on 64 bits
- unsuccessful if the work is not already done.
4.2.2.1. ioclt alias[edit source]
The glibc added a time64 alias for ioctl but some application can still look for ioctl during the link. A quick patch could be something like that
libtswrap_la_LDFLAGS = \ - -export-symbols-regex ^ioctl \ + -export-symbols-regex ^__ioctl_time64 \