OOB read in __txn_printlog WT_LOGREC_SYSTEM handling on truncated log records

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Minor - P4
    • WT12.0.0, 9.1.0-rc0
    • Affects Version/s: None
    • Component/s: Logging
    • None
    • Environment:
      GCC 13, Ubuntu 24.04
    • Storage Engines - Transactions
    • 504.072
    • None
    • 1

      In __txn_printlog (src/txn/txn_log.c (line 745-750), the WT_LOGREC_SYSTEM case unpacks two uint32_t fields using format "II", even though WT_LOGREC_SYSTEM records have zero header fields per dist/log_data.py; this call is actually a leftover from 2017, when WT_LOGREC_SYSTEM records only ever carried a prev_lsn payload and this same "II" unpack was used intentionally to decode it directly (commit f86e30cb2), but when the record type was later generalized to also carry other operations like checkpoint_start and the printlog handler was switched to the generic __txn_oplist_printlog (commit 540cb969a), the now-stale "II" unpack call above it was never removed, so today it reads the first system operation's optype/opsize bytes instead. But since __wt_struct_unpack takes the buffer pointer by value it never advances the caller's p, so on well-formed records the stale unpack is silently harmless and __txn_oplist_printlog re-parses the same bytes correctly afterward, which is why this has gone unnoticed. However, if a system record's payload is empty or truncated right after the rectype byte (i.e. end == p at this call site), __wt_vunpack_uint's guard WT_SIZE_CHECK_UNPACK(1, maxlen) fails to catch it because the macro treats a zero maxlen as "unchecked" by design, so the code falls through to dereference one byte past the end of the buffer, causing an out-of-bounds read. This only occurs with a corrupted or maliciously crafted log file, never through normal logging/checkpoint operations, since every real system record's optype/opsize header is written unconditionally by __wt_logop_write, so it's mainly a risk when running wt printlog against untrusted or corrupted log files, and the fix is simply to remove the stale "II" unpack call, noting that a test which only exercises normal printlog output (e.g. checkpoint then printlog) will pass identically with or without the fix since it never produces a zero-length payload at this call site.

            Assignee:
            Unassigned
            Reporter:
            Tuna KARABACAK (EXT)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: