NetBSD Problem Report #40570

From dholland@eecs.harvard.edu  Sat Feb  7 04:24:57 2009
Return-Path: <dholland@eecs.harvard.edu>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by narn.NetBSD.org (Postfix) with ESMTP id 172CB63C07F
	for <gnats-bugs@gnats.NetBSD.org>; Sat,  7 Feb 2009 04:24:57 +0000 (UTC)
Message-Id: <20090207042348.5C4A4F788@tanaqui.eecs.harvard.edu>
Date: Fri,  6 Feb 2009 23:23:48 -0500 (EST)
From: dholland@eecs.harvard.edu
Reply-To: dholland@eecs.harvard.edu
To: gnats-bugs@gnats.NetBSD.org
Subject: portalfs + puffs = panic
X-Send-Pr-Version: 3.95

>Number:         40570
>Category:       kern
>Synopsis:       file descriptor passing = panic
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Feb 07 04:25:00 +0000 2009
>Closed-Date:    Wed Mar 18 08:15:25 +0000 2009
>Last-Modified:  Wed Mar 18 08:15:25 +0000 2009
>Originator:     David A. Holland
>Release:        NetBSD 5.99.7
>Organization:
>Environment:
System: NetBSD malfoy 5.99.7 NetBSD 5.99.7 (MALFOY) #15: Mon Jan 12 15:44:34 EST 2009 root@malfoy:/usr/src/sys/arch/i386/compile/MALFOY i386
Architecture: i386
Machine: i386
>Description:

portalfs+puffs dies a horrible death. By request of pooka@:

# mount_puffsportal /usr/share/examples/mount_portal/tcp.1.conf /mnt
# cat /mnt/tcp/localhost/daytime
uvm_fault(0xcb00db64, 0xb9dc2000, 1) -> 0xe
fatal page fault in supervisor mode
trap type 6 code 0 eip c01d7153 cs 8 eflags 10282 cr2 b9dc2ed8 ilevel 4
kernel: supervisor trap page fault, code=0
Stopped in pid 585.1 (mount_puffsporta) at     netbsd:fd_putfile+0x33: movl 0(%eax),%esi
db{0}> bt
fd_putfile(bbbcaf78,caf9cbc0,4,0,c039055c,cb010280,4,cae97000,c08b9b00,0) at netbsd:fd_putfile+0x33
unp_internalize(cb07bb84,bbabfe30,c0940d38,4,cb00db64,cae96008,c0940d3c,caf9cbc0,0,0) at netbsd:unp_internalize+0x10e
uipc_usrreq(c0980a1c,9,c0940d00,0,c08b9b00,cb010280,c08b9b00,8b9b00,c0980a74,10) at netbsd:uipc_usrreq+0x2c7
sosend(c0980a1c,0,cb08bc58,c0940d00,c08b9b00,0,cb010280,1,0,cb07bc18) at netbsd:sosend+0x403
do_sys_sendmsg(cb010280,6,cb07bcb8,0,cb07bd28,cb00db64,cb07bd3c,c02e2b30,0,0) at netbsd:do_sys_sendmsg+0x2fb
sys_sendmsg(cb010280,cb07bd00,cb07bd28,bbbe7b1c,bbbe7000,cb00db64,1,6,bbabfdfc,0) at netbsd:sys_sendmsg+0x58
syscall(cb07bd48,bb9000b3, blah blah blah) at netbsd:syscall+0xc8

Usual caveats about hand-typed traces apply.

I also question the trace, because fd_putfile takes one argument
that's supposed to be a file handle number. Although if someone's
really passing 0xbbbcaf78 as a file handle, it would explain the crash...

>How-To-Repeat:

as above

>Fix:
.

>Release-Note:

>Audit-Trail:

From: Antti Kantee <pooka@cs.hut.fi>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/40570
Date: Sat, 7 Feb 2009 14:55:31 +0200

 Two issues: first of all, mount_puffsportal does not use the portalfs
 in any way, so I think we could drop "portalfs" from the synopsis.
 Second, I believe this is a panic common to all userland programs doing
 file descriptor passing.  I suggest changing the synopsis to e.g. "file
 descriptor passing = panic" ... and am in fact doing so.

 As this is a (potential) local DoS, I think it's a priority for 5.0.

 The application code which corresponds to the kernel stack trace is:

 static int
 sendfd(int s, int fd, int error)
 {
         struct cmsghdr *cmp;
         struct msghdr msg;
         struct iovec iov;
         ssize_t n;
         int rv;

         rv = 0;
         cmp = emalloc(CMSG_LEN(sizeof(int)));

         iov.iov_base = &error;
         iov.iov_len = sizeof(int);

         cmp->cmsg_level = SOL_SOCKET;
         cmp->cmsg_type = SCM_RIGHTS;
         cmp->cmsg_len = CMSG_LEN(sizeof(int));

         msg.msg_iov = &iov;
         msg.msg_iovlen = 1;
         msg.msg_name = NULL;
         msg.msg_namelen = 0;
         msg.msg_control = cmp;
         msg.msg_controllen = CMSG_LEN(sizeof(int));
         *(int *)CMSG_DATA(cmp) = fd;

         n = sendmsg(s, &msg, 0);
         if (n == -1)
                 rv = errno;
         else if (n < sizeof(int))
                 rv = EPROTO;

         free(cmp);
         return rv;
 }

