Blame SOURCES/bz1616389-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise.patch

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