kern/58258: Panic in knote_drop()

Stefan Farfeleder stefan at fafoe.narf.at
Sun Oct 19 14:10:04 PDT 2003


>Number:         58258
>Category:       kern
>Synopsis:       Panic in knote_drop()
>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:   Sun Oct 19 14:10:02 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Stefan Farfeleder
>Release:        FreeBSD 5.1-CURRENT i386
>Organization:
>Environment:
System: FreeBSD wombat.fafoe.narf.at 5.1-CURRENT FreeBSD 5.1-CURRENT #6: Thu Oct 16 21:34:42 CEST 2003 freebsd at frog.fafoe.narf.at:/freebsd/wombat/obj/freebsd/wombat/src/sys/WOMBAT i386

>Description:
The attached program kqueue-crash.c causes a null pointer dereference in
the kernel if you do a few ctrl-z / fg cycles while it is running.  I'm
aware that the program is rather buggy (e.g. it doesn't collect its
zombies), but I stripped it down to the smallest one still reproducing
the panic.

>How-To-Repeat:
This panic results from the actions described above:

%%
Fatal trap 12: page fault while in kernel mode
fault virtual address	= 0x0
fault code		= supervisor read, page not present
instruction pointer	= 0x8:0xc04b25c2
stack pointer	        = 0x10:0xcd429bf0
frame pointer	        = 0x10:0xcd429c0c
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		= 514 (a.out)
kernel: type 12 trap, code=0
Stopped at      knote_drop+0xc2:        cmpl    %ebx,0(%edx)
db> t
knote_drop(c1e64cc0,c1cb9000,c06589a8,29b,c065de22) at knote_drop+0xc2
kqueue_scan(c1cf46e8,1,8049b40,0,c1cb9000) at kqueue_scan+0x2f0
kevent(c1cb9000,cd429d10,c067228c,3ec,6) at kevent+0x1f1
syscall(2f,2f,2f,bfbffbe0,bfbffbe8) at syscall+0x273
Xint0x80_syscall() at Xint0x80_syscall+0x1d
--- syscall (363, FreeBSD ELF32, kevent), eip = 0x280bc18f, esp = 0xbfbff77c, ebp = 0xbfbffbb8 ---
db> show registers                                                              
cs                 0x8                                                          
ds                0x10                                                          
es          0xc1e50010                                                          
fs                0x18                                                          
ss                0x10                                                          
eax                0x1                                                          
ecx                0x1                                                          
edx                  0                                                          
ebx         0xc1e65500                                                          
esp         0xcd975bf0                                                          
ebp         0xcd975c0c                                                          
esi         0xc1e5a500                                                          
edi         0xc1d5ed34                                                          
eip         0xc04b25c2  knote_drop+0xc2                                         
efl            0x10207                                                          
dr0                  0                                                          
dr1                  0                                                          
dr2                  0                                                          
dr3                  0                                                          
dr4         0xffff0ff0                                                          
dr5              0x400                                                          
dr6         0xffff0ff0                                                          
dr7              0x400                                                          
knote_drop+0xc2:        cmpl    %ebx,0(%edx)                                    
db> ps
  pid   proc     uarea   uid  ppid  pgrp  flag   stat  wmesg    wchan  cmd
  519 c1cf0d3c cd8aa000 1001   514   514 0010002 [RUNQ] a.out
  514 c1cf0974 cd8a8000 1001   468   514 0005002 [CPU 0] a.out
  468 c1e3b790 cd8bf000 1001   467   468 0004002 [SLP]wait 0xc1e3b790] bash
  467 c1e3b974 cd8c0000 1001   465   465 0000100 [RUNQ] sshd
  465 c1e3bd3c cd8e9000    0   398   465 0000100 [SLP]sbwait 0xc1d3d964] sshd
  461 c1e3e5ac cd8ed000    0     1   461 0004002 [SLP]ttyin 0xc1d6ac10] getty
  460 c1e3e790 cd8ee000    0     1   460 0004002 [SLP]ttyin 0xc1d6a810] getty
  459 c1cf05ac cd8a6000    0     1   459 0004002 [SLP]ttyin 0xc1d6a410] getty
  458 c1cb8d3c cd44f000    0     1   458 0004002 [SLP]ttyin 0xc1d6a010] getty
  457 c1cf0b58 cd8a9000    0     1   457 0004002 [SLP]ttyin 0xc1d35c10] getty
  456 c1cb85ac cd424000    0     1   456 0004002 [SLP]ttyin 0xc1d35810] getty
  455 c1cf03c8 cd8a5000    0     1   455 0004002 [SLP]ttyin 0xc1d35610] getty
  454 c1cb8b58 cd44e000    0     1   454 0004002 [SLP]ttyin 0xc0f76410] getty
  416 c1cb8790 cd425000    0     1   416 0000000 [SLP]nanslp 0xc06b62cc] cron
  398 c1cf01e4 cd8a4000    0     1   398 0000100 [CV]select 0xc06db394] sshd
  250 c1cb8974 cd426000    0     1   250 0000000 [CV]select 0xc06db394] syslogd
   42 c1c2eb58 c9406000    0     0     0 0000204 [SLP]- 0xc06e310c] nfsiod 3
   41 c1c2ed3c c9407000    0     0     0 0000204 [SLP]- 0xc06e3108] nfsiod 2
   40 c1cb6000 cd419000    0     0     0 0000204 [SLP]- 0xc06e3104] nfsiod 1
