How to prevent the year 2038 bug

Revision as of 14:00, 22 September 2022 by Registered User (Created page with "=Introduction= The [https://en.wikipedia.org/wiki/Year_2038_problem Year 2038 problem] is a time formatting bug in computer systems with representing times after 03:14:07 UTC...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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 bug, 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[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.

No categories assignedEdit