mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 10:40:47 +03:00
fix(storage/fatfs): clamp exFAT volume-label length in f_getlabel() (CVE-2026-6687)
f_getlabel() extracts the exFAT volume label with a loop bounded by the on-disk
byte dj.dir[XDIR_NumLabel] (0-255):
for (si = di = hs = 0; si < dj.dir[XDIR_NumLabel]; si++)
wc = ld_16(dj.dir + XDIR_Label + si * 2);
The exFAT label field holds at most 11 UTF-16 units (22 bytes). A crafted
directory entry with a larger count both reads past the 22-byte label field and,
through put_utf(... &label[di], 4), writes past the end of the caller-provided
label buffer (the canonical API examples use small fixed stack buffers) -> stack
buffer overflow.
Clamp the character count to the exFAT maximum of 11 before the extraction loop.
Record the CVE in the component SBOM.
Note: f_getlabel() takes no destination-buffer size, so under UTF-8 output
(FF_LFN_UNICODE == 2) 11 units can still expand to up to 34 bytes; the clamp
downgrades this from attacker-unbounded to spec-bounded. ESP-IDF's VFS layer
does not call f_getlabel(); direct callers on untrusted media should size their
buffer accordingly. A complete fix requires an upstream size-aware API change.
Reference: https://www.runzero.com/blog/fatfs-bugs/
This commit is contained in:
@@ -10,3 +10,5 @@ cve-exclude-list:
|
||||
reason: exFAT divide-by-zero when NumClusters == 0. The vulnerable exFAT PercInUse sync division was introduced in R0.16 and is not present in this R0.15 release; an empty cluster heap is additionally rejected at mount as defense-in-depth.
|
||||
- cve: CVE-2026-6685
|
||||
reason: Unsigned-subtraction wrap in the dirty-cache refill check. Patched by requiring the cached sector to lie within the direct-I/O range in both f_write() and f_read().
|
||||
- cve: CVE-2026-6687
|
||||
reason: exFAT label-length overflow in f_getlabel(). Patched by clamping XDIR_NumLabel to the 11-unit exFAT label maximum.
|
||||
|
||||
@@ -5408,9 +5408,11 @@ FRESULT f_getlabel (
|
||||
#if FF_FS_EXFAT
|
||||
if (fs->fs_type == FS_EXFAT) {
|
||||
WCHAR hs;
|
||||
UINT nw;
|
||||
UINT nw, nchar;
|
||||
|
||||
for (si = di = hs = 0; si < dj.dir[XDIR_NumLabel]; si++) { /* Extract volume label from 83 entry */
|
||||
nchar = dj.dir[XDIR_NumLabel]; /* Number of UTF-16 characters in the label entry */
|
||||
if (nchar > 11) nchar = 11; /* CVE-2026-6687: clamp to the exFAT maximum (11) to prevent OOB read of the entry and overflow of the caller label buffer */
|
||||
for (si = di = hs = 0; si < nchar; si++) { /* Extract volume label from 83 entry */
|
||||
wc = ld_word(dj.dir + XDIR_Label + si * 2);
|
||||
if (hs == 0 && IsSurrogate(wc)) { /* Is the code a surrogate? */
|
||||
hs = wc; continue;
|
||||
|
||||
Reference in New Issue
Block a user