Subject: y2k/11545: gmtime does not work after 2038
To: None <gnats-bugs@gnats.netbsd.org>
From: Tero Kivinen <kivinen@ssh.fi>
List: netbsd-bugs
Date: 11/21/2000 18:04:17
>Number:         11545
>Category:       y2k
>Synopsis:       gmtime returns year 1901 if trying to use time > 0x80000000
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    y2k-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Nov 21 18:04:01 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Tero Kivinen
>Release:        NetBSD 1.5_ALPHA 2
>Organization:
SSH Communications Security
>Environment:
System: NetBSD kaakeli.ssh.fi 1.5_ALPHA2 NetBSD 1.5_ALPHA2 (KAAKELI) #39: Fri Oct 13 03:12:52 EEST 2000 kivinen@kaakeli.ssh.fi:/usr/src/sys/arch/i386/compile/KAAKELI i386


>Description:

	If gmtime is given a time_t that is negative (i.e unix time
	after 2038), then it returns year as 1901. This breaks for
	example the perl HTTP::Cookie library, as for example the
	www.google.com sets cookie like this:

	Set-Cookie: PREF=ID=15d4258c1f04851e:TM=973465320:LM=973465320;
	domain=.google.com; path=/; expires=Sun, 17-Jan-2038 19:14:07 GMT

	And when HTTP::Cookie tries to convert that 17-Jan-2038
	19:14:07 to unix time it will fail and print out error
	message.

	Also most of the commercial y2k statements define programs to
	be y2k safe only if they work up to year 2100. This means that
	netbsd programs are NOT y2k safe in that sense, if they use
	any gmtime etc functions. 

>How-To-Repeat:

	#include <stdio.h>
	#include <stdlib.h>
	#include <time.h>

	int main(int argc, char **argv)
	{
	  struct tm *t;
	  time_t c;

	  c = 0x80000000;
	  t = gmtime(&c);
	  printf("%d-%02d-%02d %02d:%02d:%02d\n",
		 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
		 t->tm_hour, t->tm_min, t->tm_sec);
	  return 0;
	}

>Fix:

	Proper fix would be to define new time_t type (ltime_t?) that
	would be 64-bits and start using that. Another easier fix
	would be change the time_t to be unsigned instead of signed,
	but this might break some programs. Easiest fix would be to
	modify the lib/libc/time/localtime.c:timesub() so that it will
	interpret the time_t as unsigned internally and return years
	bigger than 2038 instead of years smaller than 1970 if
	negative time_t values are used.
>Release-Note:
>Audit-Trail:
>Unformatted: