Blame SOURCES/bz1616389-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise.patch

744fcf
commit 1a4581c3f54b5c794da6537789eeab298b78e031
744fcf
Author: Andrew Price <anprice@redhat.com>
744fcf
Date:   Fri Aug 17 12:49:24 2018 +0100
744fcf
744fcf
    fsck.gfs2: Don't check fs formats we don't recognise
744fcf
    
744fcf
    Currently fsck.gfs2 will ignore sb_fs_format but in order to support
744fcf
    future formats we need to make sure it doesn't try to check filesystems
744fcf
    with formats we don't recognise yet. Better late than never.
744fcf
    
744fcf
    Tests included.
744fcf
    
744fcf
    rhbz#1616389
744fcf
    rhbz#1622050
744fcf
    
744fcf
    Signed-off-by: Andrew Price <anprice@redhat.com>
744fcf
744fcf
diff --git a/gfs2/fsck/fsck.h b/gfs2/fsck/fsck.h
744fcf
index 8af4eb41..db173c67 100644
744fcf
--- a/gfs2/fsck/fsck.h
744fcf
+++ b/gfs2/fsck/fsck.h
744fcf
@@ -4,6 +4,8 @@
744fcf
 #include "libgfs2.h"
744fcf
 #include "osi_tree.h"
744fcf
 
744fcf
+#define FSCK_MAX_FORMAT (1801)
744fcf
+
744fcf
 #define FSCK_HASH_SHIFT         (13)
744fcf
 #define FSCK_HASH_SIZE          (1 << FSCK_HASH_SHIFT)
744fcf
 #define FSCK_HASH_MASK          (FSCK_HASH_SIZE - 1)
744fcf
diff --git a/gfs2/fsck/initialize.c b/gfs2/fsck/initialize.c
744fcf
index 75f050b5..4e323ffa 100644
744fcf
--- a/gfs2/fsck/initialize.c
744fcf
+++ b/gfs2/fsck/initialize.c
744fcf
@@ -1332,12 +1332,12 @@ static int fill_super_block(struct gfs2_sbd *sdp)
744fcf
 	if (sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize){
744fcf
 		log_crit( _("GFS superblock is larger than the blocksize!\n"));
744fcf
 		log_debug("sizeof(struct gfs2_sb) > sdp->sd_sb.sb_bsize\n");
744fcf
-		return -1;
744fcf
+		return FSCK_ERROR;
744fcf
 	}
744fcf
 
744fcf
 	if (compute_constants(sdp)) {
744fcf
 		log_crit("%s\n", _("Failed to compute file system constants"));
744fcf
-		exit(FSCK_ERROR);
744fcf
+		return FSCK_ERROR;
744fcf
 	}
744fcf
 	ret = read_sb(sdp);
744fcf
 	if (ret < 0) {
744fcf
@@ -1346,10 +1346,15 @@ static int fill_super_block(struct gfs2_sbd *sdp)
744fcf
 		/* Now that we've tried to repair it, re-read it. */
744fcf
 		ret = read_sb(sdp);
744fcf
 		if (ret < 0)
744fcf
-			return -1;
744fcf
+			return FSCK_ERROR;
744fcf
 	}
744fcf
 	if (sdp->gfs1)
744fcf
 		sbd1 = (struct gfs_sb *)&sdp->sd_sb;
744fcf
+	else if (sdp->sd_sb.sb_fs_format > FSCK_MAX_FORMAT) {
744fcf
+		log_crit(_("Unsupported gfs2 format found: %"PRIu32"\n"), sdp->sd_sb.sb_fs_format);
744fcf
+		log_crit(_("A newer fsck.gfs2 is required to check this file system.\n"));
744fcf
+		return FSCK_USAGE;
744fcf
+	}
744fcf
 	return 0;
744fcf
 }
744fcf
 
744fcf
@@ -1554,6 +1559,7 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
744fcf
 	       int *all_clean)
744fcf
 {
744fcf
 	int clean_journals = 0, open_flag;
744fcf
+	int err;
744fcf
 
744fcf
 	*all_clean = 0;
744fcf
 
744fcf
@@ -1599,8 +1605,9 @@ int initialize(struct gfs2_sbd *sdp, int force_check, int preen,
744fcf
 	}
744fcf
 
744fcf
 	/* read in sb from disk */
744fcf
-	if (fill_super_block(sdp))
744fcf
-		return FSCK_ERROR;
744fcf
+	err = fill_super_block(sdp);
744fcf
+	if (err != FSCK_OK)
744fcf
+		return err;
744fcf
 
744fcf
 	/* Change lock protocol to be fsck_* instead of lock_* */
744fcf
 	if (!opts.no && preen_is_safe(sdp, preen, force_check)) {
744fcf
diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
744fcf
index 61752031..cc9679f5 100644
744fcf
--- a/gfs2/libgfs2/super.c
744fcf
+++ b/gfs2/libgfs2/super.c
744fcf
@@ -29,11 +29,18 @@ int check_sb(struct gfs2_sb *sb)
744fcf
 		errno = EIO;
744fcf
 		return -1;
744fcf
 	}
744fcf
+	/* Check for gfs1 */
744fcf
 	if (sb->sb_fs_format == GFS_FORMAT_FS &&
744fcf
 	    sb->sb_header.mh_format == GFS_FORMAT_SB &&
744fcf
 	    sb->sb_multihost_format == GFS_FORMAT_MULTI) {
744fcf
 		return 1;
744fcf
 	}
744fcf
+	/* It's gfs2. Check format number is in a sensible range. */
744fcf
+	if (sb->sb_fs_format < GFS2_FORMAT_FS ||
744fcf
+	    sb->sb_fs_format > 1899) {
744fcf
+		errno = EINVAL;
744fcf
+		return -1;
744fcf
+	}
744fcf
 	return 2;
744fcf
 }
744fcf
 
744fcf
diff --git a/tests/fsck.at b/tests/fsck.at
744fcf
index 0dfeac33..d3cf3dbb 100644
744fcf
--- a/tests/fsck.at
744fcf
+++ b/tests/fsck.at
744fcf
@@ -45,3 +45,16 @@ AT_SETUP([Fix bad rindex entry #1])
744fcf
 AT_KEYWORDS(fsck.gfs2 fsck)
744fcf
 GFS_NUKERG_CHECK([mkfs.gfs2 -O -p lock_nolock $GFS_TGT], [-i 1])
744fcf
 AT_CLEANUP
744fcf
+
744fcf
+AT_SETUP([gfs2 format versions])
744fcf
+AT_KEYWORDS(fsck.gfs2 fsck)
744fcf
+GFS_TGT_REGEN
744fcf
+AT_CHECK([mkfs.gfs2 -O -p lock_nolock ${GFS_TGT}], 0, [ignore], [ignore])
744fcf
+AT_CHECK([echo "set sb { sb_fs_format: 1802 }" | gfs2l ${GFS_TGT}], 0, [ignore], [ignore])
744fcf
+# Unsupported format, FSCK_USAGE == 16
744fcf
+AT_CHECK([fsck.gfs2 -y $GFS_TGT], 16, [ignore], [ignore])
744fcf
+# Format out of range
744fcf
+AT_CHECK([echo "set sb { sb_fs_format: 4242 }" | gfs2l ${GFS_TGT}], 0, [ignore], [ignore])
744fcf
+AT_CHECK([fsck.gfs2 -y $GFS_TGT], 1, [ignore], [ignore])
744fcf
+AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore])
744fcf
+AT_CLEANUP