Explorar o código

fix(fat32): validate the cluster no, treating 0, 1 as EOC

greatbridf hai 7 meses
pai
achega
a6b8a3c8c3
Modificáronse 2 ficheiros con 17 adicións e 10 borrados
  1. 16 9
      src/fs/fat32.rs
  2. 1 1
      src/fs/fat32/dir.rs

+ 16 - 9
src/fs/fat32.rs

@@ -174,7 +174,12 @@ impl FatFs {
 
         let root_dir_cluster_count = ClusterIterator::new(fat, fatfs.rootdir_cluster).count();
         let root_dir_size = root_dir_cluster_count as u32 * info.sectors_per_cluster as u32 * 512;
-        let root_inode = DirInode::new(info.root_cluster as Ino, fatfs.weak.clone(), root_dir_size);
+
+        let root_inode = DirInode::new(
+            (info.root_cluster & !0xF000_0000) as Ino,
+            fatfs.weak.clone(),
+            root_dir_size,
+        );
 
         Ok((fatfs_arc, root_inode))
     }
@@ -195,14 +200,16 @@ impl<'fat> Iterator for ClusterIterator<'fat> {
     type Item = ClusterNo;
 
     fn next(&mut self) -> Option<Self::Item> {
-        const EOC: ClusterNo = 0x0FFFFFF8;
-        let next = self.cur;
-
-        if next >= EOC {
-            None
-        } else {
-            self.cur = self.fat[next as usize];
-            Some(next)
+        const EOC: ClusterNo = 0x0FFF_FFF8;
+        const INVL: ClusterNo = 0xF000_0000;
+
+        match self.cur {
+            ..2 | EOC..INVL => None,
+            INVL.. => unreachable!("Invalid cluster number: {}", self.cur),
+            next => {
+                self.cur = self.fat[next as usize] & !INVL;
+                Some(next)
+            }
         }
     }
 }

+ 1 - 1
src/fs/fat32/dir.rs

@@ -232,7 +232,7 @@ where
             size: entry.size,
             entry_offset,
             filename,
-            cluster: entry.cluster_low as u32 | ((entry.cluster_high as u32) << 16),
+            cluster: entry.cluster_low as u32 | (((entry.cluster_high & !0xF000) as u32) << 16),
             is_directory: entry.is_directory(),
         }))
     }