Blame SOURCES/bz1622050-1-fsck_gfs2_Don_t_check_fs_formats_we_don_t_recognise.patch

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