From pb@fasterix.frmug.org Tue May 11 10:39:27 1999
Return-Path: <pb@fasterix.frmug.org>
Received: from fasterix.frmug.org (d109.paris-84.cybercable.fr [212.198.84.109])
	by hub.freebsd.org (Postfix) with ESMTP id D05E414D87
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 11 May 1999 10:39:19 -0700 (PDT)
	(envelope-from pb@fasterix.frmug.org)
Received: (from pb@localhost)
	by fasterix.frmug.org (8.9.3/8.9.3/pb-19990315) id TAA82788;
	Tue, 11 May 1999 19:39:08 +0200 (CEST)
Message-Id: <199905111739.TAA82788@fasterix.frmug.org>
Date: Tue, 11 May 1999 19:39:08 +0200 (CEST)
From: Pierre Beyssac <pb@fasterix.freenix.org>
Sender: pb@fasterix.frmug.org
Reply-To: pb@fasterix.freenix.org
To: FreeBSD-gnats-submit@freebsd.org
Subject: inetd's childs staying around after a scan
X-Send-Pr-Version: 3.2

>Number:         11651
>Category:       bin
>Synopsis:       inetd's childs staying around after a scan
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    sheldonh
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 11 10:40:01 PDT 1999
>Closed-Date:    Wed Jun 9 08:52:17 PDT 1999
>Last-Modified:  Wed Jun  9 08:53:27 PDT 1999
>Originator:     Pierre Beyssac
>Release:        FreeBSD 4.0-CURRENT i386
>Organization:
individual
>Environment:

	-current as of May 1st
	inetd using hosts.allow and hosts.deny

>Description:

Summary: several forked childs for the echo datagram service staying
around.  One of them logs EBADF errors in select(2). The others
are stuck in a recvfrom.

Details: I was recently the victim of a UDP (+ probably TCP) scan.

After the fact, I noticed that I had many (about 20) hung inetd
around, all childs of the "main" inetd (unfortunately I've
been unable to find a way to reproduce the problem so far).

Most of them are stuck at the following place: recvfrom() in the
echo datagram service (the weird thing being that the echo
datagram service is not supposed to fork):

0x280a9330 in _recvfrom ()
(gdb) where
#0  0x280a9330 in _recvfrom ()
#1  0x804b88f in echo_dg (s=13, sep=0x8057900)
    at /u2/usr/src/usr.sbin/inetd/inetd.c:1670
#2  0x8049fba in main (argc=1, argv=0xbfbfde0c, envp=0xbfbfde14)
    at /u2/usr/src/usr.sbin/inetd/inetd.c:656
#3  0x8049689 in _start ()

One of the forked inetd's (not the father) periodically logs the
following, which alerted me to the problem:

May  7 03:23:32 fasterix inetd[24557]: select: Bad file descriptor

Same process in gdb:
#0  0x280a8630 in nanosleep ()
#1  0x280c3c2b in sleep ()
#2  0x8049a6d in main (argc=1, argv=0xbfbfde0c, envp=0xbfbfde14)
    at /u2/usr/src/usr.sbin/inetd/inetd.c:485
#3  0x8049689 in _start ()
Breakpoint 2, main (argc=1, argv=0xbfbfde0c, envp=0xbfbfde14)
    at /u2/usr/src/usr.sbin/inetd/inetd.c:484
484                             syslog(LOG_WARNING, "select: %m");
(gdb) print maxsock
$1 = 20
(gdb) print allsock
$2 = {fds_bits = {2097144, 0 <repeats 31 times>}}

Equivalent bitmask: 1 1111 1111 1111 1111 1000

fstat yields the following for all child processes:

root     inetd      24557 root /             2 drwxr-xr-x    1024  r
root     inetd      24557   wd /             2 drwxr-xr-x    1024  r
root     inetd      24557 text /u2      500641 -r-xr-xr-x   21548  r
root     inetd      24557    0 /           107 crw-rw-rw-    null rw
root     inetd      24557    1 /           107 crw-rw-rw-    null rw
root     inetd      24557    2 /           107 crw-rw-rw-    null rw
root     inetd      24557    3* local dgram c49d73c0 <-> c49d7fc0
root     inetd      24557   13* internet dgram udp c4455840
root     inetd      24557   21* internet dgram udp c4455660
root     inetd      24557   22* pipe c49d2d40 <-> c49d2de0      0 rw

>How-To-Repeat:

Unknown yet. It's not enough to just flood echo/chargen and friends
with datagrams.

Note that the forking/not forking behaviour seems to be affected
by libwrap configuratin as shown by the following from inetd.c:

#ifdef LIBWRAP_INTERNAL
                    dofork = 1;
#else
                    dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork);
#endif  


>Fix:
>Release-Note:
>Audit-Trail:

