Of chroot, time zone and glibc

A N-DJBDNS user reported an issue saying, “Timestamps logged by the DNS servers are off by one hour. Doesn’t N-DJBDNS account for Daylight Savings Time(DST)? Our time changed this week.”

I was puzzled. Because N-DJBDNS servers use system time zone by initialising the TZ environment variable with it. System time zone is identified by a file ‘/etc/localtime’. Often it is a symbolic link pointing to one of the binary data file under ‘/usr/share/zoneinfo/’. Standard <time.h> functions read from this file to perform their operation. Since N-DJBDNS servers are confined to the chroot(2) jail, they can not access ‘/etc/localtime’ and thus have to rely on the
POSIX TZ environment variable for the time zone definition.
See:
        vsftpd: vsf_sysutil_tzset(void) -> ../vsftpd-3.0.2/sysutil.c
        postfix: -> http://www.postfix.org/postconf.5.html (search for “TZ”)

How does one set this TZ variable? The closest I could get was the tzset(3) standard API. Going by its name, one would expect it to set the time zone appropriately, so that applications continue to see correct times. But far from it, the API actually reads TZ variable if it is set or reads ‘/etc/localtime’ when TZ is not set and initialises three public variables:

        extern char *tzname[2];
        extern long timezone;
        extern int daylight;

Of these, ‘tzname’ array stores standard & dst time zone names(ex: EST/EDT), ‘timezone’ stores the standard time offset from UTC(ex: +5:30/-12:00) and ‘daylight’ acts as a boolean variable indicating whether current time zone follows DST rules during any time of the year or not at all. tzset(3) manual says ‘daylight’ has been obsolete for many years. Thus is not useful. A saving grace for the tzset(3) API is that its manual is quite elaborate about 3 formats of the TZ variable.

N-DJBDNS was using the standard time zone name from ‘tzname[2]’ array and standard time offset from ‘timezone’ variable to define the TZ environment variable in its “std offset” format as IST+5:30 OR NZST-12:00 etc. This is where the bug lies, TZ definition does not account for DST time changes.

But there is no standard method to appropriately define the TZ variable so that it accounts for Daylight Savings Time, as and when it is applicable. I discussed this issue with the upstream glibc developers. They also agreed that it’ll help to have an API to query system time zone definition. As per the discussion, three bugs have been filed against glibc, including an RFE for a new time zone API.

        BZ#1077902 -> [RFE] A new API to query time zone data from the tzdata files.
        BZ#1077377 -> tzset(3) incorrectly sets the ‘int daylight’ variable.
        BZ#1076794 -> tzset(3) incorrectly sets tzname[1] DST time zone name.

A basic patch too has been submitted for the new time zone API. If you are interested in contributing to glibc, please join the discussion at #glibc on irc.freenode.net and libc-help mailing list. These bugs are classic low hanging fruits for someone to start with. 🙂

Btw, the N-DJBDNS issue is fixed here -> d77a7d6dd1a2.

Advertisements

One thought on “Of chroot, time zone and glibc

  1. You might be interested in a discussion at stackoverflow regarding the int daylight variable. In the man page it says it’s =1 if daylight savings time should be followed at some time in the year, but it appears the implementation sets daylight=1 if there has been daylight savings time enabled at any time in history of that time-zone. Which is true? I’m not 100% sure, but I do know the documentation is ambiguous and contradictory depending on where you look.

    The guys on stackoverflow seem to think that daylight=1 only means that you need to observe the zoneinfo rules (thus DST was enabled at some time in history), and NOT that daylight savings is going to happen some time in the current year. One of the bugs in your post is relating to this daylight variable, and if the stackoverflow guys are correct, then this bug isn’t a bug at all, but is intended that way by design. So which is it? It’s so hard to get a definitive answer to this. I hope you can shed some light on it.

    http://stackoverflow.com/questions/33992832/tzset-and-daylight-global-variable-interpretation-in-time-h

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s