1SEAL-2026-010: Two critical out-of-bounds writes in uefi-firmware-parser's imported Tiano decompressor
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-firmware1.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.
mastercontains the fix- no post-fix GitHub release tag newer than
v1.13was published as of 2026-03-29 - the PyPI package still reported
1.11as the latest published version
am i affected?
you are affected if all of the following are true:
- you use
uefi-firmware-parserin 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 < Numberwithout enforcingIndex < NC - the
CharC == 2run-length path can write up toGetBits(Sd, 9) + 20, i.e. as many as531zero bytes, also without anIndex < NCguard
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
BitLenvalues greater than16before indexingCount[]inMakeTable() - add
Index < NCguards inReadCLen() - propagate
MakeTable()failure out ofReadCLen()viamBadTableFlag - tighten adjacent decode bounds in the same decompressor hardening pass
user guidance
- do not assume GitHub
masterfixes 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
- public fix PR #145
- public fix merge commit
- latest vulnerable GitHub release before fix
- PyPI package metadata
- vulnerable
MakeTable()callsite inv1.13 - vulnerable
ReadCLen()write path inv1.13 - fixed downstream file
- related upstream EDK2 hardening family referenced by the maintainer:
CVE-2017-5731,CVE-2017-5732,CVE-2017-5733,CVE-2017-5734,CVE-2017-5735 - CWE-787: Out-of-bounds Write