--More--   39 c1cb61e4 cd41a000    0     0     0 0000204 [SLP]- 0xc06e3100] nfsiod 0
   38 c1cb63c8 cd41b000    0     0     0 0000204 [SLP]vlruwt 0xc1cb63c8] vnlru
   37 c1cb65ac cd41c000    0     0     0 0000204 [SLP]syncer 0xc06b5c80] syncer
   36 c1cb6790 cd41d000    0     0     0 0000204 [SLP]psleep 0xc06db828] bufdaemon
   35 c1cb6974 cd41e000    0     0     0 000020c [SLP]pgzero 0xc06e9288] pagezero
   34 c1cb6b58 cd41f000    0     0     0 0000204 [SLP]psleep 0xc06e92e0] vmdaemon
    9 c1cb6d3c cd420000    0     0     0 0000204 [SLP]psleep 0xc06e92cc] pagedaemon
   33 c1cb8000 cd421000    0     0     0 0000204 new [IWAIT] irq8: rtc
   32 c1cb81e4 cd422000    0     0     0 0000204 new [IWAIT] irq0: clk
   31 c1bb95ac c93d0000    0     0     0 0000204 new [IWAIT] irq5: ed1
   30 c1bb9790 c93d1000    0     0     0 0000204 new [IWAIT] irq3: sio1
   29 c1bb9974 c93d2000    0     0     0 0000204 new [IWAIT] irq4: sio0
   28 c1bb9b58 c93d3000    0     0     0 0000204 [IWAIT] swi0: tty:sio
   27 c1bb9d3c c93d4000    0     0     0 0000204 [IWAIT] irq6: fdc0
   26 c1c2e000 c93d9000    0     0     0 0000204 [RUNQ] irq12: sis0
   25 c1c2e1e4 c93da000    0     0     0 0000204 [IWAIT] irq15: ata1
   24 c1c2e3c8 c93db000    0     0     0 0000204 [IWAIT] irq14: ata0
    8 c1c2e5ac c93dc000    0     0     0 0000204 [SLP]actask 0xc07c366c] acpi_task2
    7 c1c2e790 c93dd000    0     0     0 0000204 [SLP]actask 0xc07c366c] acpi_task1
    6 c1c2e974 c93de000    0     0     0 0000204 [SLP]actask 0xc07c366c] acpi_task0
--More--   23 c0f821e4 c8dce000    0     0     0 0000204 new [IWAIT] irq9: acpi0
   22 c0f823c8 c8dcf000    0     0     0 0000204 new [IWAIT] irq13:
   21 c0f825ac c8dd0000    0     0     0 0000204 [IWAIT] swi7: task queue
   20 c0f82790 c8dd1000    0     0     0 0000204 new [IWAIT] swi3: cambio
   19 c0f82974 c8dd2000    0     0     0 0000204 new [IWAIT] swi2: camnet
   18 c0f82b58 c8dd3000    0     0     0 0000204 new [IWAIT] swi5:+
   17 c0f82d3c c8dfb000    0     0     0 0000204 new [IWAIT] swi7: acpitaskq
    5 c1bb9000 c93cd000    0     1     0 0000204 [SLP]tqthr 0xc06b6ec8] taskqueue
   16 c1bb91e4 c93ce000    0     0     0 0000204 new [IWAIT] swi6:+
   15 c1bb93c8 c93cf000    0     0     0 0000204 [SLP]- 0xc06a30c0] random
    4 c0f7b000 c8d77000    0     0     0 0000204 [SLP]- 0xc06afc00] g_down
    3 c0f7b1e4 c8dc6000    0     0     0 0000204 [SLP]- 0xc06afbfc] g_up
    2 c0f7b3c8 c8dc7000    0     0     0 0000204 [SLP]- 0xc06afbf4] g_event
   14 c0f7b5ac c8dc8000    0     0     0 0000204 [IWAIT] swi1: net
   13 c0f7b790 c8dc9000    0     0     0 0000204 new [IWAIT] swi4: vm
   12 c0f7b974 c8dca000    0     0     0 000020c [RUNQ] swi8: tty:sio clock
   11 c0f7bb58 c8dcb000    0     0     0 000020c [Can run] idle
    1 c0f7bd3c c8dcc000    0     0     1 0004200 [SLP]wait 0xc0f7bd3c] init
   10 c0f82000 c8dcd000    0     0     0 0000204 [CV]ktrace 0xc06b3634] ktrace
    0 c06afd20 c081f000    0     0     0 0000200 [SLP]sched 0xc06afd20] swapper
--More--  518 c1e3b3c8 cd8bd000 1001   514   514 0002002 zomb[CPU 0] a.out
  517 c1e3b000 cd8bb000 1001   514   514 0002002 zomb[CPU 0] a.out
  516 c1cf0000 cd8a3000 1001   514   514 0002002 zomb[CPU 0] a.out
  515 c1e3b5ac cd8be000 1001   514   514 0002002 zomb[CPU 0] a.out
%%

This is the output from gdb.  Unfortunately the knote_drop frame gets
eaten by gdb for some reason, but I think the output is valuable
nevertheless.

%%
GNU gdb 5.2.1 (FreeBSD)
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-undermydesk-freebsd"...
panic messages:
---
Fatal trap 12: page fault while in kernel mode
fault virtual address	= 0x0
fault code		= supervisor read, page not present
instruction pointer	= 0x8:0xc04b25c2
stack pointer	        = 0x10:0xcd429bf0
frame pointer	        = 0x10:0xcd429c0c
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		= 514 (a.out)
Dumping 127 MB
 16 32 48 64 80 96 112
---
Reading symbols from /boot/kernel/acpi.ko...done.
Loaded symbols for /boot/kernel/acpi.ko
#0  doadump () at /freebsd/lama/src/sys/kern/kern_shutdown.c:240
240		dumping++;
(kgdb) bt
#0  doadump () at /freebsd/lama/src/sys/kern/kern_shutdown.c:240
#1  0xc043d9b5 in db_fncall (dummy1=1016, dummy2=0, dummy3=1016, 
    dummy4=0xcd4299e4 "ÈÇpÀø\003")
    at /freebsd/lama/src/sys/ddb/db_command.c:548
#2  0xc043d702 in db_command (last_cmdp=0xc06a1c80, cmd_table=0x0, 
    aux_cmd_tablep=0xc0676ef4, aux_cmd_tablep_end=0xc0676ef8)
    at /freebsd/lama/src/sys/ddb/db_command.c:346
#3  0xc043d845 in db_command_loop ()
    at /freebsd/lama/src/sys/ddb/db_command.c:472
#4  0xc0440835 in db_trap (type=12, code=0)
    at /freebsd/lama/src/sys/ddb/db_trap.c:73
#5  0xc0616c6c in kdb_trap (type=12, code=0, regs=0xcd429bb0)
    at /freebsd/lama/src/sys/i386/i386/db_interface.c:171
#6  0xc0628086 in trap_fatal (frame=0xcd429bb0, eva=0)
    at /freebsd/lama/src/sys/i386/i386/trap.c:814
#7  0xc0627d52 in trap_pfault (frame=0xcd429bb0, usermode=0, eva=0)
    at /freebsd/lama/src/sys/i386/i386/trap.c:733
#8  0xc062790d in trap (frame=
      {tf_fs = 24, tf_es = -1043005424, tf_ds = 16, tf_edi = -1042951920, tf_esi = -1042952192, tf_ebp = -851272692, tf_isp = -851272740, tf_ebx = -1041871680, tf_edx = 0, tf_ecx = 1, tf_eax = 1, tf_trapno = 12, tf_err = 0, tf_eip = -1068816958, tf_cs = 8, tf_eflags = 66051, tf_esp = -1042952140, tf_ss = 0})
    at /freebsd/lama/src/sys/i386/i386/trap.c:418
---Type <return> to continue, or q <return> to quit---
#9  0xc0618618 in calltrap () at {standard input}:102
#10 0xc04b1cd0 in kqueue_scan (fp=0xc1e64cc0, maxevents=1, ulistp=0x8049b40, 
    tsp=0xc1d5d000, td=0xc1cb9000)
    at /freebsd/lama/src/sys/kern/kern_event.c:755
#11 0xc04b14d1 in kevent (td=0xc1cb9000, uap=0xcd429d10)
    at /freebsd/lama/src/sys/kern/kern_event.c:483
#12 0xc06283a3 in syscall (frame=
      {tf_fs = 47, tf_es = 47, tf_ds = 47, tf_edi = -1077937184, tf_esi = -1077937176, tf_ebp = -1077937224, tf_isp = -851272332, tf_ebx = 1, tf_edx = 134519636, tf_ecx = -1077938288, tf_eax = 363, tf_trapno = 12, tf_err = 2, tf_eip = 671859087, tf_cs = 31, tf_eflags = 658, tf_esp = -1077938308, tf_ss = 47})
    at /freebsd/lama/src/sys/i386/i386/trap.c:1006
