OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
The Windows "April Fools 2001" bug
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

The Windows "April Fools 2001" bug


  • To: NTBUGTRAQLISTSERV.NTBUGTRAQ.COM
  • Subject: The Windows "April Fools 2001" bug
  • From: "Richard M. Smith" <rmsPHARLAP.COM>
  • Date: Thu, 7 Jan 1999 10:18:33 +0100
  • Approved-By: Russ.CooperRC.ON.CA
  • Reply-To: "Richard M. Smith" <rmsPHARLAP.COM>
  • Sender: Windows NT BugTraq Mailing List <NTBUGTRAQLISTSERV.NTBUGTRAQ.COM>

January 7, 1999

I have discovered a serious bug in Windows which will cause
many Windows applications to give the incorrect time starting
on April 1, 2001.  Although this new bug is not technically a Y2K
bug, it is similar because programs will fail on a particular
day in the next century.

The bug causes Windows applications to give times which are off by one hour
even though the Windows clock shows the correct time.  The bug will continue
for one week until April 8th of 2001, when applications will again show the
correct time.  The bug occurs under Windows 95, 98, and NT.

The problem is caused by the Visual C++ runtime library being
confused and assuming that daylight saving time doesn't start until
April the 8th.  In fact, daylight saving time starts on April 1 in
the year 2001.  The confusion appears to be caused by the fact that
April 1 falls on a Sunday in the year 2001.  The same bug occurs
in other years where April 1 also falls on a Sunday.  The last time this
happened was in 1990 and after 2001 it will occur again in 2007.  If April 1
falls on any other day of the week, the bug does not occur.

I reported the bug to Microsoft on Jan. 5th and got confirmation of
from them on the evening of Jan. 6th.  At the present time, Microsoft told
me that they don't know when a fix will be available for the bug.

For some applications, users should be able to fix the
problem by downloading a new version of the Visual C++ runtime
library DLL, MSVCRT.DLL.  Since the DLL now ships as part of Windows,
I would assume the fixed DLL will be available of the Windows Update
site.

Unfortunately not all applications can be corrected with a new release of
MSVCRT.DLL.  Any applications which statically links with the Visual C++
runtime will have to be fixed by the application vendor.  Users will
have to download the new releasess of these kinds of applications.

In my testing, I believe that the bug was introduced in version 4.1 of
Visual C++.  It is present in versions 4.2, 5.0, and 6.0 according to
my testing.

At the present time, the bug has been confirmed only in North American
time zones.  Outside North America it is unknown if the same bug
exists or not.  If it does exists, it may occur on different days
and different years.

I have written a small program in C that tests for the problem.
The source code for the test program is attached to the end of this
message.

This "April Fools 2001" bug is present in the localtime() function, but
is probably also in other functions defined in the C language "time.h"
header file.

Here is the output from the test program under Windows 98:

   0x3AC796D0 = Sunday, April 1, 2001 -- 16:00:00 Eastern Standard Time -- DOY=90
   0x3ACF2B70 = Saturday, April 7, 2001 -- 10:00:00 Eastern Standard Time -- DOY=96
   0x3AD06EE0 = Sunday, April 8, 2001 -- 10:00:00 Eastern Daylight Time -- DOY=97

The hours and time zones are incorrect for April 1st and April 7th.  The time
on April 8th is correct.

A bit of background.  In the United State and Canada, daylight
saving time (DST) always starts on the first Sunday in April and ends on
the last Sunday in October.  More information of the DST rules can
be found in the article at http://www.energy.ca.gov/daylightsaving.html.

I have also created a live demo page on the Web that tests for the bug
in Netscape Navigator 4 and Internet Explorer 4 which both apparently
use Visual C++ runtime library.  The URL of this demo page is:

    http://security.pharlap.com/y2k/demo1.htm

I am interested for folks to test for this same bug in other
operating systems and programming tools.  If you do run any tests,
I would appreciate in hearing the results via Email.  I know that
JavaScript has the bug in Netscape and Internet Explorer as well as
Win32 version of Perl.  Excel and Netscape Java Virtual Machine on
the other hand seem immune to the bug.

Thanks,
Richard M. Smith
rmspharlap.com

--------------------------------------------------------------------------------

//
// APRIL1.C -- Simple test program for the "April's Fools 2001" bug
//
// by Richard M. Smith (rmspharlap.com)
// copyright (C) 1999
//

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

#define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (24 * SECS_PER_HOUR)
#define SECS_PER_YEAR (365 * SECS_PER_DAY)

#define START (3 * SECS_PER_DAY)
#define INCR (23 * SECS_PER_HOUR)
#define MAXTIMES ((0x80000000L - START) / INCR)

void print_time(time_t mytime);

char *month_tab[] =
{
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December"
};

char *dow_tab[] =
{
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday"
};

int main()

{

        print_time(0x3AC796D0);  // Sunday, April 1, 2001
        print_time(0x3ACF2B70);  // Saturday, April 7, 2001
        print_time(0x3AD06EE0);  // Sunday, April 8, 2001
        return 0;

}

//
// print_time -- print out a time_t value converted by localtime()
//

void print_time(time_t mytime)

{

    char month[100];
    char dow[100];
    struct tm *tmp;

    tmp = localtime(&mytime);
    if(tmp == NULL)
    {
        printf("0x%08lX = Invalid time\n", mytime);
        return;
    }
    if(tmp->tm_mon >= 0 && tmp->tm_mon <= 11)
        strcpy(month, month_tab[tmp->tm_mon]);
    else
        sprintf(month, "BadMonth=%d", tmp->tm_mon);
    if(tmp->tm_wday >= 0 && tmp->tm_wday <= 6)
        strcpy(dow, dow_tab[tmp->tm_wday]);
    else
        sprintf(month, "BadDOW=%d", tmp->tm_wday);
    printf("0x%08lX = %s, %s %d, %d -- %d:%02d:%02d %s -- DOY=%d\n",
           mytime, dow, month, tmp->tm_mday, tmp->tm_year + 1900,
           tmp->tm_hour, tmp->tm_min, tmp->tm_sec, _tzname[tmp->tm_isdst != 0],
           tmp->tm_yday);
    return;

}