Uninitialized Memory Access in zic
Core Problem
PostgreSQL's zic (timezone compiler) utility, which is used during the build process to compile timezone data files into binary format, contains an uninitialized memory access bug detected by Valgrind. Specifically, a conditional jump or move depends on uninitialized values in the writezone() function at line 2311 of zic.c.
The root cause, as identified through the Valgrind trace, is:
- Memory is allocated via
emalloc()(a wrapper aroundmalloc()) atzic.c:2102withinwritezone() - This memory is not fully initialized before being used in a conditional branch at line 2311
- The control flow path that leaves the memory uninitialized appears to be related to a QT bug workaround — code that was unconditionally executed but whose prerequisite initialization was gated behind a
want_bloat()check
Technical Context
PostgreSQL maintains a vendored copy of the IANA timezone code (src/timezone/), including the zic compiler. This code is periodically synced from upstream (the eggert/tz repository maintained by Paul Eggert). The PostgreSQL copy can lag behind upstream, which means bugs fixed upstream may persist in PostgreSQL's tree.
The writezone() function is responsible for writing compiled timezone data to binary files. It handles various output formats and compatibility workarounds, including a workaround for a QT framework bug. The issue is that the workaround code path accessed allocated memory that was only conditionally initialized — specifically, initialization occurred only when want_bloat() returned true (indicating the user wanted backward-compatible "bloated" output), but the workaround code that read that memory ran unconditionally.
Resolution Path
The thread quickly converges on a resolution strategy: do not independently fix this bug; instead, update PostgreSQL's vendored tzcode to a more recent upstream version. The upstream fix is identified as commit 93132d18 in the eggert/tz repository, which first appeared in timezone release 2021b. This commit restructured the relevant code in writezone() to eliminate the uninitialized access.
Tom Lane explicitly volunteers to prioritize the tzcode update, noting he had already been meaning to do this sync for some time.
Key Design Decision
The decision not to independently patch this bug, but to instead pull in a newer upstream version, reflects PostgreSQL's maintenance strategy for vendored external code:
- Minimizing local divergence from upstream reduces long-term maintenance burden
- Upstream has already fixed the issue plus potentially other bugs
- Independent patches risk merge conflicts with future upstream syncs
- The bug is in build-time tooling (not runtime), limiting its immediate severity
Severity Assessment
This bug is relatively low-severity because:
- It occurs in
zic, a build-time tool, not in the PostgreSQL server itself - The uninitialized memory likely doesn't produce incorrect timezone files in practice (the workaround code path's conditional probably evaluates "safely" with garbage data in most cases)
- It was detected by Valgrind instrumentation, not by observable misbehavior
However, it does represent a real correctness issue and would be a problem for anyone running Valgrind-instrumented builds (e.g., for development/CI testing), as it produces noise in Valgrind output that could mask other real issues.