#13 0xc061866d in Xint0x80_syscall () at {standard input}:144
---Can't read userspace from dump, or kernel process---

(kgdb) f 10
#10 0xc04b1cd0 in kqueue_scan (fp=0xc1e64cc0, maxevents=1, ulistp=0x8049b40, 
    tsp=0xc1d5d000, td=0xc1cb9000)
    at /freebsd/lama/src/sys/kern/kern_event.c:755
755				knote_drop(kn, td);
(kgdb) l
750			if (kn->kn_flags & EV_ONESHOT) {
751				kn->kn_status &= ~KN_QUEUED;
752				kq->kq_count--;
753				splx(s);
754				kn->kn_fop->f_detach(kn);
755				knote_drop(kn, td);
756				s = splhigh();
757                     } else if (kn->kn_flags & EV_CLEAR) {
758				kn->kn_data = 0;
759				kn->kn_fflags = 0;
(kgdb) p kn->kn_fop->f_isfd
$3 = 0
(kgdb) p kn->kn_id
There is no member named kn_id.
(kgdb) p kn->kn_kevent.ident
$4 = 518
(kgdb) p td->td_proc->p_fd->fd_knhashmask
$5 = 63
(kgdb) p (518 ^ (518 >> 8)) & 63
$6 = 4
(kgdb) p td->td_proc->p_fd->fd_knhash[4]
$7 = {slh_first = 0x0}
(kgdb) q
%%

Finally here is the interesting part from the disassembled kern_event.o:

%%
static void
knote_drop(struct knote *kn, struct thread *td)
{
    1900:       55                      push   %ebp
    1901:       89 e5                   mov    %esp,%ebp
    1903:       57                      push   %edi
[...]
        SLIST_REMOVE(list, kn, knote, kn_link);
    19b3:       39 1f                   cmp    %ebx,(%edi)
    19b5:       75 09                   jne    19c0 <knote_drop+0xc0>
    19b7:       8b 03                   mov    (%ebx),%eax
    19b9:       89 07                   mov    %eax,(%edi)
    19bb:       eb 1f                   jmp    19dc <knote_drop+0xdc>
    19bd:       8d 76 00                lea    0x0(%esi),%esi
    19c0:       8b 17                   mov    (%edi),%edx
    19c2:       39 1a                   cmp    %ebx,(%edx)

This line leeds to the page fault because edx is 0.  Obviously the SLIST
list is empty although it shouldn't be.

    19c4:       74 10                   je     19d6 <knote_drop+0xd6>
    19c6:       8d 76 00                lea    0x0(%esi),%esi
    19c9:       8d bc 27 00 00 00 00    lea    0x0(%edi,1),%edi
    19d0:       8b 12                   mov    (%edx),%edx
    19d2:       39 1a                   cmp    %ebx,(%edx)
    19d4:       75 fa                   jne    19d0 <knote_drop+0xd0>
    19d6:       8b 02                   mov    (%edx),%eax
    19d8:       8b 00                   mov    (%eax),%eax
    19da:       89 02                   mov    %eax,(%edx)
        if (kn->kn_status & KN_QUEUED)
%%

>Fix:
Not known at this time.

--- kqueue-crash.c begins here ---
#include <sys/types.h>
#include <sys/event.h>

#include <err.h>
#include <unistd.h>

struct kevent	kev[2];
int		chfd, kqfd;

void
new_child(void)
{
	static char	buf[32] = "abc";
	int		pipefd[2], i, pid;

	if (pipe(pipefd) != 0)
		err(1, "pipe");
	switch (pid = fork()) {
	case -1:
		err(1, "fork");
	case 0:
		for (i = 0; i < 1024; i++)
			if (write(pipefd[1], buf, sizeof(buf)) != sizeof(buf))
				err(1, "write");
		exit(0);
	}
	close(pipefd[1]);
	chfd = pipefd[0];
	EV_SET(&kev[0], chfd, EVFILT_READ, EV_ADD, 0, 0, NULL);
	EV_SET(&kev[1], pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL);
	if (kevent(kqfd, kev, 2, NULL, 0, NULL) == -1)
		err(1, "kevent");
}

int
main(void)
{
	char	buf[1024];
	ssize_t	n;

	if ((kqfd = kqueue()) == -1)
		err(1, "kqueue");
	new_child();
	while (kevent(kqfd, NULL, 0, kev, 1, NULL) == 1)
		if (kev[0].filter == EVFILT_READ) {
			if ((n = read(chfd, buf, sizeof buf)) < 0)
				err(1, "read");
			else if (n == 0)
				new_child();
		}
	err(1, "kevent");
}
--- kqueue-crash.c ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list