From: Antti Kantee <pooka@cs.hut.fi>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/40570
Date: Sun, 8 Feb 2009 18:42:40 +0200

 Ok, it's an error branch error.  I extracted the necessary stuff from
 puffs_portal.c and made it use rump syscalls:

 pain-rustique:47:~> cc crash.c -g -lrump -lrumpvfs -lrumpnet -lrumpnet_local -lrumpnet_net -lrumpuser -lpthread
 pain-rustique:48:~> ./a.out
 sysctl_createv: sysctl_locate(disknames) returned 2
 sysctl_createv: sysctl_locate(iostatnames) returned 2
 sysctl_createv: sysctl_locate(iostats) returned 2
 rn_init: radix functions require max_keylen be set
 Segmentation fault (core dumped)
 pain-rustique:49:~> gdb a.out a.out.core                                        GNU gdb 6.5
 [...]
 Program terminated with signal 11, Segmentation fault.
 #0  0xbbbd11e0 in fd_putfile (fd=1231231)
     at /usr/allsrc/src/sys/rump/librump/rumpkern/../../../kern/kern_descrip.c:380
 380             ff = fdp->fd_ofiles[fd];
 (gdb) print fd
 $1 = 1231231

 So it tries to put a garbage value.  With uipc_ussreq.c rev 1.120 included
 in librumpnet_local:

 pain-rustique:50:~> ./a.out 
 sysctl_createv: sysctl_locate(disknames) returned 2
 sysctl_createv: sysctl_locate(iostatnames) returned 2
 sysctl_createv: sysctl_locate(iostats) returned 2
 rn_init: radix functions require max_keylen be set
 a.out: sendmsg: Bad file descriptor
 pain-rustique:51:~> 

 Test program (if someone's bored, this is a good base for a AF_LOCAL
 regression test .. ):
 === snip ===
 #include <sys/types.h>
 #include <sys/socket.h>

 #include <rump/rump.h>
 #include <rump/rump_syscalls.h>

 #include <err.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #include <util.h>

 static int
 sendfd(int s, int fd, int error)
 {
 	struct cmsghdr *cmp;
 	struct msghdr msg;
 	struct iovec iov;
 	ssize_t n;
 	int rv;

 	rv = 0;
 	cmp = malloc(CMSG_LEN(sizeof(int)));

 	iov.iov_base = &error;
 	iov.iov_len = sizeof(int);

 	cmp->cmsg_level = SOL_SOCKET;
 	cmp->cmsg_type = SCM_RIGHTS;
 	cmp->cmsg_len = CMSG_LEN(sizeof(int));

 	msg.msg_iov = &iov;
 	msg.msg_iovlen = 1;
 	msg.msg_name = NULL;
 	msg.msg_namelen = 0;
 	msg.msg_control = cmp;
 	msg.msg_controllen = CMSG_LEN(sizeof(int));
 	*(int *)CMSG_DATA(cmp) = fd;

 	n = rump_sys_sendmsg(s, &msg, 0);
 	warn("sendmsg");
 	if (n == -1)
 		rv = errno;
 	else if (n < sizeof(int))
 		rv = EPROTO;

 	free(cmp);
 	return rv;
 }

 int
 main()
 {
 	int s[2];
 	int fd, error = 0;
 	int data;

 	rump_init();

 	if (rump_sys_socketpair(AF_LOCAL, SOCK_STREAM, 0, s) == -1)
 		err(1, "socket");

 	sendfd(s[1], 1231231, error);
 }
 === snip ===

State-Changed-From-To: open->feedback
State-Changed-By: pooka@NetBSD.org
State-Changed-When: Sun, 08 Feb 2009 18:52:16 +0200
State-Changed-Why:
is the kernel panic gone with uipc_usrreq.c 1.120?


State-Changed-From-To: feedback->closed
State-Changed-By: pooka@NetBSD.org
State-Changed-When: Wed, 18 Mar 2009 11:15:25 +0300
State-Changed-Why:
problem gone and netbsd-5 pullup done


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.