laitimes

glibc does not properly address the Y2038 issue by default

Due to Y2038 issues, linux kernels switched to 64-bit time_t years ago, and the release Alpine 3.13 also jumped to 64-bit time_t. Recently, however, Ariadne Conill, head of Alpine's security team, posted that GNU libc 2.34 has flaws in supporting 64-bit time_t, which may create obstacles in the transition process.

glibc does not properly address the Y2038 issue by default

Ariadne Conill, head of Alpine's security team, image from Twitter

If you pay close attention to developments and trends in the Linux space, you are sure to know about the Year 2038 bug. This problem exists because on January 19, 2038, the latest time, expressed in Unix's signed 32-bit integer time format, is 03:14:07 UTC.

The latest time, expressed in Unix's signed 32-bit integer time format, is January 19, 2038, 03:14:07 UTC, which is 2147483647 seconds after January 1, 1970. After that time, due to integer overflow, the time value is stored as a negative number and the date is read as December 13, 1901 instead of January 19, 2038.

The Alpine operating system is a lightweight Linux distribution for security. Unlike the usual Linux distribution, Alpine uses musl libc and busybox to reduce the size of the system and runtime resource consumption, but it is much more functional than busybox, so it is more and more favored by the open source community.

In the blog post, Conill indicates that in the musl C library used by Alpine and many other UNIX C library implementations, time_t always 64-bit in new code and provides compatibility stubs for code that requires old 32-bit functions. When the code is rebuilt over time, it will automatically become Y2038 compliant code without any effort.

Microsoft takes another step forward in msvcrt: you get 64-bit time_t by default, but if you define _USE_32BIT_TIME_T macros at compile time, you can still access the old 32-bit functions. It's important to note that both of the methods described above introduce zero friction to get the right stuff.

The GNU project's approach to transitioning to the new ABI is the opposite: you must explicitly request the new feature, or you will never get it. This approach leaves the possibility of changing the default values in the future, but so far, they have never done so.

This can be seen from the Large File Support Extension, which requires processing files larger than 2 GiB and you must always build your code with -D_FILE_OFFSET_BITS=64. Similarly, if you are on a 32-bit system and you are not building your application with -D_TIME_BITS=64, it will not be built using a Y2038-compliant ABI.

This is the worst way. Consider libraries: what if one dependency is built with -D_TIME_BITS=64 and the other dependency doesn't, and they need to swap structures with each other timespec or something similar? Well, in this case, your program will most likely crash or behave strangely because you are not consistently using the same structure timespec in the compiled program.

Fortunately, if your goal is a 32-bit system and you want to work with files larger than 2 GiB, or are confident that your code will continue to work in 2038, there are some Linux distributions built on top of Musl, such as Alpine, which will save you from having to deal with the peculiarities of GNU libc

Read on