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:
(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.