From nobody Fri Jun 24 00:40:20 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 68C8986D7EB; Fri, 24 Jun 2022 00:40:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4LTdZD2TTtz3QdG; Fri, 24 Jun 2022 00:40:20 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1656031220; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=puqnmZPB3Nv/GUq8ia/ORi/5bBdDHAc1AT/xzr+o2LU=; b=NDsoWJnDfehSjVyXOD0KWJgd0uXeVx2T5KzxC/vfkXR4X3uMScP0OWa9rk4psT8SSdPUQE qkQOABwMUz7Qx6+jo7rOTew/E4H1xP82wqmbX4x+z1VO8vBemj4JBQEK4LnD6ncPVpzDbM ZeWFudnWABE+fqfEnwx6TFf98O1XrZJdhxAaT9wjP6D6Cua3UwlmXoa8NzCk1zQZiQOt7M 7JF0hUHDMbGE/6o5rZ10B4XLSsO2M4eyNz6SglvJWdEn2iSJ98PyOix6d/LZn5cPcI36EU /+z/JHmbrvXXjy0TYaZDxLwZVN08w7HFwq/bQcLJryPmesDyNNKr7lEMl3BHsA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3541725461; Fri, 24 Jun 2022 00:40:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 25O0eKuf038802; Fri, 24 Jun 2022 00:40:20 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 25O0eK0J038798; Fri, 24 Jun 2022 00:40:20 GMT (envelope-from git) Date: Fri, 24 Jun 2022 00:40:20 GMT Message-Id: <202206240040.25O0eK0J038798@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kirk McKusick Subject: git: 50dc4c7df415 - main - When a superblock integrity check fails, report the cause of the failure. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mckusick X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 50dc4c7df4156863148e6a9609c03e852e2aeb35 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1656031220; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=puqnmZPB3Nv/GUq8ia/ORi/5bBdDHAc1AT/xzr+o2LU=; b=KkMm86iuiSuNX3JUntvmuQRFP5Y9j70UGmqENO1Fsf5dD0a4xxEq6yX0llRwRhxrxl2Ld1 zNx41nGIOFNxhDFbwH8hKHXsIDFF6nwDWGRpvE+LW8PQHITEzhgx/tv+gvWCGqK/SCIO63 71m2zbwRtHqrqMePX4qq8cwrnuLl1OSc1qCtFXUgTYqmu8UJ/iLO9YHTjIMXw7okEydBrQ aSQUuJhVzv/vHUVUEoVtDaxEm+5yUm1nqr66puWcH8MsGQDSySssB9sZHkmPCk6Lud9bzA MIiSXHdUse5rpv/DF8a2iFowjfwXs3F68ADM/kLOJByWXaqIVyAbHt5Mhmek6w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1656031220; a=rsa-sha256; cv=none; b=Rgl+1nT+K7pWsdvGZk83/nyoTdmFYpQhBGD350zoo35pA+/uL+c7D98v49qFRXBQaML9Mf 2cU34V+HZ+KLSs2tHKajG1SOMF0HkyZazZ8xl/zE/ctAZ9C+fY9Cawdh9qeolZE01tA7eE pl50qkuTHjjZg/Uuim6bmV30ztEwRsPpqJPqh64kPmGXfKk6980H0ovbx/a7/OaDMmBL+5 gVctoA0HNP3qDSOuH8m8fm5vyClvf26XqHHd3hSQKNX3V5gdOg0wSdVNmVYj+hspT4i5MW KlhTHFeij4SUec7FyITB9XWxeiyo30KQCBIZQH0RkLEzZwkw4Ew0QCZU9Xlo6A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=50dc4c7df4156863148e6a9609c03e852e2aeb35 commit 50dc4c7df4156863148e6a9609c03e852e2aeb35 Author: Kirk McKusick AuthorDate: 2022-06-24 00:39:05 +0000 Commit: Kirk McKusick CommitDate: 2022-06-24 00:39:53 +0000 When a superblock integrity check fails, report the cause of the failure. No functional change intended. MFC after: 1 month (with 076002f24d35) Differential Revision: https://reviews.freebsd.org/D35219 --- sys/ufs/ffs/ffs_subr.c | 202 +++++++++++++++++++++++++++---------------------- 1 file changed, 111 insertions(+), 91 deletions(-) diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c index 3e31746c2cfc..b1e52f5964d9 100644 --- a/sys/ufs/ffs/ffs_subr.c +++ b/sys/ufs/ffs/ffs_subr.c @@ -309,6 +309,22 @@ readsuper(void *devfd, struct fs **fsp, off_t sblockloc, int isaltsblk, * Verify the filesystem values. */ #define ILOG2(num) (fls(num) - 1) +#define CHK(lhs, op, rhs, fmt) \ + if (lhs op rhs) { \ + printf("UFS%d superblock failed: %s (" #fmt ") %s %s (" \ + #fmt ")\n", fs->fs_magic == FS_UFS1_MAGIC ? 1 : 2, \ + #lhs, (intmax_t)lhs, #op, #rhs, (intmax_t)rhs); \ + return (ENOENT); \ + } +#define CHK2(lhs1, op1, rhs1, lhs2, op2, rhs2, fmt) \ + if (lhs1 op1 rhs1 && lhs2 op2 rhs2) { \ + printf("UFS%d superblock failed: %s (" #fmt ") %s %s (" \ + #fmt ") && %s (" #fmt ") %s %s (" #fmt ")\n", \ + fs->fs_magic == FS_UFS1_MAGIC ? 1 : 2, #lhs1, \ + (intmax_t)lhs1, #op1, #rhs1, (intmax_t)rhs1, #lhs2, \ + (intmax_t)lhs2, #op2, #rhs2, (intmax_t)rhs2); \ + return (ENOENT); \ + } static int validate_sblock(struct fs *fs, int isaltsblk) @@ -318,91 +334,95 @@ validate_sblock(struct fs *fs, int isaltsblk) sectorsize = dbtob(1); if (fs->fs_magic == FS_UFS2_MAGIC) { - if ((!isaltsblk && (fs->fs_sblockloc != SBLOCK_UFS2 || - !(fs->fs_sblockactualloc == 0 || - fs->fs_sblockactualloc == SBLOCK_UFS2))) || - fs->fs_maxsymlinklen != ((UFS_NDADDR + UFS_NIADDR) * - sizeof(ufs2_daddr_t)) || - fs->fs_nindir != fs->fs_bsize / sizeof(ufs2_daddr_t) || - fs->fs_inopb != fs->fs_bsize / sizeof(struct ufs2_dinode)) - return (ENOENT); + if (!isaltsblk) { + CHK(fs->fs_sblockloc, !=, SBLOCK_UFS2, %#jx); + CHK2(fs->fs_sblockactualloc, !=, SBLOCK_UFS2, + fs->fs_sblockactualloc, !=, 0, %jd); + } + CHK(fs->fs_maxsymlinklen, !=, ((UFS_NDADDR + UFS_NIADDR) * + sizeof(ufs2_daddr_t)), %jd); + CHK(fs->fs_nindir, !=, fs->fs_bsize / sizeof(ufs2_daddr_t), + %jd); + CHK(fs->fs_inopb, !=, fs->fs_bsize / sizeof(struct ufs2_dinode), + %jd); } else if (fs->fs_magic == FS_UFS1_MAGIC) { - if ((!isaltsblk && (fs->fs_sblockloc > SBLOCK_UFS1 || - !(fs->fs_sblockactualloc == SBLOCK_UFS1 || - fs->fs_sblockactualloc == 0))) || - fs->fs_nindir != fs->fs_bsize / sizeof(ufs1_daddr_t) || - fs->fs_inopb != fs->fs_bsize / sizeof(struct ufs1_dinode) || - fs->fs_maxsymlinklen != ((UFS_NDADDR + UFS_NIADDR) * - sizeof(ufs1_daddr_t)) || - fs->fs_old_inodefmt != FS_44INODEFMT || - fs->fs_old_cgoffset != 0 || - fs->fs_old_cgmask != 0xffffffff || - fs->fs_old_size != fs->fs_size || - fs->fs_old_rotdelay != 0 || - fs->fs_old_rps != 60 || - fs->fs_old_nspf != fs->fs_fsize / sectorsize || - fs->fs_old_cpg != 1 || - fs->fs_old_interleave != 1 || - fs->fs_old_trackskew != 0 || - fs->fs_old_cpc != 0 || - fs->fs_old_postblformat != 1 || - fs->fs_old_nrpos != 1 || - fs->fs_old_spc != fs->fs_fpg * fs->fs_old_nspf || - fs->fs_old_nsect != fs->fs_old_spc || - fs->fs_old_npsect != fs->fs_old_spc || - fs->fs_old_dsize != fs->fs_dsize || - fs->fs_old_ncyl != fs->fs_ncg) - return (ENOENT); + if (!isaltsblk) { + CHK(fs->fs_sblockloc, >, SBLOCK_UFS1, %#jx); + CHK2(fs->fs_sblockactualloc, !=, SBLOCK_UFS1, + fs->fs_sblockactualloc, !=, 0, %jd); + } + CHK(fs->fs_nindir, !=, fs->fs_bsize / sizeof(ufs1_daddr_t), + %jd); + CHK(fs->fs_inopb, !=, fs->fs_bsize / sizeof(struct ufs1_dinode), + %jd); + CHK(fs->fs_maxsymlinklen, !=, ((UFS_NDADDR + UFS_NIADDR) * + sizeof(ufs1_daddr_t)), %jd); + CHK(fs->fs_old_inodefmt, !=, FS_44INODEFMT, %jd); + CHK(fs->fs_old_cgoffset, !=, 0, %jd); + CHK(fs->fs_old_cgmask, !=, 0xffffffff, %#jx); + CHK(fs->fs_old_rotdelay, !=, 0, %jd); + CHK(fs->fs_old_rps, !=, 60, %jd); + CHK(fs->fs_old_nspf, !=, fs->fs_fsize / sectorsize, %jd); + CHK(fs->fs_old_cpg, !=, 1, %jd); + CHK(fs->fs_old_interleave, !=, 1, %jd); + CHK(fs->fs_old_trackskew, !=, 0, %jd); + CHK(fs->fs_old_cpc, !=, 0, %jd); + CHK(fs->fs_old_postblformat, !=, 1, %jd); + CHK(fs->fs_old_nrpos, !=, 1, %jd); + CHK(fs->fs_old_spc, !=, fs->fs_fpg * fs->fs_old_nspf, %jd); + CHK(fs->fs_old_nsect, !=, fs->fs_old_spc, %jd); + CHK(fs->fs_old_npsect, !=, fs->fs_old_spc, %jd); + CHK(fs->fs_old_ncyl, !=, fs->fs_ncg, %jd); } else { + /* Bad magic number, so assume not a superblock */ return (ENOENT); } - if (fs->fs_bsize < MINBSIZE || fs->fs_bsize > MAXBSIZE || - fs->fs_bsize < roundup(sizeof(struct fs), DEV_BSIZE) || - fs->fs_sbsize > SBLOCKSIZE || fs->fs_sbsize < fs->fs_fsize || - !powerof2(fs->fs_bsize)) - return (ENOENT); - if (fs->fs_fsize < sectorsize || fs->fs_fsize > fs->fs_bsize || - fs->fs_fsize * MAXFRAG < fs->fs_bsize || !powerof2(fs->fs_fsize)) - return (ENOENT); - if (fs->fs_maxbsize < fs->fs_bsize || !powerof2(fs->fs_maxbsize) || - fs->fs_maxbsize > FS_MAXCONTIG * fs->fs_bsize) - return (ENOENT); - if (fs->fs_bmask != ~(fs->fs_bsize - 1) || - fs->fs_fmask != ~(fs->fs_fsize - 1) || - fs->fs_qbmask != ~fs->fs_bmask || - fs->fs_qfmask != ~fs->fs_fmask || - fs->fs_bshift != ILOG2(fs->fs_bsize) || - fs->fs_fshift != ILOG2(fs->fs_fsize) || - fs->fs_frag != numfrags(fs, fs->fs_bsize) || - fs->fs_fragshift != ILOG2(fs->fs_frag) || - fs->fs_frag > MAXFRAG || - fs->fs_fsbtodb != ILOG2(fs->fs_fsize / sectorsize)) - return (ENOENT); - if (fs->fs_sblkno != - roundup(howmany(fs->fs_sblockloc + SBLOCKSIZE, fs->fs_fsize), - fs->fs_frag) || - fs->fs_cblkno != fs->fs_sblkno + - roundup(howmany(SBLOCKSIZE, fs->fs_fsize), fs->fs_frag) || - fs->fs_iblkno != fs->fs_cblkno + fs->fs_frag || - fs->fs_dblkno != fs->fs_iblkno + fs->fs_ipg / INOPF(fs) || - fs->fs_cgsize > fs->fs_bsize) - return (ENOENT); - if (fs->fs_csaddr != cgdmin(fs, 0) || - fs->fs_cssize != - fragroundup(fs, fs->fs_ncg * sizeof(struct csum)) || - fs->fs_dsize != fs->fs_size - fs->fs_sblkno - + CHK(fs->fs_bsize, <, MINBSIZE, %jd); + 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); + CHK(fs->fs_fsize * MAXFRAG, <, fs->fs_bsize, %jd); + CHK(powerof2(fs->fs_fsize), ==, 0, %jd); + CHK(fs->fs_maxbsize, <, fs->fs_bsize, %jd); + CHK(powerof2(fs->fs_maxbsize), ==, 0, %jd); + CHK(fs->fs_maxbsize, >, FS_MAXCONTIG * fs->fs_bsize, %jd); + CHK(fs->fs_bmask, !=, ~(fs->fs_bsize - 1), %#jx); + CHK(fs->fs_fmask, !=, ~(fs->fs_fsize - 1), %#jx); + CHK(fs->fs_qbmask, !=, ~fs->fs_bmask, %#jx); + CHK(fs->fs_qfmask, !=, ~fs->fs_fmask, %#jx); + CHK(fs->fs_bshift, !=, ILOG2(fs->fs_bsize), %jd); + CHK(fs->fs_fshift, !=, ILOG2(fs->fs_fsize), %jd); + CHK(fs->fs_frag, !=, numfrags(fs, fs->fs_bsize), %jd); + CHK(fs->fs_fragshift, !=, ILOG2(fs->fs_frag), %jd); + CHK(fs->fs_frag, >, MAXFRAG, %jd); + CHK(fs->fs_fsbtodb, !=, ILOG2(fs->fs_fsize / sectorsize), %jd); + CHK(fs->fs_sblkno, !=, roundup( + howmany(fs->fs_sblockloc + SBLOCKSIZE, fs->fs_fsize), + fs->fs_frag), %jd); + CHK(fs->fs_cblkno, !=, fs->fs_sblkno + + roundup(howmany(SBLOCKSIZE, fs->fs_fsize), fs->fs_frag), %jd); + CHK(fs->fs_iblkno, !=, fs->fs_cblkno + fs->fs_frag, %jd); + CHK(fs->fs_dblkno, !=, fs->fs_iblkno + fs->fs_ipg / INOPF(fs), %jd); + CHK(fs->fs_cgsize, >, fs->fs_bsize, %jd); + CHK(fs->fs_csaddr, !=, cgdmin(fs, 0), %jd); + CHK(fs->fs_cssize, !=, + fragroundup(fs, fs->fs_ncg * sizeof(struct csum)), %jd); + CHK(fs->fs_dsize, !=, fs->fs_size - fs->fs_sblkno - fs->fs_ncg * (fs->fs_dblkno - fs->fs_sblkno) - - howmany(fs->fs_cssize, fs->fs_fsize) || - fs->fs_metaspace < 0 || fs->fs_metaspace > fs->fs_fpg / 2 || - fs->fs_minfree > 99) - return (ENOENT); + howmany(fs->fs_cssize, fs->fs_fsize), %jd); + CHK(fs->fs_metaspace, <, 0, %jd); + CHK(fs->fs_metaspace, >, fs->fs_fpg / 2, %jd); + CHK(fs->fs_minfree, >, 99, %jd%%); maxfilesize = fs->fs_bsize * UFS_NDADDR - 1; for (sizepb = fs->fs_bsize, i = 0; i < UFS_NIADDR; i++) { sizepb *= NINDIR(fs); maxfilesize += sizepb; } - if (fs->fs_maxfilesize != maxfilesize) - return (ENOENT); + CHK(fs->fs_maxfilesize, !=, maxfilesize, %jd); /* * These values have a tight interaction with each other that * makes it hard to tightly bound them. So we can only check @@ -416,14 +436,16 @@ validate_sblock(struct fs *fs, int isaltsblk) * since newfs(8) strives to have at least four cylinder groups. */ minfpg = MIN(12289, fs->fs_size / 4); - if (fs->fs_ncg < 1 || fs->fs_ncg > (fs->fs_size / minfpg) + 1 || - fs->fs_fpg < minfpg || fs->fs_fpg > fs->fs_size || - fs->fs_ipg * fs->fs_ncg > (((int64_t)(1)) << 32) - INOPB(fs) || - fs->fs_ipg > fs->fs_fpg || fs->fs_size < 8 * fs->fs_frag) - return (ENOENT); - if (fs->fs_size <= (fs->fs_ncg - 1) * fs->fs_fpg || - fs->fs_size > fs->fs_ncg * fs->fs_fpg) - return (ENOENT); + CHK(fs->fs_ncg, <, 1, %jd); + CHK(fs->fs_ncg, >, (fs->fs_size / minfpg) + 1, %jd); + CHK(fs->fs_fpg, <, minfpg, %jd); + CHK(fs->fs_fpg, >, fs->fs_size, %jd); + CHK(fs->fs_ipg * fs->fs_ncg, >, (((int64_t)(1)) << 32) - INOPB(fs), + %jd); + CHK(fs->fs_ipg, >, fs->fs_fpg, %jd); + CHK(fs->fs_size, <, 8 * fs->fs_frag, %jd); + CHK(fs->fs_size, <=, (fs->fs_ncg - 1) * fs->fs_fpg, %jd); + CHK(fs->fs_size, >, fs->fs_ncg * fs->fs_fpg, %jd); /* * With file system clustering it is possible to allocate * many contiguous blocks. The kernel variable maxphys defines @@ -443,14 +465,12 @@ validate_sblock(struct fs *fs, int isaltsblk) * those (mostly 32-bit machines) can (very slowly) handle I/O * requests that exceed maxphys. */ - if (fs->fs_maxcontig < 1 || - fs->fs_maxcontig > MAX(256, maxphys / fs->fs_bsize)) - return (ENOENT); - if (fs->fs_maxcontig < 0 || - (fs->fs_maxcontig == 0 && fs->fs_contigsumsize != 0) || - (fs->fs_maxcontig > 1 && - fs->fs_contigsumsize != MIN(fs->fs_maxcontig, FS_MAXCONTIG))) - return (ENOENT); + CHK(fs->fs_maxcontig, <, 1, %jd); + CHK(fs->fs_maxcontig, >, MAX(256, maxphys / fs->fs_bsize), %jd); + CHK(fs->fs_maxcontig, <, 0, %jd); + CHK2(fs->fs_maxcontig, ==, 0, fs->fs_contigsumsize, !=, 0, %jd); + CHK2(fs->fs_maxcontig, >, 1, fs->fs_contigsumsize, !=, + MIN(fs->fs_maxcontig, FS_MAXCONTIG), %jd); return (0); }