A vulnerability in the widely used NASM assembler, tracked as CVE-2020-21528, allows a specially crafted assembly file to cause an immediate crash. First reported in late 2019, the flaw went largely unnoticed until recently, when it was assigned a CVE and patched in a maintenance release. For anyone running build pipelines or CI systems that process untrusted assembly input, the fix is urgent: an unpatched NASM can be paralyzed by a single malicious file.
The Bug: A NULL Pointer in a Forgotten Code Path
NASM (the Netwide Assembler) is the go-to assembler for many developers working on x86 and x86-64 code. It supports a variety of output formats—ELF, COFF, and the less common IEEE format for floating-point data. The vulnerability lives inside the IEEE output module, specifically in the ieee_segment function of output/outieee.c.
When NASM processes a malformed assembly file that triggers the IEEE code path, it calls the C library function strcmp on a pointer that hasn’t been initialized. This causes a null pointer dereference and an immediate segmentation fault, crashing the assembler. Public advisories confirm that the bug was present in NASM versions 2.14.03 and 2.15, though earlier and intermediate releases may also be affected.
The original bug report, filed in December 2019, included a proof-of-concept input file and an AddressSanitizer (ASAN) stack trace. That trace pinpointed the crash to a string comparison near line 705 of outieee.c. The root cause is simple but deadly: the code assumes a section name string is always valid, but a crafted file can force the assembler into a state where that assumption fails.
Who Is at Risk? Build Pipelines, Sandboxes, and Package Builders
If you only run NASM on your own local machine to assemble code you wrote yourself, you have little to worry about. The bug requires an attacker-supplied file. But if your system automatically assembles code from outside sources—such as in a CI/CD pipeline, an educational coding platform, or a package build farm—you are exposed.
For home users and casual developers: Risk is minimal. You control the input. But if you download and assemble open-source projects or code snippets from forums, an attacker could theoretically hide a malicious file among them. Exercise caution.
For CI/CD administrators and build engineers: This is where the pain can strike. A pull request containing a crafted .asm file can crash your build agents. Even if the job just fails, repeated crashes can stall your pipeline, waste compute resources, and create noise that masks genuine failures. Some pipelines run NASM inside minimal containers; a crash often kills the container and forces a restart.
For developers of online sandboxes and educational tools: Platforms that let users submit assembly code for instant compilation are prime targets. A crash in a worker process could disrupt service for many users or, in poorly isolated environments, take down the entire host.
Even though NASM is far more common on Linux and macOS, Windows users are not immune. Many CI pipelines run Linux workers in Docker, and Windows developers often use WSL or cross-compilation toolchains that include NASM. If NASM lives anywhere in your build chain, you need to check.
How the Vulnerability Works (and How It Doesn’t)
The bug is a denial-of-service (DoS) with no known path to remote code execution (RCE). NASM is not a network-facing program; it reads files from disk. The crafted file must be fed to NASM explicitly—for instance, by running nasm -f ieee crafted.asm. But in automated systems, that feeding happens without human oversight.
The CVSS v3.1 score of 5.5 (Medium) reflects this narrow impact: availability is compromised, but confidentiality and integrity are not. The attack complexity is low, and no privileges are required if the victim processes untrusted input automatically. However, the attack vector is “local,” meaning the vulnerable instance must be executed on the target machine—though “local” in CVSS can be misleading because the input can arrive over the network.
No public exploits have demonstrated anything beyond the crash. The original proof of concept triggers the segmentation fault reliably, and the vendor patch simply added a null check before the offending strcmp call.
A Timeline: From Bug Report to Patch
- December 2019: The bug is reported to the NASM project with a PoC and an ASAN trace. The report notes that the crash occurs in NASM 2.14.03 and 2.15.
- Early 2020: Project maintainers identify the regression, create a patch, and commit it to the source repository. The fix adds proper null pointer validation in
ieee_segment. - 2021–2022: Various Linux distributions begin shipping the patched version. Advisories often reference the fix as part of NASM 2.16.01 release, though some backport it to earlier package versions.
- 2023–2024: The vulnerability is formally assigned CVE-2020-21528 and added to public databases. Microsoft’s Security Response Center publishes an advisory (MSRC) for the issue, and vulnerability scanners integrate detection.
Despite the upstream fix being available for years, downstream users can remain vulnerable if they use older package repositories or custom-built versions. The IEEE output format is so rarely used that many administrators didn’t prioritize the update.
What You Should Do Right Now
1. Check Your NASM Version
Run nasm -v on any machine that builds code. If you see 2.14, 2.15, or any 2.16 release earlier than 2.16.01, assume you are vulnerable unless the vendor has backported the patch.
2. Upgrade
- From package manager: On Linux, use
apt update && apt upgrade nasm,dnf update nasm, or equivalent. Verify the installed version after. - On Windows: If you use NASM via Chocolatey (
choco upgrade nasm) or directly from the NASM website, download the latest stable release (2.16.01 or newer). - From source: If you build NASM yourself, pull the latest commit from the official repository or apply the patch manually. The fix is a small change in
output/outieee.c.
3. If You Can’t Upgrade Immediately
- Block untrusted assembly files: Configure your CI system to reject pull requests that introduce new
.asmfiles, or require human approval before they’re processed. - Sandbox the assembler: Run NASM inside an ephemeral container or virtual machine that can crash without affecting other services. Use seccomp on Linux or JobObjects on Windows to contain the process.
- Disable the IEEE output format: If your codebase never uses
-f ieee, you can modify your build scripts to reject that flag or even remove the offending code path from your local build—but upgrading is safer.
4. Monitor for Crashes
Set up alerting for repeated NASM segmentation faults. On Windows, this may appear as “Exception code: 0xc0000005” in Event Viewer. On Linux, monitor dmesg or system logs for segfaults in /usr/bin/nasm.
5. Audit Your Build Input Sources
List every place your CI pipeline or build service accepts external code. If any of those sources could include assembly files, you have an exposure. Treat any such input as untrusted.
The Bigger Picture: Toolchain Hygiene
CVE-2020-21528 isn’t a dramatic remote exploit, but it exposes a systemic weakness: developers treat compilers and assemblers as opaque utilities, not attack surfaces. A niche code path—like an output format nobody uses—can lurk in a tools for years, bypassing test suites and code reviews.
The NASM case is a textbook example of why fuzz testing matters. The original reporter found the bug with a crafted file, but automated fuzzers targeting the IEEE backend would have unearthed it years earlier. The project’s maintainers responded quickly once the bug was reported, but prevention is always better.
For organizations that build and maintain software, the lesson is clear: inventory every tool in your build chain, track their security advisories, and sandbox them ruthlessly. A crash in a build job may not be a headline-grabbing breach, but it can grind development to a halt.
Outlook
The patch for CVE-2020-21528 has been available for years in upstream NASM, but the slow pace of deployment reminds us that toolchain vulnerabilities often linger. Watch for similar bugs in other assemblers and build tools that parse complex input with little isolation. As CI/CD pipelines and automated code acceptance become more common, the attack surface grows. The next “simple crash” might not be so simple.