NetBSD Problem Report #50995
From www@NetBSD.org Wed Mar 23 17:07:12 2016
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id 688307A0EB
for <gnats-bugs@gnats.NetBSD.org>; Wed, 23 Mar 2016 17:07:12 +0000 (UTC)
Message-Id: <20160323170711.547CF7ACB7@mollari.NetBSD.org>
Date: Wed, 23 Mar 2016 17:07:11 +0000 (UTC)
From: prlw1@cam.ac.uk
Reply-To: prlw1@cam.ac.uk
To: gnats-bugs@NetBSD.org
Subject: sigsegv in recv()
X-Send-Pr-Version: www-1.0
>Number: 50995
>Category: pkg
>Synopsis: sigsegv in recv()
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: pkg-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Mar 23 17:10:00 +0000 2016
>Last-Modified: Wed Apr 20 13:55:01 +0000 2016
>Originator: Patrick Welche
>Release: NetBSD-7/amd64
>Organization:
>Environment:
>Description:
Running pkgsrc dansguardian 2.12.0.3nb4 on a busy NetBSD-7/amd64 (both
original 7 kernel and most recent from 7 branch), dansguardian will run
fine for say a fortnight, then run through a patch of coredumps as a
result of a SIGSEGV. There is no apparent pattern. Could also coredump
on startup.
NetBSD-5/i386 does not exhibit the problem.
http://www.netbsd.org/~sborrill/dansguardian/
contains the patches that were added to dansguardian to try to see
whether the issue was with the application or the recv() call.
BaseSocket.cc is the patched source file. The syslog line is not
reached. "dansguardian" is the 9.2M binary with symbols, dansguardian.core
one of the 43M core files. core file says:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 BaseSocket::readFromSocket (this=0x7f7f00000001,
this@entry=0x7f7fffffd320, buff=buff@entry=0x7f7fffffd25e "",
len=len@entry=1, flags=flags@entry=0, timeout=timeout@entry=360,
check_first=check_first@entry=true,
honour_reloadconfig=honour_reloadconfig@entry=true) at BaseSocket.cpp:476
476 rc = recv(sck, buff, cnt, flags);
Conjecture: another manifestation of the recvfrom returns EAGAIN loop problem.
>How-To-Repeat:
>Fix:
>Audit-Trail:
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@NetBSD.org, pkg-manager@netbsd.org, gnats-admin@netbsd.org,
pkgsrc-bugs@netbsd.org
Cc:
Subject: Re: pkg/50995: sigsegv in recv()
Date: Wed, 23 Mar 2016 13:31:49 -0400
On Mar 23, 5:10pm, prlw1@cam.ac.uk (prlw1@cam.ac.uk) wrote:
-- Subject: pkg/50995: sigsegv in recv()
| >Number: 50995
| >Category: pkg
| >Synopsis: sigsegv in recv()
| >Confidential: no
| >Severity: serious
| >Priority: high
| >Responsible: pkg-manager
| >State: open
| >Class: sw-bug
| >Submitter-Id: net
| >Arrival-Date: Wed Mar 23 17:10:00 +0000 2016
| >Originator: Patrick Welche
| >Release: NetBSD-7/amd64
| >Organization:
| >Environment:
| >Description:
| Running pkgsrc dansguardian 2.12.0.3nb4 on a busy NetBSD-7/amd64 (both
| original 7 kernel and most recent from 7 branch), dansguardian will run
| fine for say a fortnight, then run through a patch of coredumps as a
| result of a SIGSEGV. There is no apparent pattern. Could also coredump
| on startup.
|
| NetBSD-5/i386 does not exhibit the problem.
|
| http://www.netbsd.org/~sborrill/dansguardian/
|
| contains the patches that were added to dansguardian to try to see
| whether the issue was with the application or the recv() call.
| BaseSocket.cc is the patched source file. The syslog line is not
| reached. "dansguardian" is the 9.2M binary with symbols, dansguardian.core
| one of the 43M core files. core file says:
|
| Program terminated with signal SIGSEGV, Segmentation fault.
| #0 BaseSocket::readFromSocket (this=0x7f7f00000001,
| this@entry=0x7f7fffffd320, buff=buff@entry=0x7f7fffffd25e "",
| len=len@entry=1, flags=flags@entry=0, timeout=timeout@entry=360,
| check_first=check_first@entry=true,
| honour_reloadconfig=honour_reloadconfig@entry=true) at BaseSocket.cpp:476
|
| 476 rc = recv(sck, buff, cnt, flags);
|
| Conjecture: another manifestation of the recvfrom returns EAGAIN loop problem.
| >How-To-Repeat:
Well, in this case, this=0x7f7f00000001 does not seem right; for one, it should
be aligned. Now you are asking this->sck as the first argument of the recv()
call, and
22175 1 dansguardian PSIG SIGSEGV SIG_DFL: code=SEGV_MAPERR, addr=0x7f7f00000011, trap=6)
Which looks like it dereferencing it and dying before it gets a chance to call
recv(). I wonder what's corrupting memory. The socket is coming from the stack
so the address of "this" should look a lot like the others, but it looks like
it lost it's bottom 32 bits... Perhaps something overwrote that word on the
stack with a 0?
christos
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@NetBSD.org, pkg-manager@netbsd.org, gnats-admin@netbsd.org,
pkgsrc-bugs@netbsd.org
Cc:
Subject: Re: pkg/50995: sigsegv in recv()
Date: Wed, 23 Mar 2016 14:15:35 -0400
On Mar 23, 5:10pm, prlw1@cam.ac.uk (prlw1@cam.ac.uk) wrote:
-- Subject: pkg/50995: sigsegv in recv()
Is that netbsd-7 with these patches applied?
uipc_syscalls.c: 1.172.2.1.0.2
revision 1.172.2.2
date: 2015-11-07 19:55:11 -0500; author: riz; state: Exp; lines: +8 -7; commitid: W3wKhbmbFC8QZdIy;
Pull up following revision(s) (requested by christos in ticket #1018):
sys/kern/uipc_syscalls.c: revision 1.181
Don't overwrite the user iov pointer in sendmmsg. Make the send and receive
code look the same.
revision 1.172.2.1
date: 2015-08-08 11:45:47 -0400; author: martin; state: Exp; lines: +10 -3; commitid: ZgH9XMVFrI9IStwy;
Pull up following revision(s) (requested by maxv in ticket #942):
sys/kern/uipc_syscalls.c: revision 1.179
Memory leak. Triggerable from an unprivileged user via COMPAT_43.
From: Patrick Welche <prlw1@cam.ac.uk>
To: Christos Zoulas <christos@zoulas.com>
Cc: gnats-bugs@NetBSD.org, pkg-manager@netbsd.org, gnats-admin@netbsd.org,
pkgsrc-bugs@netbsd.org
Subject: Re: pkg/50995: sigsegv in recv()
Date: Wed, 23 Mar 2016 18:21:33 +0000
On Wed, Mar 23, 2016 at 02:15:35PM -0400, Christos Zoulas wrote:
> On Mar 23, 5:10pm, prlw1@cam.ac.uk (prlw1@cam.ac.uk) wrote:
> -- Subject: pkg/50995: sigsegv in recv()
>
> Is that netbsd-7 with these patches applied?
>
> uipc_syscalls.c: 1.172.2.1.0.2
>
> revision 1.172.2.2
> date: 2015-11-07 19:55:11 -0500; author: riz; state: Exp; lines: +8 -7; commitid: W3wKhbmbFC8QZdIy;
> Pull up following revision(s) (requested by christos in ticket #1018):
> sys/kern/uipc_syscalls.c: revision 1.181
> Don't overwrite the user iov pointer in sendmmsg. Make the send and receive
> code look the same.
>
> revision 1.172.2.1
> date: 2015-08-08 11:45:47 -0400; author: martin; state: Exp; lines: +10 -3; commitid: ZgH9XMVFrI9IStwy;
> Pull up following revision(s) (requested by maxv in ticket #942):
> sys/kern/uipc_syscalls.c: revision 1.179
> Memory leak. Triggerable from an unprivileged user via COMPAT_43.
Unfortunately it seems to be:
# ident /netbsd | grep uipc_syscalls.c
$NetBSD: uipc_syscalls.c,v 1.172.2.2 2015/11/08 00:55:11 riz Exp $
From: Patrick Welche <prlw1@cam.ac.uk>
To: Christos Zoulas <christos@zoulas.com>
Cc: gnats-bugs@NetBSD.org, pkg-manager@netbsd.org, gnats-admin@netbsd.org,
pkgsrc-bugs@netbsd.org
Subject: Re: pkg/50995: sigsegv in recv()
Date: Wed, 30 Mar 2016 14:43:30 +0100
On Wed, Mar 23, 2016 at 01:31:49PM -0400, Christos Zoulas wrote:
> | Program terminated with signal SIGSEGV, Segmentation fault.
> | #0 BaseSocket::readFromSocket (this=0x7f7f00000001,
> | this@entry=0x7f7fffffd320, buff=buff@entry=0x7f7fffffd25e "",
> | len=len@entry=1, flags=flags@entry=0, timeout=timeout@entry=360,
> | check_first=check_first@entry=true,
> | honour_reloadconfig=honour_reloadconfig@entry=true) at BaseSocket.cpp:476
> |
> | 476 rc = recv(sck, buff, cnt, flags);
> |
> | Conjecture: another manifestation of the recvfrom returns EAGAIN loop problem.
> | >How-To-Repeat:
>
> Well, in this case, this=0x7f7f00000001 does not seem right; for one, it should
> be aligned. Now you are asking this->sck as the first argument of the recv()
> call, and
> 22175 1 dansguardian PSIG SIGSEGV SIG_DFL: code=SEGV_MAPERR, addr=0x7f7f00000011, trap=6)
>
> Which looks like it dereferencing it and dying before it gets a chance to call
> recv(). I wonder what's corrupting memory. The socket is coming from the stack
> so the address of "this" should look a lot like the others, but it looks like
> it lost it's bottom 32 bits... Perhaps something overwrote that word on the
> stack with a 0?
In terms of the code (class UDSocket : public BaseSocket):
bool getsock_fromparent(UDSocket &fd)
{
...
rc = fd.readFromSocket(&buf, 1, 0, 360, true, true);
and here, fd.sck = 256 at address
(gdb) print &fd
$6 = (UDSocket *) 0x7f7fffffd320
(gdb) print &fd.sck
$4 = (int *) 0x7f7fffffd330
so how
(gdb) print this
$7 = (BaseSocket * const) 0x7f7f00000001
isn't == 0x7f7fffffd320, I don't know...
From: Patrick Welche <prlw1@cam.ac.uk>
To: Christos Zoulas <christos@zoulas.com>
Cc: gnats-bugs@netbsd.org
Subject: Re: pkg/50995: sigsegv in recv()
Date: Wed, 30 Mar 2016 17:11:51 +0100
> (gdb) print this
> $7 = (BaseSocket * const) 0x7f7f00000001
>
> isn't == 0x7f7fffffd320, I don't know...
>
> > | #0 BaseSocket::readFromSocket (this=0x7f7f00000001,
> > | this@entry=0x7f7fffffd320, buff=buff@entry=0x7f7fffffd25e "",
Note that @entry *this is the expected 0x7f7fffffd320, and all that
happens of note is a call to select() and the recv() mentioned above.
From: David Holland <dholland-pbugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: pkg/50995: sigsegv in recv()
Date: Thu, 31 Mar 2016 04:56:35 +0000
On Wed, Mar 30, 2016 at 04:15:00PM +0000, Patrick Welche wrote:
> > (gdb) print this
> > $7 = (BaseSocket * const) 0x7f7f00000001
> >
> > isn't == 0x7f7fffffd320, I don't know...
> >
> > > | #0 BaseSocket::readFromSocket (this=0x7f7f00000001,
> > > | this@entry=0x7f7fffffd320, buff=buff@entry=0x7f7fffffd25e "",
>
> Note that @entry *this is the expected 0x7f7fffffd320, and all that
> happens of note is a call to select() and the recv() mentioned above.
Wild speculation: is the number-of-fds argument to select larger than
FD_SETSIZE?
--
David A. Holland
dholland@netbsd.org
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@NetBSD.org, pkg-manager@netbsd.org, gnats-admin@netbsd.org,
pkgsrc-bugs@netbsd.org, prlw1@cam.ac.uk
Cc:
Subject: Re: pkg/50995: sigsegv in recv()
Date: Thu, 31 Mar 2016 11:58:27 -0400
On Mar 31, 5:00am, dholland-pbugs@netbsd.org (David Holland) wrote:
-- Subject: Re: pkg/50995: sigsegv in recv()
| The following reply was made to PR pkg/50995; it has been noted by GNATS.
|
| From: David Holland <dholland-pbugs@netbsd.org>
| To: gnats-bugs@NetBSD.org
| Cc:
| Subject: Re: pkg/50995: sigsegv in recv()
| Date: Thu, 31 Mar 2016 04:56:35 +0000
|
| On Wed, Mar 30, 2016 at 04:15:00PM +0000, Patrick Welche wrote:
| > > (gdb) print this
| > > $7 = (BaseSocket * const) 0x7f7f00000001
| > >
| > > isn't == 0x7f7fffffd320, I don't know...
| > >
| > > > | #0 BaseSocket::readFromSocket (this=0x7f7f00000001,
| > > > | this@entry=0x7f7fffffd320, buff=buff@entry=0x7f7fffffd25e "",
| >
| > Note that @entry *this is the expected 0x7f7fffffd320, and all that
| > happens of note is a call to select() and the recv() mentioned above.
|
| Wild speculation: is the number-of-fds argument to select larger than
| FD_SETSIZE?
Perhaps! Add a check in BaseSocket::checkForInput().
christos
From: Patrick Welche <prlw1@cam.ac.uk>
To: gnats-bugs@NetBSD.org
Cc: pkg-manager@netbsd.org, gnats-admin@netbsd.org, pkgsrc-bugs@netbsd.org
Subject: Re: pkg/50995: sigsegv in recv()
Date: Fri, 1 Apr 2016 09:19:40 +0100
On Thu, Mar 31, 2016 at 05:00:01AM +0000, David Holland wrote:
> The following reply was made to PR pkg/50995; it has been noted by GNATS.
>
> From: David Holland <dholland-pbugs@netbsd.org>
> To: gnats-bugs@NetBSD.org
> Cc:
> Subject: Re: pkg/50995: sigsegv in recv()
> Date: Thu, 31 Mar 2016 04:56:35 +0000
>
> On Wed, Mar 30, 2016 at 04:15:00PM +0000, Patrick Welche wrote:
> > > (gdb) print this
> > > $7 = (BaseSocket * const) 0x7f7f00000001
> > >
> > > isn't == 0x7f7fffffd320, I don't know...
> > >
> > > > | #0 BaseSocket::readFromSocket (this=0x7f7f00000001,
> > > > | this@entry=0x7f7fffffd320, buff=buff@entry=0x7f7fffffd25e "",
> >
> > Note that @entry *this is the expected 0x7f7fffffd320, and all that
> > happens of note is a call to select() and the recv() mentioned above.
>
> Wild speculation: is the number-of-fds argument to select larger than
> FD_SETSIZE?
Good point! The fd handling in general in dansguardian is a mess...
Looking at the coredump:
fd.sck = 256
fd_set fdSet;
FD_ZERO(&fdSet); // clear the set
FD_SET(sck, &fdSet); // add fd to the set
timeval t; // timeval struct
t.tv_sec = 0;
t.tv_usec = 0;
if (selectEINTR(sck + 1, &fdSet, NULL, NULL, &t) < 1) {
return false;
}
so the number-of-fds argument is 257
src/sys/sys/fd_set.h:
/*
* Select uses bit fields of file descriptors. These macros manipulate
* such bit fields. Note: FD_SETSIZE may be defined by the user.
*/
#ifndef FD_SETSIZE
#define FD_SETSIZE 256
#endif
so you have a hole in one! (I don't see FD_SETSIZE defined by the user...)
(How can this trash the stack?)
From: Patrick Welche <prlw1@cam.ac.uk>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: pkg/50995: sigsegv in recv()
Date: Fri, 1 Apr 2016 09:45:51 +0100
On Fri, Apr 01, 2016 at 09:19:40AM +0100, Patrick Welche wrote:
> #define FD_SETSIZE 256
and how does FD_SETSIZE tie in with
kern.maxfiles = 16384
?
From: Joerg Sonnenberger <joerg@britannica.bec.de>
To: gnats-bugs@NetBSD.org
Cc: pkg-manager@netbsd.org, gnats-admin@netbsd.org, pkgsrc-bugs@netbsd.org,
prlw1@cam.ac.uk
Subject: Re: pkg/50995: sigsegv in recv()
Date: Fri, 1 Apr 2016 10:53:32 +0200
On Fri, Apr 01, 2016 at 08:50:01AM +0000, Patrick Welche wrote:
> The following reply was made to PR pkg/50995; it has been noted by GNATS.
>
> From: Patrick Welche <prlw1@cam.ac.uk>
> To: gnats-bugs@NetBSD.org
> Cc:
> Subject: Re: pkg/50995: sigsegv in recv()
> Date: Fri, 1 Apr 2016 09:45:51 +0100
>
> On Fri, Apr 01, 2016 at 09:19:40AM +0100, Patrick Welche wrote:
> > #define FD_SETSIZE 256
>
> and how does FD_SETSIZE tie in with
>
> kern.maxfiles = 16384
Completely unrelated. That's the global FD limit, not even the process
limit.
Joerg
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@NetBSD.org, pkg-manager@netbsd.org, gnats-admin@netbsd.org,
pkgsrc-bugs@netbsd.org, prlw1@cam.ac.uk
Cc:
Subject: Re: pkg/50995: sigsegv in recv()
Date: Fri, 1 Apr 2016 08:30:21 -0400
On Apr 1, 8:50am, prlw1@cam.ac.uk (Patrick Welche) wrote:
-- Subject: Re: pkg/50995: sigsegv in recv()
| The following reply was made to PR pkg/50995; it has been noted by GNATS.
|
| From: Patrick Welche <prlw1@cam.ac.uk>
| To: gnats-bugs@NetBSD.org
| Cc:
| Subject: Re: pkg/50995: sigsegv in recv()
| Date: Fri, 1 Apr 2016 09:45:51 +0100
|
| On Fri, Apr 01, 2016 at 09:19:40AM +0100, Patrick Welche wrote:
| > #define FD_SETSIZE 256
|
| and how does FD_SETSIZE tie in with
|
| kern.maxfiles = 16384
Don't use select.
christos
From: David Holland <dholland-pbugs@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: pkg/50995: sigsegv in recv()
Date: Sun, 3 Apr 2016 03:24:34 +0000
On Fri, Apr 01, 2016 at 08:20:01AM +0000, Patrick Welche wrote:
> Looking at the coredump:
>
> fd.sck = 256
>
> fd_set fdSet;
> FD_ZERO(&fdSet); // clear the set
> FD_SET(sck, &fdSet); // add fd to the set
> timeval t; // timeval struct
> t.tv_sec = 0;
> t.tv_usec = 0;
>
> if (selectEINTR(sck + 1, &fdSet, NULL, NULL, &t) < 1) {
> return false;
> }
>
> so the number-of-fds argument is 257
>
> src/sys/sys/fd_set.h:
>
> /*
> * Select uses bit fields of file descriptors. These macros manipulate
> * such bit fields. Note: FD_SETSIZE may be defined by the user.
> */
>
> #ifndef FD_SETSIZE
> #define FD_SETSIZE 256
> #endif
>
> so you have a hole in one! (I don't see FD_SETSIZE defined by the user...)
>
> (How can this trash the stack?)
An out-of-range FD_SET will scribble outside of the fd_set, and since
the one here is on the stack, whatever's next on the stack gets a
present.
The path of least resistance is #define FD_SETSIZE 512 (before
including anything) but rewriting to use poll is probably a better
choice. Especially for selecting on a single fd like this.
(while changing FD_SETSIZE is a traditional interface, it's probably
not very portable)
Does the package have a viable upstream?
--
David A. Holland
dholland@netbsd.org
From: Patrick Welche <prlw1@cam.ac.uk>
To: gnats-bugs@NetBSD.org
Cc: pkg-manager@netbsd.org, gnats-admin@netbsd.org, pkgsrc-bugs@netbsd.org
Subject: Re: pkg/50995: sigsegv in recv()
Date: Mon, 4 Apr 2016 16:15:02 +0100
On Sun, Apr 03, 2016 at 03:25:00AM +0000, David Holland wrote:
> An out-of-range FD_SET will scribble outside of the fd_set, and since
> the one here is on the stack, whatever's next on the stack gets a
> present.
bug analyzed :-) Thanks!
> The path of least resistance is #define FD_SETSIZE 512 (before
> including anything) but rewriting to use poll is probably a better
> choice. Especially for selecting on a single fd like this.
I am testing
CONFIGURE_ARGS+= CPPFLAGS=-DFD_SETSIZE=512
I saw that solaris 7 uses 1024 by default. I think we might just have
been unlucky, as maxchildren = 250, so 512 should be enough. In the
patches I'm testing, I complain if it is not enough, so we won't get
the mysterious core dumps...
> (while changing FD_SETSIZE is a traditional interface, it's probably
> not very portable)
>
> Does the package have a viable upstream?
No, but e2guardian is looking promising. I already looked at using
kqueue instead, and saw:
https://github.com/e2guardian/e2guardian/issues/88
From: "Patrick Welche" <prlw1@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50995 CVS commit: pkgsrc/www/dansguardian
Date: Wed, 20 Apr 2016 13:52:24 +0000
Module Name: pkgsrc
Committed By: prlw1
Date: Wed Apr 20 13:52:24 UTC 2016
Modified Files:
pkgsrc/www/dansguardian: Makefile distinfo
pkgsrc/www/dansguardian/patches: patch-src_ConnectionHandler.cpp
Added Files:
pkgsrc/www/dansguardian/patches: patch-src_BaseSocket.cpp
patch-src_FatController.cpp
Log Message:
Defend against calling select() with nfds >= FD_SETSIZE.
PR pkg/50995
To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 pkgsrc/www/dansguardian/Makefile
cvs rdiff -u -r1.12 -r1.13 pkgsrc/www/dansguardian/distinfo
cvs rdiff -u -r0 -r1.1 \
pkgsrc/www/dansguardian/patches/patch-src_BaseSocket.cpp \
pkgsrc/www/dansguardian/patches/patch-src_FatController.cpp
cvs rdiff -u -r1.1 -r1.2 \
pkgsrc/www/dansguardian/patches/patch-src_ConnectionHandler.cpp
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.