kern/91224: sending file descriptors via AF_UNIX socket crashes
kernel
Vladimir Kotal
vlada at devnull.cz
Mon Jan 2 07:00:19 PST 2006
>Number: 91224
>Category: kern
>Synopsis: sending file descriptors via AF_UNIX socket crashes kernel
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Jan 02 15:00:16 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Vladimir Kotal
>Release: 6.0-RELEASE
>Organization:
>Environment:
FreeBSD mailnfs1 6.0-RELEASE FreeBSD 6.0-RELEASE #0: Thu Dec 22 18:33:19 CET 2005 x at mailnfs1:/usr/src/sys/i386/compile/mailnfs i386
>Description:
When playing with AF_UNIX sockets, I have discovered that ancient code which crashed FreeBSD 3.1 still "works" on more recent versions of FreeBSD.
The original bug report can be found at
http://www.securiteam.com/exploits/2FUQ4QAQRK.html
Fixed code (so that it compiles cleanly) is here:
http://techie.devnull.cz/public/AF_UNIX-FreeBSD-crash.c
The backtrace looks like this:
#0 doadump () at pcpu.h:165
#1 0xc05deb7e in boot (howto=260) at ../../../kern/kern_shutdown.c:399
#2 0xc05dee14 in panic (fmt=0xc07adf73 "%s")
at ../../../kern/kern_shutdown.c:555
#3 0xc076ee10 in trap_fatal (frame=0xe6cf5a44, eva=0)
at ../../../i386/i386/trap.c:831
#4 0xc076eb7b in trap_pfault (frame=0xe6cf5a44, usermode=0, eva=0)
at ../../../i386/i386/trap.c:742
#5 0xc076e7b9 in trap (frame=
{tf_fs = -422641656, tf_es = 40, tf_ds = 40, tf_edi = -1042289368, tf_esi = -1030220736, tf_ebp = -422618400, tf_isp = -422618512, tf_ebx = -1044382336, tf_edx = -1047046376, tf_ecx = -1043903488, tf_eax = 0, tf_trapno = 12, tf_err = 0, tf_eip = -1067719191, tf_cs = 32, tf_eflags = 66050, tf_esp = 0, tf_ss = 0})
at ../../../i386/i386/trap.c:432
#6 0xc075dfaa in calltrap () at ../../../i386/i386/exception.s:139
#7 0xc05be5e9 in closef (fp=0xc1bffd80, td=0x0)
at ../../../kern/kern_descrip.c:1877
#8 0xc0622958 in unp_discard (fp=0xc1bffd80)
at ../../../kern/uipc_usrreq.c:1888
#9 0xc0622854 in unp_scan (m0=0xc1dfe600, op=0xc06228dc <unp_discard>)
at ../../../kern/uipc_usrreq.c:1855
#10 0xc0622721 in unp_dispose (m=0x0) at ../../../kern/uipc_usrreq.c:1802
#11 0xc06181f8 in sorflush (so=0xc2e162c8) at ../../../kern/uipc_socket.c:1479
#12 0xc0620699 in unp_detach (unp=0xc3b9cc08)
at ../../../kern/uipc_usrreq.c:805
#13 0xc061f562 in uipc_detach (so=0x0) at ../../../kern/uipc_usrreq.c:256
#14 0xc0616840 in soclose (so=0xc2e162c8) at ../../../kern/uipc_socket.c:475
#15 0xc0606783 in soo_close (fp=0xc1e14558, td=0xc1c74c00)
at ../../../kern/sys_socket.c:317
#16 0xc05c040c in fdrop_locked (fp=0xc1e14558, td=0xc1c74c00) at file.h:289
#17 0xc05c035d in fdrop (fp=0xc1e14558, td=0xc1c74c00)
at ../../../kern/kern_descrip.c:2101
#18 0xc05be98b in closef (fp=0xc1e14558, td=0xc1c74c00)
at ../../../kern/kern_descrip.c:1921
#19 0xc05bbdb9 in close (td=0xc1c74c00, uap=0x0)
at ../../../kern/kern_descrip.c:1004
#20 0xc076f127 in syscall (frame=
{tf_fs = 59, tf_es = 59, tf_ds = 59, tf_edi = 671408776, tf_esi = -1077940908, tf_ebp = -1077941032, tf_isp = -422617756, tf_ebx = 1, tf_edx = 134515882, tf_ecx = 9, tf_eax = 6, tf_trapno = 0, tf_err = 2, tf_eip = 671836115, tf_cs = 51, tf_eflags = 658, tf_esp = -1077941348, tf_ss = 59})
at ../../../i386/i386/trap.c:976
#21 0xc075dfff in Xint0x80_syscall () at ../../../i386/i386/exception.s:200
#22 0x00000033 in ?? ()
The kernel crash occured in closef():
(kgdb) fr 7
#7 0xc05be5e9 in closef (fp=0xc1bffd80, td=0x0)
at ../../../kern/kern_descrip.c:1877
1877 if ((td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) {
(kgdb) l
1872 if (fp->f_type == DTYPE_VNODE) {
1873 int vfslocked;
1874
1875 vp = fp->f_vnode;
1876 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1877 if ((td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) {
1878 lf.l_whence = SEEK_SET;
1879 lf.l_start = 0;
1880 lf.l_len = 0;
1881 lf.l_type = F_UNLCK;
because of:
(kgdb) p &td->td_proc
$1 = (struct proc **) 0x0
(kgdb) p td
$2 = (struct thread *) 0x0
>How-To-Repeat:
1. download source code mentioned in previous section
2. compile the code
3. run the code
>Fix:
It seems that the root cause is in unp_discard():
static void
unp_discard(struct file *fp)
{
FILE_LOCK(fp);
fp->f_msgcount--;
unp_rights--;
FILE_UNLOCK(fp);
(void) closef(fp, (struct thread *)NULL);
}
because it calls closef() with second param which is NULL pointer.
Possible solutions:
- patch unp_discard() so it fills something more sane into second param
- fix closef() so it checks NULL pointer
side note: This might be vaguely related to ancient kern/4345 bug report (Kernel panic is caused by passing file descriptors through AF_UNIX socket)
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list