From: Sheldon Hearn <sheldonh@uunet.co.za>
To: freebsd-gnats-submit@freebsd.org
Cc: Pierre Beyssac <pb@fasterix.freenix.org>, markm@freebsd.org
Subject: Re: bin/11651: inetd's childs staying around after a scan
Date: Thu, 20 May 1999 16:52:35 +0200

 Hi Pierre,
 
 This was caused by an oversight in our handling of internal service
 wrapping. The feature was disabled by markm when the problem was
 discovered, since neither he nor I felt like looking at it at the time.
 
 The problem is that the code as compiled with -DLIBWRAP_INTERNAL forks
 for _all_ services, even internals whose se_bi flag is _not_ set. This
 invalidates the assumption made at line 657 (inetd.c v1.49).
 
 Please would you try the following patch. I've tested it for external,
 forking internal and non-forking internal services for each of the
 following three cases:
 
 	no wrapping
 	-DLIBWRAP
 	-DLIBWRAP -DLIBWRAP_INTERNAL
 
 So it should work fine for you.
 
 Ciao,
 Sheldon.
 
 Index: Makefile
 ===================================================================
 RCS file: /home/ncvs/src/usr.sbin/inetd/Makefile,v
 retrieving revision 1.8
 diff -u -d -r1.8 Makefile
 --- Makefile	1999/05/07 06:48:01	1.8
 +++ Makefile	1999/05/20 14:34:35
 @@ -5,7 +5,7 @@
  MAN8=	inetd.8
  MLINKS=	inetd.8 inetd.conf.5
  
 -COPTS+=	-Wall -DLOGIN_CAP -DLIBWRAP
 +COPTS+=	-Wall -DLOGIN_CAP -DLIBWRAP -DLIBWRAP_INTERNAL
  #COPTS+=	-DSANITY_CHECK
  
  DPADD+=	${LIBUTIL} ${LIBWRAP}
 Index: inetd.c
 ===================================================================
 RCS file: /home/ncvs/src/usr.sbin/inetd/inetd.c,v
 retrieving revision 1.49
 diff -u -d -r1.49 inetd.c
 --- inetd.c	1999/05/11 12:50:14	1.49
 +++ inetd.c	1999/05/20 14:14:02
 @@ -556,11 +556,7 @@
  			    ctrl = sep->se_fd;
  		    (void) sigblock(SIGBLOCK);
  		    pid = 0;
 -#ifdef LIBWRAP_INTERNAL
 -		    dofork = 1;
 -#else
  		    dofork = (sep->se_bi == 0 || sep->se_bi->bi_fork);
 -#endif
  		    if (dofork) {
  			    if (sep->se_count++ == 0)
  				(void)gettimeofday(&sep->se_time, (struct timezone *)NULL);
 @@ -746,7 +742,8 @@
  #endif
  				if (sep->se_socktype != SOCK_STREAM)
  					recv(0, buf, sizeof (buf), 0);
 -				_exit(EX_OSERR);
 +				if (dofork)
 +					_exit(EX_OSERR);
  			    }
  		    }
  		    if (sep->se_accept && sep->se_socktype == SOCK_STREAM)
 

From: Pierre Beyssac <pb@fasterix.freenix.org>
To: Sheldon Hearn <sheldonh@uunet.co.za>,
	freebsd-gnats-submit@freebsd.org
Cc: Pierre Beyssac <pb@fasterix.freenix.org>, markm@freebsd.org
Subject: Re: bin/11651: inetd's childs staying around after a scan
Date: Thu, 20 May 1999 22:48:19 +0200

 On Thu, May 20, 1999 at 04:52:35PM +0200, Sheldon Hearn wrote:
 > Please would you try the following patch. I've tested it for external,
 > forking internal and non-forking internal services for each of the
 > following three cases:
 > 
 > 	no wrapping
 > 	-DLIBWRAP
 > 	-DLIBWRAP -DLIBWRAP_INTERNAL
 
 Thanks a lot for the patch! It fixes the problem even in the latter
 case (which was the default in -current at the time I recompiled
 inetd).
 -- 
 Pierre Beyssac	      pb@fasterix.frmug.org pb@fasterix.freenix.org
 {Free,Net,Open}BSD, Linux : il y a moins bien, mais c'est plus cher
     Free domains: http://www.eu.org/ or mail dns-manager@EU.org
 
Responsible-Changed-From-To: freebsd-bugs->markm 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Sun May 30 22:33:05 PDT 1999 
Responsible-Changed-Why:  
He says he'll take a look at it. :-) 
State-Changed-From-To: open->closed 
State-Changed-By: sheldonh 
State-Changed-When: Wed Jun 9 08:52:17 PDT 1999 
State-Changed-Why:  
Superseded by PR 12097 . 


Responsible-Changed-From-To: markm->sheldonh 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Wed Jun 9 08:52:17 PDT 1999 
Responsible-Changed-Why:  
My fix. 
>Unformatted:
