diff --git a/ChangeLog b/ChangeLog index e68cc9d80..ab1f39e0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2012-05-12 Vladimir Serbinenko + + * grub-core/fs/bfs.c (mount): Improve filesystem detection reliability. + * grub-core/fs/ext2.c (grub_ext2_mount): Likewise. + * grub-core/fs/hfs.c (grub_hfs_mount): Likewise. + * grub-core/fs/hfsplus.c (grub_hfsplus_mount): Likewise. + * grub-core/fs/jfs.c (grub_jfs_mount): Likewise. + * grub-core/fs/minix.c (grub_minix_mount): Likewise. + * grub-core/fs/ntfs.c (grub_ntfs_mount): Likewise. + * grub-core/fs/romfs.c (grub_romfs_mount): Likewise. + * grub-core/fs/xfs.c (grub_xfs_mount): Likewise. + 2012-05-11 Vladimir Serbinenko Use grub-probe and not cmp to check that disk is empty. diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c index 1d3b562b6..41a5557f9 100644 --- a/grub-core/fs/bfs.c +++ b/grub-core/fs/bfs.c @@ -43,6 +43,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); #define grub_bfs_to_cpu16 grub_le_to_cpu16 #define grub_bfs_to_cpu32 grub_le_to_cpu32 #define grub_bfs_to_cpu64 grub_le_to_cpu64 +#define grub_cpu_to_bfs32_compile_time grub_cpu_to_le32_compile_time #ifdef MODE_AFS #define grub_bfs_to_cpu_treehead grub_bfs_to_cpu32 @@ -818,11 +819,13 @@ mount (grub_disk_t disk, struct grub_bfs_superblock *sb) ); if (err) return err; - if (grub_bfs_to_cpu32 (sb->magic1) != SUPER_BLOCK_MAGIC1 - || grub_bfs_to_cpu32 (sb->magic2) != SUPER_BLOCK_MAGIC2 - || grub_bfs_to_cpu32 (sb->magic3) != SUPER_BLOCK_MAGIC3 + if (sb->magic1 != grub_cpu_to_bfs32_compile_time (SUPER_BLOCK_MAGIC1) + || sb->magic2 != grub_cpu_to_bfs32_compile_time (SUPER_BLOCK_MAGIC2) + || sb->magic3 != grub_cpu_to_bfs32_compile_time (SUPER_BLOCK_MAGIC3) + || sb->bsize == 0 || (grub_bfs_to_cpu32 (sb->bsize) - != (1U << grub_bfs_to_cpu32 (sb->log2_bsize)))) + != (1U << grub_bfs_to_cpu32 (sb->log2_bsize))) + || grub_bfs_to_cpu32 (sb->log2_bsize) < GRUB_DISK_SECTOR_BITS) return grub_error (GRUB_ERR_BAD_FS, #ifdef MODE_AFS "not an AFS filesystem" diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c index e337bebf2..c50e379d6 100644 --- a/grub-core/fs/ext2.c +++ b/grub-core/fs/ext2.c @@ -578,7 +578,8 @@ grub_ext2_mount (grub_disk_t disk) goto fail; /* Make sure this is an ext2 filesystem. */ - if (grub_le_to_cpu16 (data->sblock.magic) != EXT2_MAGIC) + if (grub_le_to_cpu16 (data->sblock.magic) != EXT2_MAGIC + || grub_le_to_cpu32 (data->sblock.log2_block_size) >= 16) { grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem"); goto fail; diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c index 890cdacbe..782329588 100644 --- a/grub-core/fs/hfs.c +++ b/grub-core/fs/hfs.c @@ -328,7 +328,8 @@ grub_hfs_mount (grub_disk_t disk) goto fail; /* Check if this is a HFS filesystem. */ - if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC) + if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC + || (data->sblock.blksz & grub_cpu_to_be32_compile_time (0xc00001ff))) { grub_error (GRUB_ERR_BAD_FS, "not an HFS filesystem"); goto fail; diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c index 8066c117d..410f0b4ff 100644 --- a/grub-core/fs/hfsplus.c +++ b/grub-core/fs/hfsplus.c @@ -439,18 +439,21 @@ grub_hfsplus_mount (grub_disk_t disk) /* Make sure this is an HFS+ filesystem. XXX: Do we really support HFX? */ magic = grub_be_to_cpu16 (volheader.hfsplus.magic); - if ((magic != GRUB_HFSPLUS_MAGIC) && (magic != GRUB_HFSPLUSX_MAGIC)) + if (((magic != GRUB_HFSPLUS_MAGIC) && (magic != GRUB_HFSPLUSX_MAGIC)) + || volheader.hfsplus.blksize == 0 + || ((volheader.hfsplus.blksize & (volheader.hfsplus.blksize - 1)) != 0) + || grub_be_to_cpu32 (volheader.hfsplus.blksize) < GRUB_DISK_SECTOR_SIZE) { grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); goto fail; } grub_memcpy (&data->volheader, &volheader.hfsplus, - sizeof (volheader.hfsplus)); + sizeof (volheader.hfsplus)); - if (grub_fshelp_log2blksize (grub_be_to_cpu32 (data->volheader.blksize), - &data->log2blksize)) - goto fail; + for (data->log2blksize = 0; + (1U << data->log2blksize) < grub_be_to_cpu32 (data->volheader.blksize); + data->log2blksize++); /* Make a new node for the catalog tree. */ data->catalog_tree.file.data = data; diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c index 470afd1be..d3de33901 100644 --- a/grub-core/fs/jfs.c +++ b/grub-core/fs/jfs.c @@ -366,8 +366,10 @@ grub_jfs_mount (grub_disk_t disk) goto fail; } - if (grub_le_to_cpu32 (data->sblock.blksz) - != (1U << grub_le_to_cpu16 (data->sblock.log2_blksz))) + if (data->sblock.blksz == 0 + || grub_le_to_cpu32 (data->sblock.blksz) + != (1U << grub_le_to_cpu16 (data->sblock.log2_blksz)) + || grub_le_to_cpu16 (data->sblock.log2_blksz) < GRUB_DISK_SECTOR_BITS) { grub_error (GRUB_ERR_BAD_FS, "not a JFS filesystem"); goto fail; diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c index a1b91addb..1e1c13b56 100644 --- a/grub-core/fs/minix.c +++ b/grub-core/fs/minix.c @@ -483,9 +483,9 @@ grub_minix_mount (grub_disk_t disk) if (data->sblock.magic == grub_cpu_to_minix16_compile_time (GRUB_MINIX_MAGIC)) { #if !defined(MODE_MINIX3) - data->filename_size = 14; + data->filename_size = 14; #else - data->filename_size = 60; + data->filename_size = 60; #endif } #if !defined(MODE_MINIX3) @@ -496,6 +496,11 @@ grub_minix_mount (grub_disk_t disk) else goto fail; + /* 20 means 1G zones. We could support up to 31 but already 1G isn't + supported by anything else. */ + if (grub_minix_to_cpu16 (data->sblock.log2_zone_size) >= 20) + goto fail; + data->disk = disk; data->linknest = 0; #ifdef MODE_MINIX3 diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c index aaa7b2df9..1e0885cc7 100644 --- a/grub-core/fs/ntfs.c +++ b/grub-core/fs/ntfs.c @@ -945,12 +945,18 @@ grub_ntfs_mount (grub_disk_t disk) if (grub_disk_read (disk, 0, 0, sizeof (bpb), &bpb)) goto fail; - if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4)) + if (grub_memcmp ((char *) &bpb.oem_name, "NTFS", 4) != 0 + || bpb.sectors_per_cluster == 0 + || (bpb.sectors_per_cluster & (bpb.sectors_per_cluster - 1)) != 0 + || bpb.bytes_per_sector == 0 + || (bpb.bytes_per_sector & (bpb.bytes_per_sector - 1)) != 0) goto fail; data->spc = (((grub_uint32_t) bpb.sectors_per_cluster * (grub_uint32_t) grub_le_to_cpu16 (bpb.bytes_per_sector)) >> GRUB_NTFS_BLK_SHR); + if (!data->spc) + goto fail; if (bpb.clusters_per_mft > 0) data->mft_size = data->spc * bpb.clusters_per_mft; diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c index c32ae9e55..b30caef35 100644 --- a/grub-core/fs/romfs.c +++ b/grub-core/fs/romfs.c @@ -107,10 +107,19 @@ grub_romfs_mount (grub_device_t dev) grub_error (GRUB_ERR_BAD_FS, "too short filesystem"); return NULL; } + if (grub_memcmp (sb.sb.magic, GRUB_ROMFS_MAGIC, + sizeof (sb.sb.magic)) != 0) + { + grub_error (GRUB_ERR_BAD_FS, "not romfs"); + return NULL; + } err = do_checksum (&sb, sizeof (sb) < grub_be_to_cpu32 (sb.sb.total_size) ? sizeof (sb) : grub_be_to_cpu32 (sb.sb.total_size)); if (err) - return NULL; + { + grub_error (GRUB_ERR_BAD_FS, "checksum incorrect"); + return NULL; + } for (ptr = sb.sb.label; (void *) ptr < (void *) (&sb + 1) && ptr - sb.d < (grub_ssize_t) grub_be_to_cpu32 (sb.sb.total_size); ptr++) if (!*ptr) diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c index 9e68ea8c4..2c6b00c2a 100644 --- a/grub-core/fs/xfs.c +++ b/grub-core/fs/xfs.c @@ -663,7 +663,10 @@ grub_xfs_mount (grub_disk_t disk) sizeof (struct grub_xfs_sblock), &data->sblock)) goto fail; - if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)) + if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4) + || data->sblock.log2_bsize < GRUB_DISK_SECTOR_BITS + || ((int) data->sblock.log2_bsize + + (int) data->sblock.log2_dirblk) >= 27) { grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem"); goto fail;