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>
