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

From: Kirk McKusick <mckusick_at_FreeBSD.org>
Date: Thu, 21 Jul 2022 05:52:42 UTC
The branch main has been updated by mckusick:

URL: https://cgit.FreeBSD.org/src/commit/?id=36e08b0127f97928a2f2c062feed8df9087b2b35

commit 36e08b0127f97928a2f2c062feed8df9087b2b35
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2022-07-21 05:51:15 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2022-07-21 05:52:11 +0000

    Bug fix to UFS/FFS superblock integrity checks when reading a superblock.
    
    A better fix to commit 9e1f44d044a. Rather than coping with the case
    where a backup superblock is used, catch the case when the superblock
    is being read in and ensure that the standard one is used rather than
    the backup one.
---
 sys/ufs/ffs/ffs_subr.c | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index 21daa44de4d8..1df3f878c4eb 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -256,6 +256,16 @@ readsuper(void *devfd, struct fs **fsp, off_t sblockloc, int isaltsblk,
 	fs = *fsp;
 	if (fs->fs_magic == FS_BAD_MAGIC)
 		return (EINVAL);
+	/*
+	 * For UFS1 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. Here we fail the lookup so that we can
+	 * retry with the correct location for the UFS1 superblock.
+	 */
+	if (fs->fs_magic == FS_UFS1_MAGIC && !isaltsblk &&
+	    fs->fs_bsize == SBLOCK_UFS2 && sblockloc == SBLOCK_UFS2)
+		return (ENOENT);
 	if ((error = validate_sblock(fs, isaltsblk)) != 0)
 		return (error);
 	/*
@@ -349,20 +359,7 @@ validate_sblock(struct fs *fs, int isaltsblk)
 	} else if (fs->fs_magic == FS_UFS1_MAGIC) {
 		if (!isaltsblk) {
 			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_sblockactualloc, >, SBLOCK_UFS1, %jd);
 		}
 		CHK(fs->fs_nindir, !=, fs->fs_bsize / sizeof(ufs1_daddr_t),
 		    %jd);