1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

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
This commit is contained in:
Kirk McKusick 2021-05-28 19:41:05 -07:00
parent 677cb9722a
commit 5c9e9eb7a2

View File

@ -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) {