glib uses wrong timezone transition with zoneinfo 2014c
Submitted by Marien Zwart
Link to original bug (#730332)
Description
Noticed this because the clock in gnome-panel was 5 minutes off. This seems to be caused by a change in tzcode 2014c, which violates an assumption in gtimezone.c.
The change is that the zoneinfo files now contain a transition at the minimum time value (G_MININT64). gdatetime.c internally uses intervals, with interval 0 being before the first transition. The end time of interval 0 is calculated as the time of the first transition - 1, which now wraps.
I confirmed g_time_zone_find_interval returns 0 when called on the Australia/Sydney timezone with G_TIME_TYPE_UNIVERSAL and the current time. That gets me the timezone "LMT" and an offset of 36292 (hence the clock being a few minutes off). gdb confirmed the first transition is at -9223372036854775808, and a script I threw together to dump the zoneinfo file confirmed that transition is really in there.
The actual overflow occurs in interval_end (on "return (TRANSITION(interval)).time - 1"), but that may not be the only spot affected.
Note tzdata 2014c is fine, as long as it's compiled with an older zic. For example, Debian testing's tzdata-2014c-1 is unaffected, as it seems to be built using libc-bin's zic, which does not have this change yet.
The change to zic is announced on tz-announce (http://mm.icann.org/pipermail/tz-announce/2014-May/000020.html): "zic now generates transitions for minimum time values, eliminating guesswork when handling low-valued time stamps" (that's probably https://github.com/eggert/tz/commit/7fb077a9ff67dab22b9a23f64f65f85d59cf593e ). Unfortunately it looks like it actually broke glib's "guesswork".
On an unrelated note, init_zone_from_iana_info looks like it should be validating "size" after parsing the header (and again after parsing the second header). It will currently read beyond the end of the buffer returned by g_bytes_get_data if fed a truncated zoneinfo file, unless I'm overlooking validation elsewhere.
Version: 2.40.x