NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/51234: syslogd sometimes incorrectly handles iso to bsd time conversion



>Number:         51234
>Category:       bin
>Synopsis:       syslogd sometimes incorrectly handles iso to bsd time conversion
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jun 11 15:15:00 +0000 2016
>Originator:     Onno van der Linden
>Release:        NetBSD 7.99.29
>Organization:
None
>Environment:
System: NetBSD sheep 7.99.29 NetBSD 7.99.29 (SHEEP) #0: Sun May 1 19:11:17 MEST 2016 onno@sheep:/usr/src/sys/arch/i386/compile/SHEEP i386
Architecture: i386
Machine: i386
>Description:
Everytime I boot my machine /var/log/messages shows the right timestamp
for the boot messages but when ntpd comes along it has a timestamp an
hour into the future:

Jun 11 15:37:31 sheep /netbsd: wsdisplay0: screen 7 added (80x25, vt100 emulation)
Jun 11 14:37:38 sheep dhcpcd[195]: wm0: no IPv6 Routers available
Jun 11 15:37:38 sheep savecore: no core dump
Jun 11 16:37:39 sheep ntpd[476]: ntpd 4.2.8p7-o Sun May  1 13:19:23 EDT 2016 (import): Starting

Notice that dhcpcd also has a wrong timestamp, but an hour in the past. I'll
have to investigate that one further.

>How-To-Repeat:
Boot my machine.
>Fix:
It looks like syslogd needs 2 fixes:
1) the copying of the timestamp data from from_buf to tsbuf is wrong.
   Some data in from_buf can be skipped but variabele i is still being
   used as an index into tsbuf causing random data to appear there which
   may affect the parsing of the data in tsbuf by strptime() later on.
   Use an additional variable as an index in tsbuf which gets initialized
   before the possible skipping of data in from_buf takes place.
2) The initialization of parsed.tm_isdst to -1 is meant for mktime() to
   define (the man page says "divine") if DST is in effect. The call to
   strptime() sets tm_isdst to 0 or 1 causing the check in mktime() for dst
   to be skipped followed by the creation of a timestamp an hour into the
   future
--- /usr/src/usr.sbin/syslogd/syslogd.c.orig	2015-09-07 20:02:50.000000000 +0200
+++ /usr/src/usr.sbin/syslogd/syslogd.c	2016-06-11 16:00:36.585881532 +0200
@@ -1745,27 +1745,28 @@
 		struct tm parsed;
 		time_t timeval;
 		char tsbuf[MAX_TIMESTAMPLEN];
-		int i = 0;
+		int i = 0, j;
 
 		DPRINTF(D_CALL, "check_timestamp(): convert ISO->BSD\n");
 		for(i = 0; i < MAX_TIMESTAMPLEN && from_buf[i] != '\0'
 		    && from_buf[i] != '.' && from_buf[i] != ' '; i++)
 			tsbuf[i] = from_buf[i]; /* copy date & time */
+		j = i;
 		for(; i < MAX_TIMESTAMPLEN && from_buf[i] != '\0'
 		    && from_buf[i] != '+' && from_buf[i] != '-'
 		    && from_buf[i] != 'Z' && from_buf[i] != ' '; i++)
 			;			   /* skip fraction digits */
 		for(; i < MAX_TIMESTAMPLEN && from_buf[i] != '\0'
-		    && from_buf[i] != ':' && from_buf[i] != ' ' ; i++)
-			tsbuf[i] = from_buf[i]; /* copy TZ */
+		    && from_buf[i] != ':' && from_buf[i] != ' ' ; i++, j++)
+			tsbuf[j] = from_buf[i]; /* copy TZ */
 		if (from_buf[i] == ':') i++;	/* skip colon */
 		for(; i < MAX_TIMESTAMPLEN && from_buf[i] != '\0'
-		    && from_buf[i] != ' ' ; i++)
-			tsbuf[i] = from_buf[i]; /* copy TZ */
+		    && from_buf[i] != ' ' ; i++, j++)
+			tsbuf[j] = from_buf[i]; /* copy TZ */
 
 		(void)memset(&parsed, 0, sizeof(parsed));
-		parsed.tm_isdst = -1;
 		(void)strptime(tsbuf, "%FT%T%z", &parsed);
+		parsed.tm_isdst = -1;
 		timeval = mktime(&parsed);
 
 		*to_buf = make_timestamp(&timeval, false, BSD_TIMESTAMPLEN);



Home | Main Index | Thread Index | Old Index