Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly repair filesystems with corrupted 3 byte headers, unrecognized by Windows? #185

Open
nyanpasu64 opened this issue Dec 5, 2022 · 1 comment

Comments

@nyanpasu64
Copy link

libparted 3.2 (2014) had a bug (bug report) which would corrupt FAT32 filesystem/partitions' first 3 bytes when resizing them. This bug was fixed in 2016 and a patched libparted made its way to GParted Live, but some distributions did not get the fix until libparted 3.3 released in 2019, a years-long downstream patch gap. The bad libparted produced corrupted FAT32 filesystems for multiple people in the wild (including myself).

Corrupted filesystems can still be mounted fine on Linux, because util-linux has multiple magic numbers for recognizing FAT32 (see https://github.com/util-linux/util-linux/blob/master/libblkid/src/superblocks/vfat.c#L443-L461), including EB and E9 for the first byte, and "FAT32 " and other strings at 0x52 or (for FAT12/16) at 0x36. However, on Windows, when the first byte of the filesystem is not EB or E9 (I know 00 and some randomly corrupted values fail, didn't test others systematically), Windows doesn't recognize FAT32 and instead prompts to format the disk.

To fix the corruption, the bug report recommends replacing the first 3 bytes with EB 58 90, which matches the default FAT32 header written by GNOME Disks and Windows (and not modified by Offline NT's syslinux installation). Oddly TestDisk's "Rebuild BS" option instead writes EB 3C 90 and a shorter boot sector metadata (I suspect this is standard for FAT12/16 rather than FAT32).

Unfortunately, fsck.vfat on Linux does not currently fix corrupted filesystem headers, leaving the disks unreadable on Windows. Currently it doesn't check the first 3 bytes bytes are valid, and so doesn't detect any errors on corrupted filesystems. I think fsck.vfat should verify that the first byte is EB (a one-byte relative jump) and the third is 90 (not sure if you should validate the second, it's executable x86 code, but who even executes a FAT32 boot sector nowadays?), or the first byte is E9 (a two-byte relative jump, but I don't know what writes this, I know syslinux doesn't). And if not, offer to replace the 3 bytes with EB 58 90 for FAT32 filesystems, or EB 3C 90 for FAT≤16 filesystems.

@pali
Copy link
Member

pali commented Dec 5, 2022

However, on Windows, when the first byte of the filesystem is not EB or E9 (I know 00 and some randomly corrupted values fail, didn't test others systematically), Windows doesn't recognize FAT32 and instead prompts to format the disk.

It can be also 0x49. Source code of MS fastfat.sys driver is available on github. Look for function FatIsBootSectorFat:
https://github.com/microsoft/Windows-driver-samples/blob/main/filesys/fastfat/fsctrl.c

And it makes sense to check & repair the first byte of FAT when fsck is not running in Atari mode (-A).

Patches with tests are welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants