Config.in: introduce BR2_TIME_BITS_64 option for Y2038 compatibility

Y2038 is now almost only 15 years away, and embedded systems built
today are potentially going to still be operational in 15 years, and
even though they are supposed to receive updates by then, we all know
how things go, and potentially some of these embedded systems will not
receive any update.

In 2038, the signed 32-bit representation of time_t used on 32-bit
architectures will overflow, causing all time-related functions to go
back in time in a surprising way.

The Linux kernel has already been modified to support a 64-bit
representation of time_t on 32-bit architectures, but from a C library
perspective, the situation varies:

 - glibc uses this 64-bit time_t representation on 32-bit systems
   since glibc 2.34, but only if -D_TIME_BITS=64 is
   specified. Therefore, this commit adds an option to add this flag
   globally to the build, when glibc is the C library and the
   architecture is not 64-bit.

 - musl uses unconditionally a 64-bit time_t representation on 32-bit
   systems since musl 1.2.0. So there is nothing to do here since
   Buildroot has been using a musl >= 1.2.0, used since Buildroot
   2020.05. No Buildroot option is needed here.

 - uClibc-ng does not support a 64-bit time_t representation on 32-bit
   systems, so systems using uClibc-ng will not be Y2038 compliant, at
   least for now. No Buildroot option is needed here.

It should be noted that being Y2038-compliant will only work if all
application/library code is correct. For example if an
application/library stores a timestamp in an "int" instead of using
the proper time_t type, then the mechanisms described above will not
fix this, and the application/library will continue to be broken in
terms of Y2038 support.

Possible discussions points about this patch:

 - Should we have an option at all, or should we unconditionally pass
   -D_TIME_BITS=64, like we have been doing for _FILE_OFFSET_BITS=64
   for quite some time. The reasoning for having an option is that
   the mechanism is itself opt-in in glibc, and generally relatively
   new, so it seemed logical for now to make it optional as well in
   Buildroot.

 - Should we show something (a Config.in comment?) in the musl and
   uClibc-ng case to let the user know that the code is Y2038
   compliant (musl) or not Y2038 compliant (uClibc-ng). Or should this
   discussion be part of the Buildroot documentation?

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
This commit is contained in:
Thomas Petazzoni 2022-10-12 23:50:08 +02:00
parent 83ffe153fa
commit 3c427c6472
2 changed files with 17 additions and 0 deletions

View File

@ -736,6 +736,20 @@ config BR2_PER_PACKAGE_DIRECTORIES
endmenu
config BR2_TIME_BITS_64
bool "Build Y2038-ready code"
depends on BR2_TOOLCHAIN_USES_GLIBC && !BR2_ARCH_IS_64
help
This option will pass -D_TIME_BITS=64 in the compiler flags
to ensure the glibc C library uses a 64-bit representation
for time_t and other time types, which ensures that
programs/libraries will correctly handle time past year
2038.
This option only has an effect with glibc >= 2.34, as
earlier glibc versions did not have support for 64-bit
time_t.
comment "Security Hardening Options"
config BR2_PIC_PIE_ARCH_SUPPORTS

View File

@ -167,6 +167,9 @@ TARGET_HARDENED += -D_FORTIFY_SOURCE=3
endif
TARGET_CPPFLAGS += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
ifeq ($(BR2_TIME_BITS_64),y)
TARGET_CPPFLAGS += -D_TIME_BITS=64
endif
TARGET_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_ABI) $(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING) $(TARGET_HARDENED)
TARGET_CXXFLAGS = $(TARGET_CFLAGS)
TARGET_FCFLAGS = $(TARGET_ABI) $(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING)