Lua CVE-2022-28805 Patch Guide: 5.4.x Buffer Over-read in Lua Parser

  • Thread Author
The Lua interpreter received a critical security fix in 2022 after researchers discovered that a missing internal call in lparser.c’s singlevar function allowed a heap-based buffer over-read when compiling certain crafted scripts—an issue tracked as CVE-2022-28805 that affects Lua releases 5.4.0 through 5.4.3 and prompted the upstream fix in the 5.4.4 release.

Lua compiler pipeline: parser → singlevar → anyregup → generator; patch 5.4.4 heap overflow.Background / Overview​

Lua is a lightweight, embeddable scripting language used widely in games, embedded devices, plugin systems, and numerous products that embed a scripting runtime into a host application. Because Lua is often embedded, the language runtime sometimes executes code originating from untrusted sources (for example: user-supplied mods, third-party plugins, or scripts shipped inside downloaded assets). The discovery of CVE-2022-28805 is important precisely because the vulnerable code path is exercised during compilation of Lua code, not just runtime execution—meaning systems that accept and compile untrusted Lua code are in scope.
The public vulnerability record describes the defect succinctly: the function singlevar in lparser.c lacked a call to luaK_exp2anyregup, and that omission allowed a heap out‑of‑bounds read under certain conditions. The practical consequence is a heap-based buffer over‑read that can cause crashes (availability impact), leak memory (confidentiality impact), and—depending on memory layout and surrounding code—could be a stepping stone toward more serious memory-corruption exploitation.

What exactly failed: a technical explanation​

The role of singlevar and expdesc​

  • singlevar is a parser helper in Lua’s lparser.c used during compilation when the parser resolves an occurrence of a single variable (a bare name) or an upvalue reference.
  • The parser uses structured descriptors—expdesc—to represent expressions and variables while generating bytecode. These descriptors record whether a value is in a register, a constant, an upvalue, or otherwise.
  • The helper luaK_exp2anyregup is a code generator utility that ensures an expression is materialized in a register or upvalue slot suitable for subsequent operations.
Under certain parsing paths, singlevar could leave the expdesc in a state that required conversion to a register/upvalue before subsequent codegen. Because the call to luaK_exp2anyregup was missing in the affected versions, further code generation assumed fields in the expdesc were valid when they were not—leading to reads past allocated arrays or buffers in subsequent routines and therefore a heap-based buffer over‑read.

Why a missing call matters in a compiler​

In compiler internals, small state invariants matter. A missing normalization step (here, ensuring the variable descriptor is in the canonical register/upvalue form) can leave the code generator operating on stale or partially-initialized descriptors. The downstream code assumes valid indices and lengths when indexing arrays or copying memory; when those assumptions are violated, the program can read beyond the intended buffer. That’s the core of CVE‑2022‑28805. Several public technical writeups reproduce the minimal fix: add the missing luaK_exp2anyregup(fs, var) call at the end of singlevar so expdesc is normalized before returning.

Exploitability and real-world impact​

Who is affected​

  • Any product or service that includes Lua versions 5.4.0, 5.4.1, 5.4.2, or 5.4.3 and compiles untrusted Lua code is within scope. That includes:
  • Game engines or games that compile user-supplied scripts or mods on the fly.
  • Plugin hosts, editors, or automation tools that accept third‑party scripts from untrusted sources.
  • Embedded devices or appliances that accept scripts via network interfaces and compile them locally.
  • CI or build systems that compile Lua code provided from untrusted origins at build time.
  • Systems that only execute pre-vetted, bundled Lua scripts and never compile untrusted input are lower risk, though supply-chain concerns still apply because statically bundled runtimes may still be vulnerable until updated.

Severity and potential outcomes​

Vendor and vulnerability-tracker scoring placed this issue at high or critical severity in many trackers—because it's a remotely reachable parsing/compilation path in many deployments and the resulting read can expose memory or crash the process. Typical and realistic impacts are:
  • Denial of Service (DoS): the most immediate and likely impact—craft a script that triggers the condition and cause the process to crash. This can be done repeatedly, producing sustained availability loss for services that accept scripts from remote sources. Many vendor advisories emphasize availability consequences in their descriptions.
  • Information Disclosure: one‑byte or multi‑byte heap over‑reads can leak adjacent heap contents to an attacker in some contexts, especially if the interpreter prints or processes touched memory in a way exposed to the attacker. While a single byte leak may seem small, repeated leaks can reveal sensitive data. Several trackers mark confidentiality impact as possible.
  • Chained Exploitation (RCE): achieving arbitrary code execution from an out‑of‑bounds read alone is harder than from a write or UAF, but it is not impossible in carefully groomed environments. Several advisories caution that RCE is theoretically possible under favorable heap layouts or when combined with other vulnerabilities, so defenders must not discount that path.

Conditions that increase risk​

  • Environments that compile untrusted code directly and return compilation results or error messages to the caller (the attacker) are higher risk, because an attacker can iteratively probe and refine inputs.
  • Statically linked or bundled Lua runtimes embedded in third‑party appliances or closed-source binaries: these will remain vulnerable until the vendor rebuilds and ships an updated binary.
  • Systems exposed to wide, unauthenticated input surfaces (public game servers, open mod repositories, file upload interfaces) elevate exploitation likelihood.

Vendor responses and distribution patching​

Upstream Lua released fixes in the 5.4.4 series and distributions rapidly mapped the fix into package updates. Major Linux distributors (Debian, Ubuntu, Red Hat/CentOS, SUSE) published advisories or backported patches; some vendors adjusted their packaging to include the specific fix and updated package revisions. Security scanners and vulnerability feeds added detection and remediation guidance fairly quickly.
A few operational notes drawn from vendor responses and packaging activity:
  • Some vendors treated the issue as critical in CVSS scoring; others gave lower internal severity based on their threat models—this variance is expected because exploitability and impact differ by deployment. Always inspect your specific vendor advisory and package version mapping rather than assuming uniform severity.
  • Static binaries and vendor appliances that bundle Lua must be rebuilt and republished—an OS-level package update does not change embedded code inside a closed binary. The supply‑chain angle is important: updating the runtime on hosts doesn’t fix already‑deployed images or appliances that include the vulnerable runtime.

Detection, testing and verification​

How to detect vulnerable builds and instances​

  • Check the Lua version: on systems where Lua is installed, run the interpreter’s version command (or inspect package metadata). Vulnerable upstream versions are from 5.4.0 up to but not including 5.4.4. Package maintainers typically include the patched version number in changelogs and security advisories.
  • Search for embedded runtimes: scan binaries and images for Lua version strings. Many compiled Lua binaries include build metadata or version strings you can search for in images. If a third‑party binary reports it bundles Lua 5.4.x in the vulnerable range, treat it as in-scope.
  • Inventory compilation surfaces: identify services and code paths that invoke the Lua compiler (for example, luac or in-process compilation APIs). Any surface that accepts external content for compilation is high priority.
  • Fuzz and regression tests: run a small set of negative tests and fuzz inputs through your compilation paths in a controlled staging environment. The bug is deterministic under the right conditions, so a small harness that compiles crafted inputs can reveal crashes.

How to verify a fix​

  • After upgrading to Lua 5.4.4 (or applying your vendor’s patched package), re-run the targeted regression/fuzz tests and verify that previously crashing inputs no longer cause over‑reads or crashes.
  • Confirm package changelogs and vendor advisory text include CVE‑2022‑28805 (or equivalent tracker) and that the revision you installed maps to the patched version. Distributions often provide version-to-fix mappings in their advisories.

Remediation and mitigation (practical playbook)​

Immediate remediation steps (minutes to hours)
  • Identify and patch any hosts running vulnerable Lua packages from 5.4.0–5.4.3. Prefer vendor-upgraded packages when available. If the host uses upstream builds, upgrade to Lua 5.4.4 or later.
  • If you cannot immediately patch, prevent untrusted compilation paths: temporarily disable any service endpoints that accept uploaded or remote Lua code for compilation. Where that’s not possible, quarantine or apply strict filtering to inputs.
  • For public-facing services that compile user scripts, apply rate limits and implement request size limits and CPU/memory caps for the compilation worker processes to limit blast radius.
Short-to-medium term (days)
  • Rebuild and redeploy any statically linked or bundled artifacts that include Lua (appliances, agents, game servers, IoT images). OS package upgrades won’t fix static binaries—you must rebuild artifacts that embed the runtime.
  • Add targeted monitoring and alerts: watch for interpreter crashes, repeated process restarts, unexpected compilation errors, or unusual spike in compilation jobs. These can indicate exploitation attempts.
  • Add regression tests into CI that compile representative untrusted samples (including edge cases) and assert the compiler does not crash.
