Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 May 2021 02:37:57 GMT
From:      Kirk McKusick <mckusick@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 5c9e9eb7a27f - main - Fix fsck_ufs segfault when it needs to rerun.
Message-ID:  <202105290237.14T2bvfv071798@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mckusick:

URL: https://cgit.FreeBSD.org/src/commit/?id=5c9e9eb7a27feb24136c16706f3db8ce7c8bbc47

commit 5c9e9eb7a27feb24136c16706f3db8ce7c8bbc47
Author:     Kirk McKusick <mckusick@FreeBSD.org>
AuthorDate: 2021-05-29 02:41:05 +0000
Commit:     Kirk McKusick <mckusick@FreeBSD.org>
CommitDate: 2021-05-29 02:41:50 +0000

    Fix fsck_ufs segfault when it needs to rerun.
    
    The segfault was being hit in the rerun of Pass 1 in ginode() when
    trying to get an inode that needs to be repaired. When the first run
    of fsck_ffs finishes it clears the inode cache, but ginode() was
    failing to check properly and tried to access the deallocated cache entry.
    
    Reported by:  Peter Holm
    Reviewed by:  Chuck Silvers
    Tested by:    Peter Holm and Chuck Silvers
    MFC after:    3 days
    Sponsored by: Netflix
---
 sbin/fsck_ffs/inode.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
index d4e5723f559f..ba2d5892238e 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/inode.c
@@ -416,14 +416,14 @@ void
 ginode(ino_t inumber, struct inode *ip)
 {
 	ufs2_daddr_t iblk;
-	static ino_t startinum = -1;
 
 	if (inumber < UFS_ROOTINO || inumber > maxino)
 		errx(EEXIT, "bad inode number %ju to ginode",
 		    (uintmax_t)inumber);
 	ip->i_number = inumber;
-	if (startinum != -1 &&
-	    inumber >= startinum && inumber < startinum + INOPB(&sblock)) {
+	if (icachebp != NULL &&
+	    inumber >= icachebp->b_index &&
+	    inumber < icachebp->b_index + INOPB(&sblock)) {
 		/* take an additional reference for the returned inode */
 		icachebp->b_refcnt++;
 	} else {
@@ -433,14 +433,14 @@ ginode(ino_t inumber, struct inode *ip)
 			brelse(icachebp);
 		icachebp = getdatablk(iblk, sblock.fs_bsize, BT_INODES);
 		if (icachebp->b_errs != 0) {
+			icachebp = NULL;
 			ip->i_bp = NULL;
 			ip->i_dp = &zino;
 			return;
 		}
-		startinum = rounddown(inumber, INOPB(&sblock));
 		/* take a cache-hold reference on new icachebp */
 		icachebp->b_refcnt++;
-		icachebp->b_index = startinum;
+		icachebp->b_index = rounddown(inumber, INOPB(&sblock));
 	}
 	ip->i_bp = icachebp;
 	if (sblock.fs_magic == FS_UFS1_MAGIC) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202105290237.14T2bvfv071798>