← research

1SEAL-2026-010: Two critical out-of-bounds writes in uefi-firmware-parser's imported Tiano decompressor

critical
CRITICAL CWE-787 theopolis/uefi-firmware-parser PR #145 credited upstream 2026-03-29

summary

uefi-firmware-parser carried a downstream copy of the Tiano/EFI decompressor without the full set of upstream EDK2 hardening fixes that had already been applied for the same bug family years earlier.

as a result, malformed compressed firmware sections can reach two independent native out-of-bounds writes in uefi_firmware/compression/Tiano/Decompress.c:

  • a stack out-of-bounds write in MakeTable()
  • a heap out-of-bounds write in ReadCLen()

both issues are reachable through the normal decompression path used for attacker-supplied firmware data. in automation or analysis services that ingest untrusted firmware blobs, the consequence is native memory corruption in the parsing process, with deterministic crash as the minimum observed effect and code execution as a plausible ceiling.

maintainer Teddy Reed fixed the downstream copy by merging PR #145, Apply hardening fixes from upstream Tiano implementation, with public reporter credit. as of 2026-03-29, no dedicated GHSA or CVE had been published for the downstream uefi-firmware-parser package.

at a glance

  • affected public GitHub releases: v1.11, v1.12, v1.13
  • affected PyPI package: uefi-firmware 1.11
  • fixed in source: bf3dfaa8a05675bae6ea0cbfa082ddcebfcde23e
  • fixed release: none observed as of 2026-03-29
  • scope: this umbrella covers only the two Tiano decompressor memory-corruption issues

severity

CRITICAL in deployments that process untrusted firmware blobs automatically or remotely.

CWE: CWE-787 (Out-of-bounds Write)

no downstream GHSA or CVE had been published as of 2026-03-29.

why this rating is justified in service-style deployments:

  • both bugs are native out-of-bounds writes in decompression code
  • both are reachable from attacker-controlled compressed input
  • both affect a parser library often used in firmware analysis pipelines
  • the public fix ports upstream security hardening rather than changing benign behavior

the practical floor is deterministic crash of the parsing process. the practical ceiling is possible code execution in the context of the parser process, depending on allocator behavior, compiler settings, and runtime hardening.

this CRITICAL framing assumes service-style or automation-style use where untrusted firmware blobs are accepted for parsing. in strictly local interactive use, the same bugs remain serious native memory corruption issues, but the deployment-adjusted floor is lower.

affected versions

artifact status
GitHub tag v1.11 affected
GitHub tag v1.12 affected
GitHub tag v1.13 affected
PyPI package uefi-firmware 1.11 affected

the imported Tiano decompressor appears to have carried this stale hardening state for years, but this advisory only claims the versions checked directly from public artifacts.

patched versions

the downstream hardening landed in merge commit bf3dfaa8a05675bae6ea0cbfa082ddcebfcde23e through PR #145.

  • master contains the fix
  • no post-fix GitHub release tag newer than v1.13 was published as of 2026-03-29
  • the PyPI package still reported 1.11 as the latest published version

am i affected?

you are affected if all of the following are true:

  • you use uefi-firmware-parser in a vulnerable released build
  • your workflow reaches the native Tiano/EFI decompressor
  • attackers can influence the firmware blobs or compressed sections being parsed

this is especially urgent if:

  • you run a firmware upload or triage service
  • you process third-party firmware automatically in CI, lab tooling, or backend analysis
  • the parsing process runs with meaningful filesystem or network access

vulnerability 1: MakeTable stack out-of-bounds write

MakeTable() uses attacker-influenced bit-length values as indices into a fixed local array:

Count[BitLen[Index]]++;

in vulnerable builds, there is no check that BitLen[Index] stays within the supported range 0..16. a malformed stream can therefore index past Count[17] and corrupt the stack.

the standard parser path reaches the bug through:

CompressedSection.process() -> efi_compressor.TianoDecompress() -> TianoDecompress() -> ReadPTLen() -> MakeTable()

vulnerability 2: ReadCLen heap out-of-bounds write

ReadCLen() reads a 9-bit Number value, so the attacker-controlled upper bound can be 511, but writes into Sd->mCLen[NC] where NC = 510.

in vulnerable builds:

  • the outer loop writes while Index < Number without enforcing Index < NC
  • the CharC == 2 run-length path can write up to GetBits(Sd, 9) + 20, i.e. as many as 531 zero bytes, also without an Index < NC guard

the standard parser path reaches the bug through:

CompressedSection.process() -> efi_compressor.TianoDecompress() -> TianoDecompress() -> DecodeC() -> ReadCLen()

why one advisory

this advisory groups the two bugs together because they share all of the following:

  • same downstream package
  • same component: Tiano/Decompress.c
  • same maintainer fix train
  • same public patch set in PR #145
  • same ecosystem story: a downstream project carried an older decompressor copy without upstream hardening that already existed in EDK2

this is an umbrella advisory, not a claim that the two bugs are identical. they remain independently reportable vulnerabilities with different root causes and different write targets.

fix

PR #145 ports upstream Tiano decompressor hardening into the downstream copy. the PR body explicitly references upstream EDK2 security hardening for CVE-2017-5731 through CVE-2017-5735.

for the two bugs covered here, the key changes are:

  • reject BitLen values greater than 16 before indexing Count[] in MakeTable()
  • add Index < NC guards in ReadCLen()
  • propagate MakeTable() failure out of ReadCLen() via mBadTableFlag
  • tighten adjacent decode bounds in the same decompressor hardening pass

user guidance

  • do not assume GitHub master fixes mean your packaged version is fixed
  • check whether your deployed build includes commit bf3dfaa8a05675bae6ea0cbfa082ddcebfcde23e
  • if you operate a service or automation pipeline, treat all pre-fix releases as unsafe for untrusted firmware input

if you parse untrusted firmware blobs, the practical safe boundary is not “latest tag before March 2026” but “a build that actually contains bf3dfaa... or a later released package once one exists.”

timeline

date event
2026-02-27 maintainer opens and merges PR #145, Apply hardening fixes from upstream Tiano implementation
2026-03-07 public comment notes that the Tiano hardening areas in the PR correspond to privately reported vulnerabilities and requests downstream CVE / GHSA handling
2026-03-09 maintainer publicly replies that a GHSA request would be welcome and asks for draft text
2026-03-09 draft GHSA text for the two independent Tiano memory-corruption issues is provided in the PR discussion
2026-03-21 public follow-up asks whether the draft is acceptable; no GHSA or CVE is visible in the public thread afterward
2026-03-29 no dedicated GHSA or CVE observed for the downstream package; public advisory published

credit

discovered and reported by Oleh Konko (1seal).

PR #145 publicly credits @1seal.

references