Long-term (weeks to months)
  • Reduce exposure: design application architecture to never compile untrusted code in-process with elevated permissions. If you must compile third‑party scripts, use hardened sandboxing (separate pinned containers, strict namespace and resource limits, seccomp filters, and dedicated users).
  • Adopt supply‑chain hygiene: track SBOMs for your images and third‑party artifacts, pin runtime versions in builds, and require rebuilds of third-party binaries before deploying to production. Vendor attestations and VEX/CSAF notices help, but internal verification remains crucial.

Concrete step‑by‑step for operators​

  • Inventory: run a discovery to find all instances of Lua and identify versions (OS packages, embedded runtimes inside binaries, images in registries).
  • Prioritize: flag public-facing compilation hosts and any service that compiles untrusted content at the top of your list.
  • Patch hosts: install vendor-provided updates or upstream Lua 5.4.4+ packages. For Debian/Ubuntu/Red Hat/SUSE, follow your vendor’s security advisory mapping to fixed package versions.
  • Rebuild images: for container images and statically linked binaries, rebuild from source using patched Lua and redeploy.
  • Harden: if immediate rebuilds are impossible, place hosts behind access controls and network filters that restrict who can submit scripts for compilation.
  • Verify: run regression tests and fuzz harnesses to confirm the fix. Monitor logs and orchestrator restart events for anomalies.

Critical analysis: strengths of the response and residual risks​

What went right
  • The Lua upstream and major distributors responded quickly with a clear, minimal fix: add the missing normalization call so parser invariants hold. This is a focused fix that preserves language behavior while closing the memory-safety gap. Multiple vendor advisories and package updates followed, enabling operators to patch.
  • The issue is well understood and reproducible in test harnesses, which helps defenders validate remediation.
Residual risks and tradeoffs
  • Static bundling / closed appliances: many third‑party products embed Lua in their images or binaries. Those artifacts will remain vulnerable until vendors rebuild and ship updates—or until customers rebuild in-house. This supply-chain lag is the most persistent operational risk.
  • Exploit chaining potential: while the primary practical impact for many deployments is DoS or limited disclosure, attackers with the ability to iteratively probe memory leaks could combine this with other weaknesses to aim for stronger primitives. Defenders must assume worst-case scenarios until their environments are verified.
  • Coverage variance among vendors: some distributions or vendors may assign differing severity levels or backport decisions; operators must not assume that “patched on one distro” equals total ecosystem safety. Always map the fix to your exact package and image versions.

Developer guidance: how to avoid similar issues​

  • Treat parser and diagnostic code with the same security discipline as core parsing/runtime code. Debug/dump helpers and pretty‑printers often manipulate internal structures—apply defensive normalization and validation before assuming invariants.
  • Add unit tests that specifically exercise rare code paths (scoping edge cases, upvalue handling, nested closures) and use fuzzing tools to stress parsing of malformed inputs.
  • When exposing compilation capabilities to users, adopt strict sandboxing and limit privileges and resources—never trust inputs by default.

Final recommendations (clear checklist)​

  • Upgrade Lua to 5.4.4 or later for any host or build environment that runs or compiles untrusted scripts. Confirm the fix via vendor advisory mappings and changelogs.
  • Rebuild and redeploy any statically linked or embedded Lua artifacts you control; require vendors to provide patched builds for appliances you use. Do not rely solely on OS package updates to remediate embedded runtimes.
  • If immediate patching is impossible, remove or restrict any service that compiles untrusted Lua code, add rate limits, and enforce resource caps on compiler processes.
  • Add regression and fuzz tests for compilation paths to CI; automate checks that refuse to build or package known-vulnerable versions.
  • Monitor for interpreter crashes, abnormal compilation failures, and repeated restarts—these could indicate active exploitation attempts.
  • Maintain SBOMs and track runtime versions across your images and appliances; plan rebuilds as a standard security lifecycle task.

CVE‑2022‑28805 is a concise reminder that tiny lapses in compiler invariants can create outsized security problems, particularly when runtimes are embedded and exposed to untrusted inputs. The fix is straightforward, but the operational work—patching hosts, rebuilding images, and verifying third‑party binaries—requires discipline and supply‑chain rigor. For organizations that compile or host Lua code originating from outside their trust boundary, the prudent path is immediate patching, aggressive containment of untrusted compilation, and a focused program to eliminate embedded vulnerable runtimes across images and appliances.

Source: MSRC Security Update Guide - Microsoft Security Response Center
 

Back
Top