tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: amd64 -current crashs at boot
Patrick Welche wrote:
> On Sun, Dec 21, 2008 at 05:55:54PM +0100, Christoph Egger wrote:
>> Christoph Egger wrote:
>>> Hi,
>>>
>>> a amd64 -current kernel from today crashes at boot
>>> when sshd starts:
>>>
>>> uvm_fault(0xffffffff80d1e180, 0x0, 1) -> e
>>> fatal page fault in supervisor mode
>>> trap type 6 code 0 rip ffffffff802abbe4 cs 8 rflags 10282 cr2 60 cpl 0
>>> rsp ffff80004d832b20
>>> kernel: page fault trap, code=0
>>> Stopped in pid 0x46 (system) at netbsd:ffs_update+0x24: testb
>>> $0x1,0x60(%ray)
>>> db{0}> bt
>>> ffs_update() at netbsd:ffs_update+0x24
>>> ffs_full_fsync() at netbsd:ffs_full_fsync+0x54b
>>> spec_fsync() at netbsd:spec_fsync+0x59
>>> VOP_FSYNC() at netbsd:VOP_FSYNC+0x71
>>> sched_sync() at netbsd:sched_sync+0x14f
>>> db{0}> ps /l
>>> [...]
>>> PID LID S FLAGS STRUCT LWP * NAME WAIT
>>>> 0 49 3 204 ffff80004e1e7400 physiod physiod
>>> 48 3 204 ffff80004d7127c0 vmem_rehash vmem_rehash
>>> 47 3 204 ffff80004d712ba0 aiodoned aiodoned
>>> > 46 7 204 ffff80004d700000 ioflush
>>> [...]
>> I found the commit which causes this:
>>
>> It is ffs_vnops.c, rev. 1.105. Going back to rev. 1.104 makes
>> the machine boot again.
>>
>> With rev. 1.105, when ffs_full_fsync() calls ffs_update in line 580,
>> vp->v_mount is a NULL pointer. ffs_update() dereferences it w/o
>> checking if the pointer is valid.
>
> I seem to hit the other branch - NULL v_specmountpoint rather
> than NULL v_mount:
> With source of Dec 21 18:40, on i386, hit the assertion in
> /sys/ufs/ffs/ffs_vnops.c:414
>
> 413 if ((flags & FSYNC_VFS) != 0) {
> 414 KASSERT(vp->v_specmountpoint != NULL);
> 415 mp = vp->v_specmountpoint;
> 416 ffsino = (mp->mnt_op == &ffs_vfsops);
> 417 KASSERT(vp->v_type == VBLK);
> 418 } else {
> 419 mp = vp->v_mount;
> 420 ffsino = true;
> 421 KASSERT(vp->v_tag == VT_UFS);
> 422 }
No, I also hit the same branch. mp is set to vp->v_specmountpoint
which is a valid pointer. vp->v_mount is the NULL pointer
which is deferenced in ffs_update() w/o any validity checks before.
Attached patch sprinkles some KASSERTs which explicitely check
for assumptions not check otherwise in the code path.
The last hunk in the diff to ffs_vnode.c fixes the crash for me
and makes my machine boot again.
Patch ok to commit ?
Christoph
Index: sys/ufs/ffs/ffs_inode.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_inode.c,v
retrieving revision 1.100
diff -u -p -r1.100 ffs_inode.c
--- sys/ufs/ffs/ffs_inode.c 17 Dec 2008 20:51:38 -0000 1.100
+++ sys/ufs/ffs/ffs_inode.c 22 Dec 2008 11:37:42 -0000
@@ -118,8 +118,12 @@ ffs_update(struct vnode *vp, const struc
void *cp;
int waitfor, flags;
+ KASSERT(vp);
+ KASSERT(vp->v_mount);
+
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (0);
+ KASSERT(VTOI(vp));
ip = VTOI(vp);
FFS_ITIMES(ip, acc, mod, NULL);
if (updflags & UPDATE_CLOSE)
Index: sys/ufs/ffs/ffs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vnops.c,v
retrieving revision 1.105
diff -u -p -r1.105 ffs_vnops.c
--- sys/ufs/ffs/ffs_vnops.c 21 Dec 2008 10:44:32 -0000 1.105
+++ sys/ufs/ffs/ffs_vnops.c 22 Dec 2008 11:37:42 -0000
@@ -410,6 +410,7 @@ ffs_full_fsync(struct vnode *vp, int fla
error = 0;
+ KASSERT(vp != NULL);
if ((flags & FSYNC_VFS) != 0) {
KASSERT(vp->v_specmountpoint != NULL);
mp = vp->v_specmountpoint;
@@ -440,6 +441,7 @@ ffs_full_fsync(struct vnode *vp, int fla
if ((flags & FSYNC_WAIT))
pflags |= PGO_SYNCIO;
+ KASSERT(mp != NULL);
if (vp->v_type == VREG &&
fstrans_getstate(mp) == FSTRANS_SUSPENDING)
pflags |= PGO_FREE;
@@ -462,6 +464,7 @@ ffs_full_fsync(struct vnode *vp, int fla
error = UFS_WAPBL_BEGIN(mp);
if (error)
return error;
+ KASSERT(vp->v_mount != NULL);
error = ffs_update(vp, NULL, NULL,
(flags & FSYNC_WAIT) ? UPDATE_WAIT : 0);
UFS_WAPBL_END(mp);
@@ -576,7 +579,7 @@ loop:
else
waitfor = (flags & FSYNC_WAIT) ? UPDATE_WAIT : 0;
- if (ffsino)
+ if (ffsino && vp->v_mount != NULL)
error = ffs_update(vp, NULL, NULL, waitfor);
if (error == 0 && flags & FSYNC_CACHE) {
Home |
Main Index |
Thread Index |
Old Index