Package: logrotate Version: 3.8.5-1 Severity: important Tags: patch l10n upstream
Hi there, we found a daylight saving time (DST) bug in logrotate. We want that our logfiles are rotated away once a year on January first, but only if they have grown larger than 1 MB. Due to the bug in logrotate they get rotated twice a year. First time on January first and a second time when they grow larger than 1 MB. This comes from a wrong conversion of the times stored in the status file. A example of the problem is: sh> export TZ="MEZ-1MSZ,M3.5.0,M10.5.0" sh> echo $TZ MEZ-1MSZ,M3.5.0,M10.5.0 sh> date Tue Jul 30 10:46:03 MSZ 2013 sh> cat /etc/logrotate.conf ... /tmp/logfile { yearly minsize 1M } ... sh> ls -lh /tmp/logfile -rw-rw-r-- 1 root root 39M Jul 30 10:40 /tmp/logfile sh> cat /var/lib/logrotate/status logrotate state -- version 2 "/tmp/logfile" 2013-1-1-0:0:0 sh> logrotate -d /etc/logrotate.conf rotating pattern: "/tmp/logfile" yearly (100 rotations) olddir is /var/log/alt, empty log files are not rotated, only log files >= 1048576 bytes are rotated, old logs are removed considering log /tmp/logfile log needs rotating rotating log /tmp/logfile, log->rotateCount is 100 copying /tmp/logfile to /tmp/old/logfile-2013-07-29 truncating /tmp/logfile At logrotate.c:945: state->lastRotated = now; the "lastRotated" is initialized with the value of "now", which makes no sense, since whatever date is found in the status file, it has never anything to do with the actual date. However, due to this initialisation, in our testcase the the field "state->lastRotated.tm_isdst" is set to 1, because DST is active at the time "now". At logrotate.c:2107: st->lastRotated.tm_year = year; logrotate.c:2108: st->lastRotated.tm_mon = month; logrotate.c:2109: st->lastRotated.tm_mday = day; logrotate.c:2110: st->lastRotated.tm_hour = hour; logrotate.c:2111: st->lastRotated.tm_min = minute; logrotate.c:2112: st->lastRotated.tm_sec = second; logrotate.c:2113: logrotate.c:2114: /* fill in the rest of the st->lastRotated fields */ logrotate.c:2115: lr_time = mktime(&st->lastRotated); logrotate.c:2116: st->lastRotated = *localtime(&lr_time); only the fields "tm_year", "tm_month", "tm_mday", "tm_hour", "tm_min" and "tm_sec" are changed but not tm_isdst, so it is still set when the time conversions in line 2115 and 2116 are done. The documentation for mkdoc says, that if tm_isdst is 1 then the time conversion is done with enabled DST which is wrong in our case for the time 2013-01-01T00:00:00. For that reason we find in "st->lastRotated" after the conversion the time 2012-12-31T23:00:00 which lies in the year 2012 and therefore logrotate thinks the logfile needs rotation. Our solution for the problem (pobably not the best) is to initialize the structur correctly by setting the "tm_isdst" field to -1. The documentation of mkdoc states, that this uses the DST which has been or will be in effect at the date converted, which is precisely what we want. Patch: --- a/logrotate.c +++ b/logrotate.c @@ -2104,12 +2104,14 @@ static int readState(char *stateFilename) return 1; } + memset (&st->lastRotated, 0, sizeof st->lastRotated); st->lastRotated.tm_year = year; st->lastRotated.tm_mon = month; st->lastRotated.tm_mday = day; st->lastRotated.tm_hour = hour; st->lastRotated.tm_min = minute; st->lastRotated.tm_sec = second; + st->lastRotated.tm_isdst = -1; /* fill in the rest of the st->lastRotated fields */ lr_time = mktime(&st->lastRotated); Probably one would also have a look at all the other uses of mkdoc. There might be similar problems. Best regards Rüdiger -- System Information: Debian Release: jessie/sid APT prefers testing APT policy: (550, 'testing'), (500, 'stable'), (210, 'unstable'), (1, 'experimental') Architecture: i386 (x86_64) Kernel: Linux 3.11.0-rc3-64+ (SMP w/16 CPU cores; PREEMPT) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Shell: /bin/sh linked to /bin/dash Versions of packages logrotate depends on: ii base-passwd 3.5.26 ii cron [cron-daemon] 3.0pl1-124 ii libacl1 2.2.52-1 ii libc6 2.17-7 ii libpopt0 1.16-7 ii libselinux1 2.1.13-2 Versions of packages logrotate recommends: ii heirloom-mailx [mailx] 12.5-2 logrotate suggests no packages. -- Configuration Files: /etc/logrotate.conf changed [not included] -- no debconf information -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org