A hostile SD card that lies about its FAT geometry until the math overflows and the mount code writes wherever the attacker wants
FatFS is ChaN's tiny FAT filesystem library — the one baked into a huge fraction of the world's microcontroller firmware, from STM32 hobby projects to industrial HMIs, printers, medical infusion pumps, automotive infotainment, and consumer USB gadgets. In mount_volume() on R0.16 and earlier, the code computes fasize *= fs->n_fats where both operands come from attacker-controlled on-disk BPB fields. On 32-bit builds (the overwhelming majority of FatFS deployments) a crafted FAT32 boot sector can wrap this multiplication, producing an undersized allocation and mis-sized cluster/FAT bookkeeping. Subsequent reads/writes then index outside the intended buffers, giving memory corruption at mount time — before any file is even opened.
Vendor severity is HIGH (7.6) with vector AV:P/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H. The scope-changed C/I/A:H is defensible for embedded targets where a filesystem library sits in the same address space as the whole firmware — corrupting it *is* corrupting the device. But the AV:P gate is the whole story: the attacker has to physically insert media. For a fleet of servers, laptops, or cloud workloads this is essentially not a threat. For a fleet of kiosks, ATMs, PLCs, or medical devices with exposed USB/SD slots, the vendor score is honest. Reality: MEDIUM for a typical enterprise, HIGH if you own field-deployed embedded gear.
4 steps from start to impact.
Craft a malicious FAT32 volume
BPB_FATSz32, BPB_NumFATs) chosen so that fasize * n_fats overflows a 32-bit unsigned. Trivially done by hand-editing sector 0 with a hex editor or a 20-line Python script; no exploit framework required. Public FAT fuzzing corpora (e.g., AFL/fatfuzz seeds) already contain overflow triggers.- Ability to write a raw disk image
- Knowledge of target FatFS build's word size (usually 32-bit)
- None — this is a text-editor step
Deliver the media to a vulnerable device
mkfs.fat + dd patching, or fatfuzz from strongcourage/fuzzing).- Physical proximity or supply-chain interdiction of media
- Firmware auto-mounts inserted volumes
- Servers, VMs, and cloud workloads don't use FatFS
- Enterprise laptops use the OS FAT driver, not FatFS
- Many embedded devices disable removable media in production
- Chassis intrusion / port-blocking policy on kiosks and ATMs
Trigger mount_volume() overflow
f_mount() → mount_volume() parses the BPB and executes fasize *= fs->n_fats, wrapping to a small value. The subsequent FAT and directory reads are computed against wrong bounds, producing out-of-bounds reads/writes into adjacent heap or static buffers depending on the firmware layout.- FatFS ≤ R0.16 linked in
- 32-bit target (or 64-bit with
FF_INTDEF=1)
- Some vendors patch or fork FatFS internally
- Some builds mount lazily and never reach this code without a user action
Achieve code execution or brick
- Exploitable memory layout — heap or static region adjacent to control data
- MPU/MMU-protected RTOS builds limit blast radius
- Secure Boot + signed firmware may prevent persistence, but not runtime code exec
- Watchdog reset may frustrate reliable RCE
binwalk, cwe_checker, or vendor SBOMs to identify which shipped firmware images link FatFS ≤ R0.16. Query Zephyr, NuttX, ChibiOS, Azure RTOS, and vendor-forked copies specifically. Complete inventory within 30 days so remediation planning has ground truth.- EDR / antivirus on the endpoint — FatFS runs inside embedded firmware, not on your Windows/Linux hosts; endpoint security has no visibility.
- Network segmentation / firewalls — the vulnerability is not network-reachable;
AV:Pmeans the packet never crosses a wire. - Filesystem scanning of the media contents — the malicious data is in the BPB (sector 0), not in files; AV file scanning won't inspect it.
- Disabling FAT filesystem support in Windows/Linux — irrelevant; the vulnerable code is FatFS specifically, not the OS FAT driver.
The supporting signals.
| In-the-wild exploitation | None observed. Not in CISA KEV. No public campaign reporting as of 2026-07-04. |
|---|---|
| PoC availability | No dedicated public PoC yet, but *trivial* to build — FatFS fuzzing harnesses in strongcourage/fuzzing and google/oss-fuzz already generate BPB-overflow inputs. |
| EPSS | 0.0021 (~0.2 percentile) — model correctly reflects negligible mass-exploitation likelihood given AV:P |
| KEV status | Not listed. No CISA action. |
| CVSS 3.1 vector | AV:P/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H — the AV:P is the decisive severity-limiter; scope-change is fair for embedded co-located firmware. |
| Affected versions | FatFS R0.16 and earlier, all configurations built with 32-bit integer defaults (default on Cortex-M). |
| Fixed version | FatFS R0.16a (upstream patch adds explicit overflow check on fasize * n_fats). Downstream: Zephyr, NuttX, ChibiOS, Azure RTOS may ship as forked copies — audit each SBOM. |
| Exposure telemetry | Not internet-reachable by definition (AV:P). No Shodan/Censys/GreyNoise signal is meaningful for this CVE — the exposure question is *physical port count*, not IP surface. |
| Disclosure | 2026-07-01, upstream by ChaN via elm-chan.org changelog; MITRE assigned as CVE-2026-6682. |
| Deployment footprint | FatFS is one of the most widely embedded FAT libraries — present in millions of MCU firmware images. Enterprise servers/workstations are not affected; embedded, OT, medical, automotive, and consumer IoT are. |
Sources.
Why this verdict
- Friction: physical access required —
AV:Pcollapses the addressable population to devices with attacker-reachable removable-media ports. Servers, VMs, laptops (which use OS FAT drivers, not FatFS) are unaffected. - Friction: FatFS is not on IT endpoints — the library ships inside firmware, not on Windows/Linux/macOS user devices. If you're not shipping firmware or operating embedded gear, your exposed count is zero.
- Friction: EPSS 0.002 and no KEV — signals from both worldwide-observed-exploitation datasets align with the AV:P reality: this will not become a mass-exploitation event.
- Role multiplier: workstation/server fleet — chain does not succeed; FatFS is not present. Blast radius: none.
- Role multiplier: kiosks, ATMs, printers, MFPs, digital signage — chain succeeds if USB/SD is reachable; blast radius: single device compromise, possibly network pivot if device is dual-homed. Verdict floor for this role: MEDIUM.
- Role multiplier: medical devices, industrial PLCs/HMIs, automotive ECUs — chain succeeds; blast radius includes safety-of-life or OT process impact. For organizations with such devices, this is HIGH and the verdict floor rises accordingly.
- Role multiplier: build systems that mount untrusted FAT images (forensics workstations, CI that unpacks firmware) — chain succeeds via a mounted image file, not physical media; blast radius: build-server compromise. Rare but worth SBOM-checking.
Why not higher?
Not HIGH for a general enterprise because the affected component is not present on the IT fleet and the attack requires physical media insertion, which excludes remote adversaries entirely. If your organization operates field-deployed embedded devices, medical equipment, or ICS/OT with FatFS in the firmware, you should locally re-rate this as HIGH per the role-multiplier analysis above.
Why not lower?
Not LOW because the vulnerability is a real memory-corruption bug in mount-time parsing, exploitable pre-authentication once media is inserted, and FatFS is genuinely ubiquitous in embedded firmware. Anyone running kiosks with exposed USB, digital signage, medical devices, or PLCs has a plausible physical-attack path with device-compromise blast radius.
Crowdsourced verification payload.
Run this on any Linux host, forensics workstation, or CI runner that stores firmware images. Invoke as ./check-fatfs.sh /path/to/firmware_dir — no root required, just read access to the firmware artifacts. It greps unpacked firmware trees for FatFS version strings and known-vulnerable ranges.
#!/usr/bin/env bash
# check-fatfs.sh — detect FatFS <= R0.16 in unpacked firmware trees
# Usage: ./check-fatfs.sh <path-to-firmware-tree>
# Exits: 0 = PATCHED / not present, 1 = VULNERABLE, 2 = UNKNOWN
set -u
TARGET="${1:-.}"
if [ ! -d "$TARGET" ]; then
echo "UNKNOWN: $TARGET is not a directory"
exit 2
fi
FOUND_ANY=0
FOUND_VULN=0
# Search source drops (ff.c, ff.h) and stripped binaries
while IFS= read -r -d '' f; do
FOUND_ANY=1
# elm-chan revision string, format like "R0.15", "R0.16", "R0.16a"
ver=$(strings "$f" 2>/dev/null | grep -Eo 'R0\.[0-9]+[a-z]?' | head -n1)
if [ -z "$ver" ]; then
continue
fi
echo "[i] $f -> FatFS $ver"
# Vulnerable: everything <= R0.16 without an 'a' or later suffix
case "$ver" in
R0.16a|R0.16b|R0.16c|R0.17*|R0.18*|R0.19*)
;;
R0.16)
FOUND_VULN=1
echo "[!] VULNERABLE: $f contains FatFS R0.16 (no fix suffix)"
;;
R0.1|R0.2|R0.3|R0.4|R0.5|R0.6|R0.7|R0.8|R0.9|R0.10*|R0.11*|R0.12*|R0.13*|R0.14*|R0.15*)
FOUND_VULN=1
echo "[!] VULNERABLE: $f contains FatFS $ver (< R0.16a)"
;;
esac
done < <(find "$TARGET" -type f \( -name 'ff.c' -o -name 'ff.h' -o -name '*.bin' -o -name '*.elf' -o -name '*.hex' -o -name '*.img' \) -print0)
if [ "$FOUND_ANY" -eq 0 ]; then
echo "PATCHED: no FatFS artifacts found under $TARGET"
exit 0
fi
if [ "$FOUND_VULN" -eq 1 ]; then
echo "VULNERABLE"
exit 1
fi
echo "PATCHED"
exit 0