fstyp: search for file system headers with the largest offset first
fstyp can misidentify a UFS file system as MS-DOS if the device was
repurposed from MS-DOS to UFS via newfs.
This happens for the following reasons:
- the header for MS-DOS begins at offset 0
- the superblock for UFS begins at offset 64k, 8k, 0k, or 256k
- newfs does not clear the area in front of UFS's superblock,
leaving the MS-DOS header intact.
- fstyp searches for file system headers alphabetically
To avoid this misidentification, have fstyp search for file system
headers with the largest offset first instead of alphabetically.
The implemented fix was suggested by reporter, Richard M. Kreuter.
PR: 252787
Reviewed by: imp, emaste
Differential Revision: https://reviews.freebsd.org/D47855
This commit is contained in:
+40
-10
@@ -54,25 +54,55 @@ bool show_label = false;
|
|||||||
|
|
||||||
typedef int (*fstyp_function)(FILE *, char *, size_t);
|
typedef int (*fstyp_function)(FILE *, char *, size_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ordering of fstypes[] is not arbitrary.
|
||||||
|
*
|
||||||
|
* fstyp checks the existence of a file system header to determine the
|
||||||
|
* type of file system on a given device. For different file systems,
|
||||||
|
* these headers reside at different offsets within the device.
|
||||||
|
*
|
||||||
|
* For example, the header for an MS-DOS file system begins at offset 0,
|
||||||
|
* whereas a header for UFS *normally* begins at offset 64k. If a device
|
||||||
|
* was constructed as MS-DOS and then repurposed as UFS (via newfs), it
|
||||||
|
* is possible the MS-DOS header will still be intact. To prevent
|
||||||
|
* misidentifying the file system, it is desirable to check the header
|
||||||
|
* with the largest offset first (i.e., UFS before MS-DOS).
|
||||||
|
*/
|
||||||
static struct {
|
static struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
fstyp_function function;
|
fstyp_function function;
|
||||||
bool unmountable;
|
bool unmountable;
|
||||||
const char *precache_encoding;
|
const char *precache_encoding;
|
||||||
} fstypes[] = {
|
} fstypes[] = {
|
||||||
{ "apfs", &fstyp_apfs, true, NULL },
|
/* last sector of geli device */
|
||||||
{ "befs", &fstyp_befs, false, NULL },
|
|
||||||
{ "cd9660", &fstyp_cd9660, false, NULL },
|
|
||||||
{ "exfat", &fstyp_exfat, false, EXFAT_ENC },
|
|
||||||
{ "ext2fs", &fstyp_ext2fs, false, NULL },
|
|
||||||
{ "geli", &fstyp_geli, true, NULL },
|
{ "geli", &fstyp_geli, true, NULL },
|
||||||
{ "hammer", &fstyp_hammer, true, NULL },
|
/*
|
||||||
{ "hammer2", &fstyp_hammer2, true, NULL },
|
* ufs headers have four different areas, searched in this order:
|
||||||
{ "hfs+", &fstyp_hfsp, false, NULL },
|
* offsets: 64k, 8k, 0k, 256k + 8192 bytes
|
||||||
{ "msdosfs", &fstyp_msdosfs, false, NULL },
|
*/
|
||||||
{ "ntfs", &fstyp_ntfs, false, NTFS_ENC },
|
|
||||||
{ "ufs", &fstyp_ufs, false, NULL },
|
{ "ufs", &fstyp_ufs, false, NULL },
|
||||||
|
/* offset 32768 + 512 bytes */
|
||||||
|
{ "cd9660", &fstyp_cd9660, false, NULL },
|
||||||
|
/* offset 1024 + 512 bytes */
|
||||||
|
{ "hfs+", &fstyp_hfsp, false, NULL },
|
||||||
|
/* offset 1024 + 512 bytes */
|
||||||
|
{ "ext2fs", &fstyp_ext2fs, false, NULL },
|
||||||
|
/* offset 512 + 36 bytes */
|
||||||
|
{ "befs", &fstyp_befs, false, NULL },
|
||||||
|
/* offset 0 + 40 bytes */
|
||||||
|
{ "apfs", &fstyp_apfs, true, NULL },
|
||||||
|
/* offset 0 + 512 bytes (for initial signature check) */
|
||||||
|
{ "exfat", &fstyp_exfat, false, EXFAT_ENC },
|
||||||
|
/* offset 0 + 1928 bytes */
|
||||||
|
{ "hammer", &fstyp_hammer, true, NULL },
|
||||||
|
/* offset 0 + 65536 bytes (for initial signature check) */
|
||||||
|
{ "hammer2", &fstyp_hammer2, true, NULL },
|
||||||
|
/* offset 0 + 512 bytes (for initial signature check) */
|
||||||
|
{ "msdosfs", &fstyp_msdosfs, false, NULL },
|
||||||
|
/* offset 0 + 512 bytes (for initial signature check) */
|
||||||
|
{ "ntfs", &fstyp_ntfs, false, NTFS_ENC },
|
||||||
#ifdef HAVE_ZFS
|
#ifdef HAVE_ZFS
|
||||||
|
/* offset 0 + 256k */
|
||||||
{ "zfs", &fstyp_zfs, true, NULL },
|
{ "zfs", &fstyp_zfs, true, NULL },
|
||||||
#endif
|
#endif
|
||||||
{ NULL, NULL, NULL, NULL }
|
{ NULL, NULL, NULL, NULL }
|
||||||
|
|||||||
Reference in New Issue
Block a user