|
|
Subscribe / Log in / New account

Year-2038 work in 4.18

By Jonathan Corbet
June 11, 2018
We now have less than 20 years to wait until the time_t value used on 32-bit systems will overflow and create time-related mayhem across the planet. The grand plan for solving this problem was posted over three years ago now; progress since then has seemed slow. But quite a bit of work has happened deep inside the kernel and, in 4.18, some of the first work that will be visible to user space has been merged. The year-2038 problem is not yet solved, but things are moving in that direction.

If 32-bit systems are to be able to handle times after January 2038, they will need to switch to a 64-bit version of the time_t type; the kernel will obviously need to support applications using that new type. Doing so in a way that doesn't break existing applications is going to require some careful work, though. In particular, the kernel must be able to successfully run a system where applications have been rebuilt to use a 64-bit time_t, but ancient binaries stuck on 32-bit time_t still exist; both applications should continue to work (though the old code may fail to handle times correctly).

The first step is to recognize that most architectures already have support for applications running in both 64-bit and 32-bit modes in the form of the compatibility code used to run 32-bit applications on 64-bit systems. At some point, all systems will be 64-bit systems when it comes to time handling, so it makes sense to use the compatibility calls for older applications even on 32-bit systems. To that end, with 4.18, work has been done to allow both 32-bit and 64-bit versions of the time-related system calls to be built on all architectures. The CONFIG_64BIT_TIME configuration symbol controls the building of the 64-bit versions on 32-bit systems, while CONFIG_COMPAT_32BIT_TIME controls the 32-bit versions.

Internally, some work has been done to keep the handling of time formats as simple as possible. The new __kernel_timespec type describes how 64-bit timespec values will be passed between the kernel and user space; it is designed to be the same for both 64-bit applications and those running under 32-bit emulation.

The long-term plan for many system calls with year-2038 issues is to create new versions, under new system-call numbers, that handle times in the __kernel_timespec format. The old versions, which will not handle 2038 correctly, will retain the old system-call numbers, so they will still be there for applications that expect them. Applications that are built for 64-bit time values will use the new versions and function correctly. For the most part, the patches for this phase of the work exist but have not yet found their way into the mainline.

One set of system calls that have changed are those managing System V interprocess communication. These system calls, providing access to semaphores, shared memory, and message queues, are not universally loved, but they do have users and need to continue to work. They also have interfaces using time_t values. For example, the semctl() system call uses the semid_ds structure, defined as:

    struct semid_ds {
	struct ipc_perm sem_perm;  /* Ownership and permissions */
	time_t          sem_otime; /* Last semop time */
	time_t          sem_ctime; /* Last change time */
	unsigned long   sem_nsems; /* No. of semaphores in set */
    };

This structure looks like it would be difficult to extend to 64-bit time values without breaking compatibility, but the reality of the situation is a good illustration of how the view of system calls provided by the C library does not always match the actual interface provided by the kernel. The structure that is actually passed into and out of the kernel is rather different; the C library takes responsibility for converting between the two. The kernel's structure looks like this:

    struct semid64_ds {
	struct ipc64_perm sem_perm;	/* permissions .. see ipc.h */
	__kernel_time_t	sem_otime;	/* last semop time */
	unsigned long	__unused1;
	__kernel_time_t	sem_ctime;	/* last change time */
	unsigned long	__unused2;
	unsigned long	sem_nsems;	/* no. of semaphores in array */
	unsigned long	__unused3;
	unsigned long	__unused4;
};

This is the 32-bit version of the structure with some #ifdef lines taken out; the full definition can be found in include/uapi/asm-generic/sembuf.h. What jumps out here is the padding that exists between the time fields. Somebody, years ago (before the beginning of the Git era) decided that the kernel should use the semid64_ds structure on all systems, and to ensure that enough space existed to pass 64-bit time values at some time in the future.

Many years later, that decision is paying off. In 4.18, the kernel will be able to unconditionally return 64-bit times for sem_otime and sem_ctime, with no compatibility issues to worry about. To that end, the structure (on 32-bit systems) now looks like:

     struct semid64_ds {
	struct ipc64_perm sem_perm;	/* permissions .. see ipc.h */
	unsigned long	sem_otime;	/* last semop time */
	unsigned long	sem_otime_high;
	unsigned long	sem_ctime;	/* last change time */
	unsigned long	sem_ctime_high;
	unsigned long	sem_nsems;	/* no. of semaphores in array */
	unsigned long	__unused3;
	unsigned long	__unused4;
    };

The extra bits in the _high fields will be ignored until the C library is upgraded to use them, but that can happen independently. There are some minor issues to be dealt with (the padding values are in the wrong place on big-endian systems, necessitating a swap operation, for example), but the change is essentially painless.

