Bug 494576 - time_t functions fail after 2038 on 64bit
Summary: time_t functions fail after 2038 on 64bit
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: glibc
Version: 5.2
Hardware: x86_64
OS: Linux
low
medium
Target Milestone: rc
: ---
Assignee: Jakub Jelinek
QA Contact: BaseOS QE
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2009-04-07 14:13 UTC by Martin Poole
Modified: 2018-10-20 00:06 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2009-04-07 16:52:28 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
C test program (514 bytes, text/plain)
2009-04-07 14:13 UTC, Martin Poole
no flags Details

Description Martin Poole 2009-04-07 14:13:16 UTC
Created attachment 338510 [details]
C test program

Description of problem:

time_t/struct tm based functions fail on dates after 0x7fffffff rollover on 64bit architectures.

Version-Release number of selected component (if applicable):

glibc-2.5-34

How reproducible:

Always

Steps to Reproduce:
1. compile/run attached program
2.
3.
  
Actual results:

time_t is 8 bytes
0x7f100eff  is 2037-07-21 04-14-07 +0100
0x7fffffff  is 2038-01-19 03-14-07 +0000
0x80eff0ff  is 1902-06-13 20-45-51 +0000
0x81dfe1ff  is 1902-12-12 20-45-51 +0000
0x82cfd2ff  is 1903-06-12 20-45-51 +0000
0x83bfc3ff  is 1903-12-11 20-45-51 +0000
0x84afb4ff  is 1904-06-10 20-45-51 +0000

Expected results:

dates in 2038,2039 etc complete with requisite DST

Additional info:

It appears glibc in RHEL5 has been updated to cope with the extended tzdata files, but there appears to be no support for this data in either the time functions nor in the utilities (zdump,zic).

Comment 1 Jakub Jelinek 2009-04-07 14:20:06 UTC
That's the expected result.
(time_t)(0x7fffffff + (t * 182 *86400))
for say t = 1 is (time_t) -2131758849, which really is 1902-ish time.
Didn't you mean
(time_t)0x7fffffff + (t * 182 * 86400)
instead?

Comment 2 Martin Poole 2009-04-07 14:21:45 UTC
No, the calculation is correct, as shown in the test output.

Comment 3 Martin Poole 2009-04-07 14:24:53 UTC
Another test to indicate the lack of handling...

  zdump -v Europe/London

This terminates with

Europe/London  Sun Oct 25 00:59:59 2037 UTC = Sun Oct 25 01:59:59 2037 BST isdst=1 gmtoff=3600
Europe/London  Sun Oct 25 01:00:00 2037 UTC = Sun Oct 25 01:00:00 2037 GMT isdst=0 gmtoff=0
Europe/London  9223372036854689407 = NULL
Europe/London  9223372036854775807 = NULL


Whereas on F10/F11 using the same zoneinfo file this continues to the year 2499

Comment 4 Jakub Jelinek 2009-04-07 14:30:47 UTC
The calculation of course isn't correct, but you also have a bug in the fprintf line.  %lx format, but you cast when to (int).  If you fix that up, cast to (long), then you'll see the calculation is wrong, the unfixed testcase then prints:
time_t is 8 bytes
0x7f100eff  is 2037-07-21 05-14-07 +0200
0x7fffffff  is 2038-01-19 04-14-07 +0100
0xffffffff80eff0ff  is 1902-06-13 21-45-51 +0100
0xffffffff81dfe1ff  is 1902-12-12 21-45-51 +0100
0xffffffff82cfd2ff  is 1903-06-12 21-45-51 +0100
0xffffffff83bfc3ff  is 1903-12-11 21-45-51 +0100
0xffffffff84afb4ff  is 1904-06-10 21-45-51 +0100
while fixed one:
time_t is 8 bytes
0x7f100eff  is 2037-07-21 05-14-07 +0200
0x7fffffff  is 2038-01-19 04-14-07 +0100
0x80eff0ff  is 2038-07-20 05-14-07 +0200
0x81dfe1ff  is 2039-01-18 04-14-07 +0100
0x82cfd2ff  is 2039-07-19 05-14-07 +0200
0x83bfc3ff  is 2040-01-17 04-14-07 +0100
0x84afb4ff  is 2040-07-17 05-14-07 +0200

Comment 5 Martin Poole 2009-04-07 14:48:37 UTC
My bad. Too long away form the coal face.

But the output is still incorrect on RHEL5.3 x86_64

# rpm -q glibc tzdata
glibc-2.5-34
glibc-2.5-34
tzdata-2008i-1.el5



time_t is 8 bytes
0x7f100eff  is 2037-07-21 04-14-07 +0100
0x7fffffff  is 2038-01-19 03-14-07 +0000
0x80eff0ff  is 2038-07-20 03-14-07 +0000
0x81dfe1ff  is 2039-01-18 03-14-07 +0000
0x82cfd2ff  is 2039-07-19 03-14-07 +0000
0x83bfc3ff  is 2040-01-17 03-14-07 +0000
0x84afb4ff  is 2040-07-17 03-14-07 +0000


And the previously noted termination of zdump at 2037

Comment 6 Jakub Jelinek 2009-04-07 16:37:55 UTC
That's because zic only generates the transitions from 1900 to 2037 if there is a POSIX tz string in the file.  Recent glibcs (2.7 and later I think) have code to parse the embedded POSIX tz strings in the files and use it after the last transition (that's why e.g. F10 zdump shows you dates up to 2500), but RHEL5 glibc doesn't and it might be too risky to backport it.  RHEL5 isn't going to be supported anywhere near 2037, worse case we could just adjust zic to generate a few years beyond 2037 by default.

Comment 7 Jakub Jelinek 2009-04-07 16:41:16 UTC
Note that apps that rely on what kind of DST saving rules will be used 30 years from now are broken anyway, in some countries it is quite certain they will be wrong even next year or the year after.


Note You need to log in before you can comment on or make changes to this bug.