git: 9e1f44d044a5 - main - Bug fix to UFS/FFS superblock integrity checks when reading a superblock.

From: Kirk McKusick <mckusick_at_FreeBSD.org>
Date: Wed, 06 Jul 2022 21:45:57 UTC
The branch main has been updated by mckusick:

URL: https://cgit.FreeBSD.org/src/commit/?id=9e1f44d044a58fcd2caaca3f57e69cf6180db3dc

commit 9e1f44d044a58fcd2caaca3f57e69cf6180db3dc
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2022-07-06 21:31:00 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2022-07-06 21:45:30 +0000

    Bug fix to UFS/FFS superblock integrity checks when reading a superblock.
    
    The original check verified that if an alternate superblock has not
    been selected that the superblock is located in its standard location.
    For UFS1 the with a 65536 block size, the first backup superblock
    is at the same location as the UFS2 superblock. Since SBLOCK_UFS2
    is the first location checked, the first backup is the superblock
    that will be used for a UFS1 filesystems with a 65536 block size.
    This patch allows the use of the first backup superblock in that
    situation.
    
    Reported by: Peter Holm
    Tested by:   Peter Holm
    MFC after:   1 month (with 076002f24d35)
    Differential Revision: https://reviews.freebsd.org/D35219
---
 sys/ufs/ffs/ffs_subr.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index 438745f8eb49..d87579832617 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -348,9 +348,21 @@ validate_sblock(struct fs *fs, int isaltsblk)
 		    %jd);
 	} else if (fs->fs_magic == FS_UFS1_MAGIC) {
 		if (!isaltsblk) {
-			CHK(fs->fs_sblockloc, >, SBLOCK_UFS1, %#jx);
-			CHK2(fs->fs_sblockactualloc, !=, SBLOCK_UFS1,
-			    fs->fs_sblockactualloc, !=, 0, %jd);
+			CHK(fs->fs_sblockloc, >, SBLOCK_UFS1, %jd);
+			/*
+			 * For UFS1 the with a 65536 block size, the first
+			 * backup superblock is at the same location as the
+			 * UFS2 superblock. Since SBLOCK_UFS2 is the first
+			 * location checked, the first backup is the
+			 * superblock that will be accessed.
+			 */
+			if (fs->fs_bsize == SBLOCK_UFS2) {
+				CHK(fs->fs_sblockactualloc, >, SBLOCK_UFS2,
+				    %jd);
+			} else {
+				CHK2(fs->fs_sblockactualloc, !=, SBLOCK_UFS1,
+				    fs->fs_sblockactualloc, !=, 0, %jd);
+			}
 		}
 		CHK(fs->fs_nindir, !=, fs->fs_bsize / sizeof(ufs1_daddr_t),
 		    %jd);
@@ -382,7 +394,6 @@ validate_sblock(struct fs *fs, int isaltsblk)
 	CHK(fs->fs_bsize, >, MAXBSIZE, %jd);
 	CHK(fs->fs_bsize, <, roundup(sizeof(struct fs), DEV_BSIZE), %jd);
 	CHK(fs->fs_sbsize, >, SBLOCKSIZE, %jd);
-	CHK(fs->fs_sbsize, <, fs->fs_fsize, %jd);
 	CHK(powerof2(fs->fs_bsize), ==, 0, %jd);
 	CHK(fs->fs_fsize, <, sectorsize, %jd);
 	CHK(fs->fs_fsize, >, fs->fs_bsize, %jd);