The one remaining piece, involving a bit more pain, is semtimedop(), which takes a struct timespec parameter. That call will have to be split into old and new versions, as described above — a change that has not found its way into 4.18.

The merging of these changes for 4.18 shows that the work on the year-2038 problem is progressing. There is still quite a bit to do; beyond the new system calls, there are a bunch of ioctl() operations that will need to be found and fixed, for example. But, from the kernel point of view at least, perhaps there is some light visible at the end of the tunnel. A complete solution will also require a lot of work at the C-library, distribution, and application levels, though, so we are likely to be hearing about year-2038 work for a while yet.

Index entries for this article
KernelYear 2038 problem


(Log in to post comments)

Year-2038 work in 4.18

Posted Jun 12, 2018 3:10 UTC (Tue) by marcH (subscriber, #57642) [Link]

> We now have less than 20 years to wait until the time_t value used on 32-bit systems will overflow and create time-related mayhem across the planet.

A bit less for applications which handle dates in the future.

Year-2038 work in 4.18

Posted Jun 12, 2018 6:01 UTC (Tue) by k8to (guest, #15413) [Link]

I'm curious about applications for future data. I dealt with Splunk for may years and while you could theoretically feed in future data, the window for doing so was really about 3 days.

Projections? Business looks maybe a year or so. Maybe other people look further?

Year-2038 work in 4.18

Posted Jun 12, 2018 6:18 UTC (Tue) by gfernandes (subscriber, #119910) [Link]

10-year bonds?

Year-2038 work in 4.18

Posted Jun 12, 2018 6:24 UTC (Tue) by jem (subscriber, #24231) [Link]

Certificate expiration dates are often past 2038, especially for root certificates.

Out of curiosity, I checked the certificates in my Firefox browser. The "Amazon Root CA 1" certificate expires on January 17, 2038, just two days before the 32-bit rollover on January 19, 2038. Coincidence?

Year-2038 work in 4.18

Posted Jun 14, 2018 19:30 UTC (Thu) by flussence (subscriber, #85566) [Link]

I think this will be the biggest fallout of the 2038 problem. Not computer systems per se, but the CA trust chain will collapse within the space of 12 months because they were all greedy and used INT_MAX.

Year-2038 work in 4.18

Posted Jun 14, 2018 13:18 UTC (Thu) by jschrod (subscriber, #1646) [Link]

Life insurances, long-term loans for houses or other industrial buildings, and other financial agreements work with dates past 2038-01-18.

That said, applications for this kind of work typically don't use time_t for such computations.

Well, except if some guys use Excel, then they use some kind of time_t nevertheless; but this doesn't have the Y2038 problem.

Year-2038 work in 4.18

Posted Jun 12, 2018 6:28 UTC (Tue) by anselm (subscriber, #2796) [Link]

Kernel-style time_t values are mostly useful for dealing with system-level stuff such as file access/modification/change times, process ages, and so on.

If you're writing applications that, e.g., handle life insurance calculations, you don't want to do that based on time_t – most programming languages have date/time data types that are way more useful and robust.

Year-2038 work in 4.18

Posted Jun 12, 2018 8:57 UTC (Tue) by eru (subscriber, #2753) [Link]

I wonder what time representation "at" and "cron" use? Of course you probably will not schedule anything with them years ahead, but in principle it is possible. Out of curiosity tried what "at" does given a date in 2040, and it did not complain (on a 64-bit Linux Mint 18.3):

$ at -f at-test.sh 12/12/2040
warning: commands will be executed using /bin/sh
job 1 at Wed Dec 12 11:48:00 2040

But I guess it is infeasible to wait until that to see if it really worked.

Year-2038 work in 4.18

Posted Jun 12, 2018 10:11 UTC (Tue) by brooksmoses (guest, #88422) [Link]

It's not that infeasible to test -- just set your system clock ahead a few decades.

Year-2038 work in 4.18

Posted Jun 12, 2018 16:08 UTC (Tue) by arnd (subscriber, #8866) [Link]

> A bit less for applications which handle dates in the future.

Also quite a bit less for people that run older kernels and/or provide long-term support.

Year-2038 work in 4.18

Posted Jun 14, 2018 6:34 UTC (Thu) by lamby (subscriber, #42621) [Link]

I can't seem to find it now but isn't there a "longtime" project in this area?

Year-2038 work in 4.18

Posted Jun 15, 2018 19:17 UTC (Fri) by fratti (guest, #105722) [Link]

Too bad all those 32-bit ARM devices won't get a single kernel update in those 20 years.


Copyright © 2018, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds