diff --git a/components/fatfs/sbom.yml b/components/fatfs/sbom.yml index e53b73b46ec..d0ae5b6b4f2 100644 --- a/components/fatfs/sbom.yml +++ b/components/fatfs/sbom.yml @@ -5,7 +5,7 @@ originator: 'Person: ChaN' description: 'Generic FAT Filesystem Module for embedded systems.' cve-exclude-list: - cve: CVE-2026-6682 - reason: Integer overflow in exFAT mount size validation. Patched by promoting the cluster-heap and bitmap-base multiplies to 64-bit in mount_volume(). + reason: FAT32 integer overflow in mount_volume(). Patched by rejecting per-FAT and system-area sizes that overflow the 32-bit multiply before use; the exFAT cluster-heap/bitmap multiplies were additionally widened to 64-bit as defense-in-depth. - cve: CVE-2026-6683 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 diff --git a/components/fatfs/src/ff.c b/components/fatfs/src/ff.c index c6967662b1c..9384e6c5ffe 100644 --- a/components/fatfs/src/ff.c +++ b/components/fatfs/src/ff.c @@ -3481,7 +3481,7 @@ static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */ fs->volbase = bsect; fs->database = bsect + ld_dword(fs->win + BPB_DataOfsEx); fs->fatbase = bsect + ld_dword(fs->win + BPB_FatOfsEx); - if (maxlba < (QWORD)fs->database + (QWORD)nclst * fs->csize) return FR_NO_FILESYSTEM; /* CVE-2026-6682: promote to 64-bit before multiply to avoid integer overflow that would accept an undersized volume */ + if (maxlba < (QWORD)fs->database + (QWORD)nclst * fs->csize) return FR_NO_FILESYSTEM; /* exFAT mount hardening (defense-in-depth): promote to 64-bit before multiply to avoid integer overflow that would accept an undersized volume */ fs->dirbase = ld_dword(fs->win + BPB_RootClusEx); /* Get bitmap location and check if it is contiguous (implementation assumption) */ @@ -3497,7 +3497,7 @@ static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */ } bcl = ld_dword(fs->win + i + 20); /* Bitmap cluster */ if (bcl < 2 || bcl >= fs->n_fatent) return FR_NO_FILESYSTEM; /* (Wrong cluster#) */ - fs->bitbase = fs->database + (LBA_t)fs->csize * (bcl - 2); /* Bitmap sector (CVE-2026-6682: 64-bit multiply to avoid overflow) */ + fs->bitbase = fs->database + (LBA_t)fs->csize * (bcl - 2); /* Bitmap sector (exFAT mount hardening: 64-bit multiply to avoid overflow) */ for (;;) { /* Check if bitmap is contiguous */ if (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR; cv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4); @@ -3520,6 +3520,7 @@ static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */ fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FATs */ if (fs->n_fats != 1 && fs->n_fats != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ + if (fs->n_fats == 2 && fasize > 0xFFFFFFFF / 2) return FR_NO_FILESYSTEM; /* CVE-2026-6682: reject a per-FAT size that overflows DWORD when multiplied by the FAT count; a wrapped (too-small) fasize would move the data area into the FAT region and let a crafted image forge a directory entry with an attacker-controlled file size */ fasize *= fs->n_fats; /* Number of sectors for FAT area */ fs->csize = fs->win[BPB_SecPerClus]; /* Cluster size */ @@ -3536,6 +3537,7 @@ static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */ /* Determine the FAT sub type */ sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZDIRE); /* RSV + FAT + FF_DIR */ + if (sysect < fasize) return FR_NO_FILESYSTEM; /* CVE-2026-6682: reject reserved+FAT+root system-area size that overflows DWORD (same data-area displacement as the FAT-count overflow above) */ if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ if (nclst == 0) return FR_NO_FILESYSTEM; /* (Invalid volume size) */