Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Oct 2002 20:10:23 +0200 (CEST)
From:      Arne H Juul <Arne.Juul@fast.no>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        arnej@pvv.org
Subject:   bin/43635: filesystem damage not detected by fsck
Message-ID:  <200210031810.g93IANd22666@guinness.trondheim.fast.no>

next in thread | raw e-mail | index | archive | help

>Number:         43635
>Category:       bin
>Synopsis:       filesystem damage not detected by fsck
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 03 11:20:01 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Arne H Juul
>Release:        FreeBSD 4.5-RELEASE i386
>Organization:
ProgramVareVerkstedet
>Environment:
System: FreeBSD guinness.trondheim.fast.no 4.5-RELEASE FreeBSD 4.5-RELEASE #0: Thu Apr 18 03:10:10 CEST 2002 arnej@guinness.trondheim.fast.no:/usr/src/sys/compile/GUINNESS_PXE i386

	The problem was originally seen on a 4.4-RELEASE kernel,
	but the fsck fix seems to apply across the board.

>Description:
	we had a problem where a machine would panic with
	page fault in kernel mode during normal usage of a
	filesystem.  fsck detected no problem but a closer
	look at a kernel crashdump showed that a cg->cg_irotor
	was hugely negative; this led to crashes in skpc like this:

#5  0xc02872bf in trap (frame={tf_fs = 24, tf_es = -1072037872, tf_ds = 16, 
      tf_edi = -724213760, tf_esi = -1002668032, tf_ebp = -413647876, 
      tf_isp = -413647896, tf_ebx = 115468226, tf_edx = -724210968, 
      tf_ecx = 255, tf_eax = -839679194, tf_trapno = 12, tf_err = 0, 
      tf_eip = -1071319959, tf_cs = 8, tf_eflags = 66195, tf_esp = -413647832, 
      tf_ss = -1071520840}) at /usr/src/sys/i386/i386/trap.c:467
#6  0xc024f469 in skpc (mask0=255, size=115468226, 
    cp0=0xcdf38326 <Address 0xcdf38326 out of bounds>)
    at /usr/src/sys/libkern/skpc.c:50
#7  0xc021e3b8 in ffs_nodealloccg (ip=0xc43d5600, cg=88, ipref=157696, 
    mode=33188) at /usr/src/sys/ufs/ffs/ffs_alloc.c:1252
#8  0xc021d587 in ffs_hashalloc (ip=0xc43d5600, cg=88, pref=157696, 
    size=33188, allocator=0xc021e278 <ffs_nodealloccg>)
    at /usr/src/sys/ufs/ffs/ffs_alloc.c:768
#9  0xc021d27a in ffs_valloc (pvp=0xe75c7b00, mode=33188, cred=0xc1ddf900, 
    vpp=0xe7583ca0) at /usr/src/sys/ufs/ffs/ffs_alloc.c:596
#10 0xc02301f7 in ufs_makeinode (mode=33188, dvp=0xe75c7b00, vpp=0xe7583edc, 
    cnp=0xe7583ef0) at /usr/src/sys/ufs/ufs/ufs_vnops.c:2097
#11 0xc022dbac in ufs_create (ap=0xe7583dfc)
    at /usr/src/sys/ufs/ufs/ufs_vnops.c:194
#12 0xc02304b9 in ufs_vnoperate (ap=0xe7583dfc)
    at /usr/src/sys/ufs/ufs/ufs_vnops.c:2382
#13 0xc01b830c in vn_open (ndp=0xe7583ec8, fmode=1538, cmode=420)
    at vnode_if.h:106
#14 0xc01b44f8 in open (p=0xe33c5f60, uap=0xe7583f80)
    at /usr/src/sys/kern/vfs_syscalls.c:1010

because ffs_nodealloccg depends on start = cgp->cg_irotor / NBBY;
to be a valid index into the "inosused" array.

fsck has a check of cg->cg_irotor but only for "too large"
values, not for negative values.  I've also added a printf
to actually report the change made by fsck since this should
only happen when the filesystem has been damaged. 

>How-To-Repeat:
	overwrite cylinder group data with random junk. "fix"
	with fsck -y. try to use filesystem normally.  observe
	the panic - if you're lucky.  If you're not lucky
	the kernel will probably read some random memory and
	write data to random places on the disk, or something...
>Fix:
	The following two patches are for current and for RELENG_4;
	they are very similar, and follow the current code-style
	in fsck.  Please apply.

Index: pass5.c
===================================================================
RCS file: /usr/cvs/src/sbin/fsck_ffs/pass5.c,v
retrieving revision 1.32
diff -u -r1.32 pass5.c
--- pass5.c	25 Sep 2002 04:06:36 -0000	1.32
+++ pass5.c	3 Oct 2002 17:52:57 -0000
@@ -192,10 +192,13 @@
 			newcg->cg_frotor = cg->cg_frotor;
 		else
 			newcg->cg_frotor = 0;
-		if (cg->cg_irotor < fs->fs_ipg)
+		if (cg->cg_irotor < fs->fs_ipg  && cg->cg_irotor >= 0)
 			newcg->cg_irotor = cg->cg_irotor;
-		else
+		else {
+			printf("%s: phase 5: bad cg irotor %d of %d\n",
+				cdevname, cg->cg_irotor, newcg->cg_niblk);
 			newcg->cg_irotor = 0;
+		}
 		if (fs->fs_magic == FS_UFS1_MAGIC) {
 			newcg->cg_initediblk = 0;
 		} else {

Index: pass5.c
===================================================================
RCS file: /usr/cvs/src/sbin/fsck/Attic/pass5.c,v
retrieving revision 1.17.2.1
diff -u -IId: -u -r1.17.2.1 pass5.c
--- pass5.c	23 Jan 2001 23:11:07 -0000	1.17.2.1
+++ pass5.c	3 Oct 2002 17:48:02 -0000
@@ -203,10 +203,13 @@
 			newcg->cg_frotor = cg->cg_frotor;
 		else
 			newcg->cg_frotor = 0;
-		if (cg->cg_irotor < newcg->cg_niblk)
+		if (cg->cg_irotor < newcg->cg_niblk && cg->cg_irotor >= 0)
 			newcg->cg_irotor = cg->cg_irotor;
-		else
+		else {
+			printf("%s: phase 5: bad cg irotor %d of %d\n",
+			    cdevname, cg->cg_irotor, newcg->cg_niblk);
 			newcg->cg_irotor = 0;
+		}
 		memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
 		memset(&cg_blktot(newcg)[0], 0,
 		      (size_t)(sumsize + mapsize));
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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