From b5d9bfe34e62cf1c57646efa0bd72ecad7d98258 Mon Sep 17 00:00:00 2001 From: Nate Clark Date: Wed, 4 Jan 2017 15:24:32 -0500 Subject: [PATCH 176/176] libblkid/minix: Use same checks for version 3 fsck.minix performs the same sanity checks on all versions of the superblock. Update the probe to perform the same sanity checks so it is less likely a different type of filesystem will be identified as minix. Upstream: http://github.com/karelzak/util-linux/commit/f82c804869bb8613fa0924e3111b7eb55bb04fcd Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1594681 Signed-off-by: Nate Clark Signed-off-by: Karel Zak --- libblkid/src/superblocks/minix.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/libblkid/src/superblocks/minix.c b/libblkid/src/superblocks/minix.c index 4e70fda8f..21b3bf8bb 100644 --- a/libblkid/src/superblocks/minix.c +++ b/libblkid/src/superblocks/minix.c @@ -75,6 +75,9 @@ static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) unsigned char *ext; const unsigned char *data; int version = 0, swabme = 0; + unsigned long zones, ninodes, imaps, zmaps; + off_t firstz; + size_t zone_size; data = blkid_probe_get_buffer(pr, 1024, max(sizeof(struct minix_super_block), @@ -85,14 +88,9 @@ static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) if (version < 1) return 1; + if (version <= 2) { struct minix_super_block *sb = (struct minix_super_block *) data; - unsigned long zones, ninodes, imaps, zmaps; - off_t firstz; - - if (sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) - return 1; - uint16_t state = minix_swab16(swabme, sb->s_state); if ((state & (MINIX_VALID_FS | MINIX_ERROR_FS)) != state) return 1; @@ -103,20 +101,30 @@ static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag) imaps = minix_swab16(swabme, sb->s_imap_blocks); zmaps = minix_swab16(swabme, sb->s_zmap_blocks); firstz = minix_swab16(swabme, sb->s_firstdatazone); - - /* sanity checks to be sure that the FS is really minix */ - if (imaps * MINIX_BLOCK_SIZE * 8 < ninodes + 1) - return 1; - if (zmaps * MINIX_BLOCK_SIZE * 8 < zones - firstz + 1) - return 1; - + zone_size = sb->s_log_zone_size; } else if (version == 3) { struct minix3_super_block *sb = (struct minix3_super_block *) data; - if (sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0) - return 1; + zones = minix_swab32(swabme, sb->s_zones); + ninodes = minix_swab32(swabme, sb->s_ninodes); + imaps = minix_swab16(swabme, sb->s_imap_blocks); + zmaps = minix_swab16(swabme, sb->s_zmap_blocks); + firstz = minix_swab16(swabme, sb->s_firstdatazone); + zone_size = sb->s_log_zone_size; } + /* sanity checks to be sure that the FS is really minix. + * see disk-utils/fsck.minix.c read_superblock + */ + if (zone_size != 0 || ninodes == 0 || ninodes == UINT32_MAX) + return 1; + if (imaps * MINIX_BLOCK_SIZE * 8 < ninodes + 1) + return 1; + if (firstz > (off_t) zones) + return 1; + if (zmaps * MINIX_BLOCK_SIZE * 8 < zones - firstz + 1) + return 1; + /* unfortunately, some parts of ext3 is sometimes possible to * interpreted as minix superblock. So check for extN magic * string. (For extN magic string and offsets see ext.c.) -- 2.14.4