embedded-sdmmc-rs: u32 overflow in finding fat_offset from cluster

I only have this message from a device deployed in the field. It seems to crash on:
let fat_offset = cluster.0 * 4;
where everything involved is u32s.
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 30 (19 by maintainers)
Commits related to this issue
- Fix issue #74 Map ROOT_DIR (0xFFFF_FFFC) to an actual cluster number, so if you go off the end of the first cluster of the root directory on FAT32, the code no longer crashes trying to convert the RO... — committed to rust-embedded-community/embedded-sdmmc-rs by thejpster 6 months ago
- Fix issue #74 Map ROOT_DIR (0xFFFF_FFFC) to an actual cluster number, so if you go off the end of the first cluster of the root directory on FAT32, the code no longer crashes trying to convert the RO... — committed to rust-embedded-community/embedded-sdmmc-rs by thejpster 6 months ago
Also, note that any directory operation involves a linear directory walk, so ideally you shouldn’t have too many files in one directory. Perhaps create
/0/1/2/0012345.dator something.OK, that all seems normal. I’ll try your example and see what is going wrong - perhaps it’s a bug when the root directory takes up more than one cluster?
big_dir.rs:Hey, I love a reproducer. Thanks! Let’s add an explicit check and look at a backtrace.
OK, so the problem is that FAT32 doesn’t live in a fixed place - the location is given by some metadata. So when you open the root directory, the directory holds the value
0xFFFF_FFFC. There was a bug in thewrite_new_directory_entryfunction where it would map that value to the real block on disk for the purposes of loading directory blocks, but it didn’t update the cluster number. So, when it went to find the next cluster it was trying to find the next cluster after0xFFFF_FFFC, which obviously isn’t a valid cluster number.The patch is pretty simple: