Skip to content

_zoneinfo: heap buffer overflow reads from malformed TZif data #145883

Closed

Description

@StanFromIreland

Crash report

What happened?

Turns out the first issue was found independently in December 2025 and March 2026 by security researchers, but it isn't considered a security issue. Our OSS Fuzz fuzzer later found a second issue, #492245058.

(See the PR for testcases.)

>>> import _zoneinfo
>>> with open("tzif_invalid_trans_idx", "rb") as f:
...     _zoneinfo.ZoneInfo.from_file(f)
...     
python: ./Modules/_zoneinfo.c:1152: load_data: Assertion `ttinfo_idx < self->num_ttinfos' failed.
Aborted                    (core dumped) /home/stan/dev/cpython/python
>>> import _zoneinfo
>>> with open("tzif_invalid_lookahead", "rb") as f:
...     _zoneinfo.ZoneInfo.from_file(f)
...     
Segmentation fault         (core dumped) /home/stan/dev/cpython/python

I have a patch that fixes both at hand.

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Output from running 'python -VV' on the command line:

No response

Linked PRs

Activity

  1. raminfp commented on Mar 13, 2026

    @raminfp
    Contributor

    Modules/_zoneinfo.c, load_data(), line 1068

    import struct
    import io
    from zoneinfo import ZoneInfo
    
    
    def build_tzif_v1(timecnt, typecnt, trans_times, trans_types,
                      utcoffs, isdsts, abbr_indices, abbr_str):
        header = b"TZif\x00" + b"\x00" * 15
        header += struct.pack(">6l", 0, 0, 0, timecnt, typecnt, len(abbr_str))
    
        data = b""
        for t in trans_times:
            data += struct.pack(">l", t)
        for idx in trans_types:
            data += struct.pack("B", idx)
        for i in range(typecnt):
            data += struct.pack(">lbb", utcoffs[i], isdsts[i], abbr_indices[i])
        data += abbr_str
    
        return header + data
    
    
    # typecnt=2 -> valid indices: 0, 1
    # trans_types=[2] -> index 2 == typecnt
    # Buggy check: 2 > 2 = False (passes)
    # Correct:     2 >= 2 = True (rejected)
    tzif = build_tzif_v1(
        timecnt=1, typecnt=2,
        trans_times=[1000],
        trans_types=[2],
        utcoffs=[0, 3600],
        isdsts=[0, 1],
        abbr_indices=[0, 4],
        abbr_str=b"STD\x00DST\x00",
    )
    
    ZoneInfo.from_file(io.BytesIO(tzif))

    Output :

    python: ../Modules/_zoneinfo.c:1152: load_data: Assertion `ttinfo_idx < self->num_ttinfos' failed.
  2. StanFromIreland commented on Mar 13, 2026

    @StanFromIreland
    MemberAuthor

    It is fixed by #145885, no?

  3. raminfp commented on Mar 14, 2026

    @raminfp
    Contributor

    Yes fixed, thanks,

  4. deleted a comment from khalidsaidi on Mar 14, 2026
  5. added a commit that references this issue on Apr 4, 2026
  6. added 2 commits that reference this issue on Apr 4, 2026
  7. added 2 commits that reference this issue on Apr 4, 2026
  8. added a commit that references this issue on Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

extension-modulesC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dump

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions