:: commit 5b1cd9d01b2c013e628aaa23ce1d6bb35c4f1530

mintsuki <mintsuki@protonmail.com> — 2024-05-22 02:44

parents: 59ac73d753

fs/fat: Address missing bpb validity checks. Fixes #351 and #352

diff --git a/common/fs/fat32.s2.c b/common/fs/fat32.s2.c
index 903984b0..c01904b4 100644
--- a/common/fs/fat32.s2.c
+++ b/common/fs/fat32.s2.c
@@ -104,24 +104,49 @@ static int fat32_init_context(struct fat32_context* context, struct volume *part
     struct fat32_bpb bpb;
     volume_read(context->part, &bpb, 0, sizeof(struct fat32_bpb));
 
+    // Sanity check of bpb
+
     // Checks for FAT12/16
     if (strncmp((((void *)&bpb) + 0x36), "FAT", 3) == 0) {
-        goto valid;
+        goto signature_valid;
     }
 
     // Checks for FAT32
     if (strncmp((((void *)&bpb) + 0x52), "FAT", 3) == 0) {
-        goto valid;
+        goto signature_valid;
     }
 
     // Checks for FAT32 (with 64-bit sector count)
     if (strncmp((((void *)&bpb) + 0x03), "FAT32", 5) == 0) {
-        goto valid;
+        goto signature_valid;
+    }
+
+    return 1;
+
+signature_valid:;
+
+    const uint8_t sector_per_cluster_valid_values[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+    for (size_t i = 0; i < SIZEOF_ARRAY(sector_per_cluster_valid_values); i++) {
+        if (bpb.sectors_per_cluster == sector_per_cluster_valid_values[i]) {
+            goto sector_per_cluster_valid;
+        }
     }
 
     return 1;
 
-valid:;
+sector_per_cluster_valid:;
+
+    const uint16_t bytes_per_sector_valid_values[] = { 512, 1024, 2048, 4096 };
+    for (size_t i = 0; i < SIZEOF_ARRAY(bytes_per_sector_valid_values); i++) {
+        if (bpb.bytes_per_sector == bytes_per_sector_valid_values[i]) {
+            goto bytes_per_sector_valid;
+        }
+    }
+
+    return 1;
+
+bytes_per_sector_valid:;
+
     // The following mess to identify the FAT type is from the FAT spec
     // at paragraph 3.5
     size_t root_dir_sects = ((bpb.root_entries_count * 32) + (bpb.bytes_per_sector - 1)) / bpb.bytes_per_sector;
tab: 248 wrap: offon