Commit Graph

437 Commits

Author SHA1 Message Date
sonika.rathi
d95ca349ca fix(fatfs): move readdir-stat cache to per-DIR stream
Move cached_fileinfo and dir_path from vfs_fat_ctx_t to vfs_fat_dir_t so
each open DIR* has its own readdir→stat cache.
2026-07-09 12:52:09 +02:00
Tomáš Rohlínek
6a20a83421 fix(storage/fatfs): fix FAT32 mount integer overflow (CVE-2026-6682)
The initial CVE-2026-6682 fix (merged in !50362) hardened the exFAT
mount path, but the CVE as reported by runZero is a FAT32 defect in
mount_volume() and is reachable in ESP-IDF's default configuration
(exFAT and 64-bit LBA disabled). This corrects the fix.

Root cause: `fasize *= fs->n_fats` is a DWORD multiply with no overflow
guard. A crafted BPB_FATSz32 such as 0x80000001 with NumFATs=2 wraps
`fasize` to 0x00000002. The wrapped (too-small) FAT size then places
`fs->database` inside the FAT region, so a forged directory entry in the
overlapping sector yields an attacker-controlled `finfo.fsize`. Any
caller that uses that size as a read length overflows its buffer with
attacker-controlled bytes (CVSS 7.6, path to RCE). The later
`fs->fsize < szbfat` check does not catch this because it compares the
un-doubled single-FAT size, which is still large.

Fix: reject a per-FAT size that overflows DWORD when multiplied by the
FAT count, and reject a reserved+FAT+root system-area size that overflows
DWORD, before either value is used to derive the data-area base.

The previous exFAT cluster-heap/bitmap 64-bit promotions are retained as
defense-in-depth and their comments relabeled accordingly (they are not
CVE-2026-6682). The SBOM cve-exclude-list reason is updated to describe
the FAT32 overflow and its fix.
2026-07-07 16:36:30 +02:00
Tomáš Rohlínek
5716f444d4 fix(storage/fatfs): record non-applicable runZero 2026 CVEs in SBOM
Document the three runZero "Seven FatFs bugs" CVEs that require no source change
in this component, so vulnerability scanners have their disposition:

  - CVE-2026-6684: GPT partition-scan loop DoS. Already fixed upstream in R0.16,
    where test_gpt_header() caps the partition-entry count at 128.
  - CVE-2026-6686: read of uninitialized clusters after f_lseek() past EOF.
    Longstanding, behavioral; not a memory-safety defect and zero-filling every
    extended cluster is prohibitively costly on flash.
  - CVE-2026-6688: long-filename overflow in downstream callers. Not exposed in
    ESP-IDF; vfs_fat.c uses bounded copies and fname is bounded by FF_MAX_LFN.

Reference: https://www.runzero.com/blog/fatfs-bugs/
2026-07-06 13:39:24 +02:00
Tomáš Rohlínek
838ea02c56 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/
2026-07-06 13:38:59 +02:00
Tomáš Rohlínek
98416b7e13 fix(storage/fatfs): guard dirty-cache refill against unsigned LBA wrap (CVE-2026-6685)
After a direct multi-sector disk_read()/disk_write(), FatFs decides whether the
cached sector overlaps the direct-I/O range with:

    fp->sect - sect < cc          (and the FF_FS_TINY variant fs->winsect - sect < cc)

`sect`, `fp->sect` and `fs->winsect` are unsigned LBA_t. On 32-bit LBA_t builds,
if the cached sector is below `sect`, the subtraction wraps to a huge value that
can still compare `< cc`, so the code computes a bogus large offset:

  - in f_write() it mis-copies from the direct write buffer (data corruption);
  - in f_read() it is worse: memcpy(rbuff + (wrapped_offset * SS), ...) is an
    out-of-bounds WRITE into the caller-supplied read buffer.

Add an explicit lower-bound check (fp->sect >= sect, resp. fs->winsect >= sect)
before the range test on both the read and write paths and both the FF_FS_TINY
and normal variants, so the condition is exactly "cached sector lies within
[sect, sect + cc)". Record the CVE in the component SBOM.

Reference: https://www.runzero.com/blog/fatfs-bugs/
2026-07-06 13:38:29 +02:00
Tomáš Rohlínek
7d73545564 fix(storage/fatfs): reject empty exFAT cluster heap and guard divisor (CVE-2026-6683)
The FAT12/16/32 mount path rejects a zero cluster count, but the exFAT path
accepted NumClusters == 0. That yields fs->n_fatent == 2, and sync_fs() later
computes the "percent in use" field as:

    ... * 100 / (fs->n_fatent - 2)

which is a division by zero (n_fatent - 2 == 0) -> crash. On a device that
syncs during an update this can brick the unit.

Reject ncl == 0 at exFAT mount time, and add a defense-in-depth
`fs->n_fatent > 2` guard around the division in sync_fs() so the divisor can
never be zero even if some future path produces such a filesystem object.
Record the CVE in the component SBOM.

Reference: https://www.runzero.com/blog/fatfs-bugs/
2026-07-06 13:37:59 +02:00
Tomáš Rohlínek
81ec08b949 fix(storage/fatfs): fix exFAT mount integer overflow (CVE-2026-6682)
The exFAT mount path validates that the media is large enough to hold the
declared cluster heap with:

    if (maxlba < (QWORD)fs->database + ncl * fs->csize) ...

`ncl` (DWORD, up to MAX_EXFAT) and `fs->csize` (WORD) are both promoted to
`unsigned int`, so `ncl * fs->csize` is evaluated in 32-bit arithmetic and can
wrap before the QWORD promotion of the sum. A crafted image with a large
NumClusters/SecPerClus can therefore make an undersized volume pass the "size
is large enough" check; subsequent cluster->sector math then addresses media
outside the actual device.

Promote the multiply to 64-bit ((QWORD)ncl * fs->csize). Apply the same
promotion to the bitmap-base computation ((LBA_t)fs->csize * (bcl - 2)), which
has the identical overflow shape. Record the CVE in the component SBOM.

Reference: https://www.runzero.com/blog/fatfs-bugs/
2026-07-06 13:37:28 +02:00
Tomáš Rohlínek
ae0fad3bac fix(storage/fatfs): correct SBOM version to R0.16
The vendored FatFs sources are revision R0.16 (FF_DEFINED == 80386, per
components/fatfs/src/ff.h and ff.c) but the SBOM recorded R0.15. Correct the
recorded version so vulnerability tracking matches the actual sources.
2026-07-06 13:36:59 +02:00
Martin Vychodil
7d515c1e2e Merge branch 'bugfix/idfci-12308-fatfs-bdl-test-stack-overflow' into 'master'
fix(fatfs): avoid stack overflow in BDL diskio partition test

Closes IDFCI-12308

See merge request espressif/esp-idf!49895
2026-06-30 16:58:56 +08:00
Martin Vychodil
caf132aaf0 Merge branch 'bugfix/idfci-8839-remove-orphan-test-configs' into 'master'
fix(fatfs): re-enable fatfs and vfs psram/ccomp CI tests

Closes IDFCI-8839

See merge request espressif/esp-idf!49986
2026-06-30 16:55:51 +08:00
Tomas Rohlinek
dfd2e6b6f7 fatfs: add read_only flag to esp_vfs_fat_mount_config_t 2026-06-26 09:16:26 +02:00
sonika.rathi
28c8a2ec0e fix(fatfs): re-enable fatfs and vfs psram/ccomp CI tests 2026-06-24 14:45:16 +02:00
sonika.rathi
1d08a22a14 fix(fatfs): avoid stack overflow in BDL diskio partition test 2026-06-22 15:22:16 +02:00
sonika.rathi
2820aa64c3 fix(fatfs): normalize fatfs Python tool CLI output 2026-06-22 12:57:33 +02:00
Chen Yudong
df045c2ef6 ci: fix pytest markers 2026-06-15 11:34:48 +08:00
Adam Múdry
1f9c627569 fix(fatfs): Fix esp_vfs_fat_unregister_path leak if esp_vfs_unregister fails 2026-06-11 16:29:25 +02:00
sonika.rathi
d3a8009684 fix(storage): mark storage pytest apps flaky in CI 2026-05-21 20:35:24 +08:00
sonika.rathi
4d9435a5ef fix(fatfs): fix readdir/stat path buffer sizing in test 2026-05-05 12:04:41 +02:00
Martin Vychodil
6c8c76f257 Merge branch 'bugfix/fatfs_memory_leak_with_dyn_buffer' into 'master'
fix(fatfs): fix a memory leak bug when FF_USE_DYN_BUFFER was enabled

Closes IDF-15593

See merge request espressif/esp-idf!47769
2026-04-22 04:33:30 +08:00
LiPeng
a8b5b8d582 fix(fatfs): fix a memory leak bug when FF_USE_DYN_BUFFER was enabled 2026-04-21 11:54:39 +08:00
Adam Múdry
c55b61d99f Merge branch 'fix/python3.14_test_fatfsgen' into 'master'
fix(fatfs): fix operator precedence bug in BootSector.__str__ for Python 3.14 compatibility

Closes IDF-15550

See merge request espressif/esp-idf!47479
2026-04-13 16:08:16 +02:00
Adam Múdry
b29b9dc4d2 Merge branch 'feat/cmake_add_partition_flash_binary_function' into 'master'
feat(esp_partition): Add esp_partition_register_target Cmake function

Closes IDF-11870 and DOC-14244

See merge request espressif/esp-idf!37176
2026-04-13 15:54:27 +02:00
Adam Múdry
749c446a7e feat(esp_partition): Add esp_partition_flash_binary() CMake function
Add a new CMake function esp_partition_flash_binary() that provides a
unified API for registering partition data binaries to be flashed. It
replaces the direct esptool_py_flash_target calls scattered across
components (spiffs, fatfs, nvs_flash) with a single function that:

- Resolves partition offset from the partition table automatically
- Determines encryption requirements (auto-detect or ALWAYS_PLAINTEXT)
- Creates per-partition flash targets (e.g. idf.py <partition>-flash)
- Optionally includes the binary in `idf.py flash` via FLASH_IN_PROJECT

On the linux target, the function registers binaries for pre-loading
into the emulated flash. A build-time manifest (linux_flash_data.txt)
is generated via file(GENERATE), and partition_linux.c reads it at
runtime to copy each binary into the memory-mapped flash buffer at
the correct offset.

The partition_ops example is updated to use the new function and
includes a custom_partition with pre-built data to demonstrate the
full workflow, including on the linux target.
2026-04-10 15:22:50 +02:00
wanckl
99bf74f022 feat(driver_spi): s31 gpspi driver support 2026-04-10 14:22:17 +08:00
Martin Vychodil
a8136c5a20 Merge branch 'fix/fatfsgen-sfn-ascii-numeric-tail' into 'master'
fix(fatfs): fix SFN generation from LFN (numeric tail ASCII encoding, switching to CRC hex numbers to mirror FATFS logic, etc.)

Closes IDF-15479

See merge request espressif/esp-idf!46828
2026-04-09 23:43:58 +08:00
Adam Múdry
5867550fb8 fix(fatfs): fix operator precedence bug in BootSector.__str__ for Python 3.14 compatibility
The condition filtering attributes lacked parentheses, causing the
'not startswith(_)' guard to only apply to str attributes. Python 3.14's
new __firstlineno__ (int) class attribute leaked into the output.

Also includes ruff auto-formatting fixes (imports, trailing commas,
union type annotations).
2026-04-09 15:36:43 +02:00
Adam Múdry
d8c30644c7 fix(fatfs): fix formatting in relevant python files to satisfy pre-commit check 2026-04-09 12:56:30 +02:00
Adam Múdry
1d0d45f203 fix(fatfs): fix a bug in SFN generation from LFN and rewrite to match C algorithm
Rewrite build_lfn_short_entry_name() and add _gen_numname_suffix() helper
to match the gen_numname() algorithm in ff.c. This fixes:

- chr(order) producing raw binary instead of ASCII digits
- Collision for order >= 10 when str(order) makes the name exceed 8 chars
- Hex suffix with dynamic stem shortening (matching C implementation)
- CRC16-CCITT hash for seq > 5 to reduce collision probability

Also fix LDIR_Name2_SIZE typo in long_filename_utils.py (should be
LDIR_Name3_SIZE), which made the assertion guard too permissive.

Add ShortFilenameGenerationTestCase with 9 unit tests covering single-digit,
multi-digit, hash-based, and collision-free generation scenarios.
2026-04-09 12:53:43 +02:00
Martin Vychodil
85ead6f5d4 fix(fatfs): Added tests for FATFS re-registration and VFS adapter early returns 2026-04-07 13:12:54 +02:00
Martin Vychodil
8240eea180 fix(fatfs): Fixed VFS adapter early return paths 2026-04-07 13:12:42 +02:00
Martin Vychodil
26ceedb5f8 fix(fatfs): Fixed uninitialized FATFS pointer for already mounted path 2026-04-07 12:08:49 +02:00
Martin Vychodil
7043fb0d14 feat(fatfs): Added BDL support to FatFS component 2026-04-07 07:11:21 +02:00
jay candel
11c2d1b472 fix(fatfs): correct preprocessor guard for fail label in f_open 2026-03-23 17:53:26 +01:00
sonika.rathi
bcfc900fe1 fix(fatfs): remove incorrect retval description from void ff_mutex_delete 2026-03-17 15:37:18 +01:00
sonika.rathi
5381064130 fix(fatfs): fix f_getfree crash when volume not mounted or mount failed 2026-03-17 15:37:17 +01:00
Evgeny Torbin
d0f062c018 ci: remove unused test cases 2026-03-12 12:02:10 +01:00
Tomáš Rohlínek
96f820e535 feat(storage/fatfs): Allow fatfs buffers to be aligned for DMA access 2026-02-25 12:50:20 +01:00
Tomas Rohlinek
ff2b43f31b Merge branch 'fix/minimize_dependencies' into 'master'
feat(storage): Minimize dependencies for test cases

Closes IDF-15321

See merge request espressif/esp-idf!45832
2026-02-24 16:06:21 +01:00
Tomáš Rohlínek
4575ac1f5e feat(storage): Minimize dependencies for test cases 2026-02-18 13:43:27 +01:00
Adam Múdry
d58b9406d8 fix: Update examples etc. to use esp_vfs_fat_register
Instead of deprecated esp_vfs_fat_register_cfg
2026-02-04 16:33:40 +01:00
Adam Múdry
38256a6b11 refactor(fatfs): Update esp_vfs_fat_register function prototype
to match esp_vfs_fat_register_cfg
2026-02-04 16:33:40 +01:00
Adam Múdry
1e195254e7 fix(fatfs): fatfs test_apps remove esp32c3 from sdcard_sdmode test 2026-01-28 13:42:33 +01:00
Igor Udot
f4cb052666 Merge branch 'ci/base_components' into 'master'
ci: use common_components in depends_components

See merge request espressif/esp-idf!45070
2026-01-26 09:08:11 +08:00
igor.udot
4c26ab876b ci: update build-test-rules to use common_components 2026-01-23 10:14:09 +08:00
Adam Múdry
d989204741 fix(fatfs): Calculate max_pos in wl_fatfsgen.py safe mode correctly 2026-01-22 15:17:36 +01:00
Adam Múdry
5e8a6c0816 fix: Satisfy Python formatter 2026-01-22 15:11:17 +01:00
Tomáš Rohlínek
8c9d62de98 feat(storage/vfs): Remove old API usage 2025-12-16 17:48:55 +08:00
C.S.M
f405e51784 ci(esp32s31): Add ci build test for esp32s31 2025-12-11 15:17:15 +08:00
sonika.rathi
075417de1a fix(fatfs): In vfs_fat_* calls, add _lock_acquire in missing places 2025-11-27 15:24:29 +01:00
Sonika Rathi
7fb2f80fe0 Merge branch 'feat/vfs_linux' into 'master'
feat(vfs): Add support for linux target in VFS

See merge request espressif/esp-idf!39524
2025-11-27 22:12:06 +08:00