kern/153847: Kernel panic from incorrect m_free in nfs_getattr

Martin Simmons martin at lispworks.com
Mon Jan 10 14:00:20 UTC 2011


>Number:         153847
>Category:       kern
>Synopsis:       Kernel panic from incorrect m_free in nfs_getattr
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 10 14:00:19 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Martin Simmons
>Release:        7.3-RELEASE
>Organization:
>Environment:
FreeBSD greig.cam.lispworks.com 7.3-RELEASE FreeBSD 7.3-RELEASE #0: Sun Mar 21 06:15:01 UTC 2010     root at walker.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
kgdb gives the output below from the dump:


Unread portion of the kernel message buffer:
<6>nfs server pid904 at greig:/sp: is alive again


Fatal trap 12: page fault while in kernel mode
cpuid = 0; apic id = 00
fault virtual address	= 0x7273752f
fault code		= supervisor read, page not present
instruction pointer	= 0x20:0xc084c330
stack pointer	        = 0x28:0xe7d0984c
frame pointer	        = 0x28:0xe7d0985c
code segment		= base 0x0, limit 0xfffff, type 0x1b
			= DPL 0, pres 1, def32 1, gran 1
processor eflags	= interrupt enabled, resume, IOPL = 0
current process		= 27611 (sh)
trap number		= 12
panic: page fault
cpuid = 0
Uptime: 23h58m43s
Physical memory: 2035 MB
Dumping 181 MB: 166 150 134 118 102
<6>nfs server pid904 at greig:/nfs: not responding
 86 70 54 38

Fatal trap 12: page fault while in kernel mode
cpuid = 1; apic id = 01
fault virtual address	= 0x207366ce
fault code		= supervisor read, page not present
instruction pointer	= 0x20:0xc06616ed
stack pointer	        = 0x28:0xc51b9be0
frame pointer	        = 0x28:0xc51b9bf0
code segment		= base 0x0, limit 0xfffff, type 0x1b
			= DPL 0, pres 1, def32 1, gran 1
processor eflags	= interrupt enabled, resume, IOPL = 0
current process		= 14 (swi4: clock sio)
trap number		= 12
 22 6



#0  doadump () at pcpu.h:196
#1  0xc07f8c57 in boot (howto=0x104) at /usr/src/sys/kern/kern_shutdown.c:418
#2  0xc07f8f29 in panic (fmt=Variable "fmt" is not available.
) at /usr/src/sys/kern/kern_shutdown.c:574
#3  0xc0b010dc in trap_fatal (frame=0xe7d0980c, eva=0x7273752f) at /usr/src/sys/i386/i386/trap.c:950
#4  0xc0b01360 in trap_pfault (frame=0xe7d0980c, usermode=0x0, eva=0x7273752f) at /usr/src/sys/i386/i386/trap.c:863
#5  0xc0b01d55 in trap (frame=0xe7d0980c) at /usr/src/sys/i386/i386/trap.c:541
#6  0xc0ae503b in calltrap () at /usr/src/sys/i386/i386/exception.s:166
#7  0xc084c330 in m_freem (mb=0x7273752f) at /usr/src/sys/kern/uipc_mbuf.c:162
#8  0xc09a4245 in nfs_getattr (ap=0xe7d09980) at /usr/src/sys/nfsclient/nfs_vnops.c:666
#9  0xc0b16172 in VOP_GETATTR_APV (vop=0xc0c8ab40, a=0xe7d09980) at vnode_if.c:530
#10 0xc09a83ac in nfs_lookup (ap=0xe7d09a98) at vnode_if.h:286
#11 0xc0b17b76 in VOP_LOOKUP_APV (vop=0xc0c8ab40, a=0xe7d09a98) at vnode_if.c:99
#12 0xc0872afb in lookup (ndp=0xe7d09ba8) at vnode_if.h:57
#13 0xc0873972 in namei (ndp=0xe7d09ba8) at /usr/src/sys/kern/vfs_lookup.c:234
#14 0xc0881c04 in kern_stat (td=0xc68a7000, path=0x28203288 <Address 0x28203288 out of bounds>, pathseg=UIO_USERSPACE, sbp=0xe7d09c18) at /usr/src/sys/kern/vfs_syscalls.c:2131
#15 0xc0881def in stat (td=0xc68a7000, uap=0xe7d09cfc) at /usr/src/sys/kern/vfs_syscalls.c:2115
#16 0xc0b016b5 in syscall (frame=0xe7d09d38) at /usr/src/sys/i386/i386/trap.c:1101
#17 0xc0ae50a0 in Xint0x80_syscall () at /usr/src/sys/i386/i386/exception.s:262
#18 0x00000033 in ?? ()

>How-To-Repeat:
Not sure, but I think it has something to do with filesystems being run by am-utils.

>Fix:
Last time I saw this (in 7.2) I got some way to tracking it down.  I think the problem is that nfs_request doesn't validate the value of error that it reads from the nfs packet:

	if (*tl == 0) {
		tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
		if (*tl != 0) {
			error = fxdr_unsigned(int, *tl);

Things go wrong if this value has the NFSERR_RETERR bit set already (e.g. due to a bug in the nfs server).  In particular, when this value is returned to nfsm_request, the bit will be cleared and nfs_getattr will subsequently call m_freem(mrep) even though mrep hasn't been initialized by nfs_request.

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list