Date: Wed, 24 May 2006 15:13:23 +0300 (EEST) From: Andriy Gapon <avg@topspin.kiev.ua> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/97786: fs/udf: incorrect timestamps Message-ID: <200605241213.k4OCDNWh004369@oddity.topspin.kiev.ua> Resent-Message-ID: <200605241220.k4OCKKFQ044851@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 97786 >Category: kern >Synopsis: fs/udf: incorrect timestamps >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed May 24 12:20:20 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Andriy Gapon >Release: FreeBSD 6.1-RELEASE i386 >Organization: >Environment: System: FreeBSD 6.1-RELEASE i386 >Description: Thanks to Bruce Evans for discovering this bug and sharing his patch. To the best of my knowledge this was not filed as a PR before, so I am doing it now to share the knowledge with community. Badically, existing code doesn't take into account that day- and month- numbering starts with 1, not zero. Month number is not validated. Also, for timestamps before 2000 it can report only three values (Jan 1 1980, Jan 1 1990, Jan 1 2000), becaus of a bug in "fast-forwarding" optimization. >How-To-Repeat: >Fix: --- datetime.patch begins here --- --- sys/fs/udf/udf_vnops.c 23 Jun 2004 21:49:03 -0000 1.37 +++ sys/fs/udf/udf_vnops.c 19 Apr 2005 06:42:17 -0000 @@ -265,7 +268,11 @@ t->tv_nsec = 0; - /* DirectCD seems to like using bogus year values */ + /* + * DirectCD seems to like using bogus year values. + * Distrust time->month especially, since it will be used for an + * array index. + */ year = le16toh(time->year); - if (year < 1970) { + if (year < 1970 || time->month > 12) { t->tv_sec = 0; return; @@ -276,19 +283,12 @@ t->tv_sec += time->minute * 60; t->tv_sec += time->hour * 3600; - t->tv_sec += time->day * 3600 * 24; + t->tv_sec += (time->day - 1) * 3600 * 24; /* Calculate the month */ lpyear = udf_isaleapyear(year); for (i = 1; i < time->month; i++) - t->tv_sec += mon_lens[lpyear][i] * 3600 * 24; + t->tv_sec += mon_lens[lpyear][i - 1] * 3600 * 24; - /* Speed up the calculation */ - if (year > 1979) - t->tv_sec += 315532800; - if (year > 1989) - t->tv_sec += 315619200; - if (year > 1999) - t->tv_sec += 315532800; - for (i = 2000; i < year; i++) { + for (i = 1970; i < year; i++) { daysinyear = udf_isaleapyear(i) + 365 ; t->tv_sec += daysinyear * 3600 * 24; --- datetime.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605241213.k4OCDNWh004369>