From nobody  Tue Jul 14 20:14:41 1998
Received: (from nobody@localhost)
          by hub.freebsd.org (8.8.8/8.8.8) id UAA03234;
          Tue, 14 Jul 1998 20:14:41 -0700 (PDT)
          (envelope-from nobody)
Message-Id: <199807150314.UAA03234@hub.freebsd.org>
Date: Tue, 14 Jul 1998 20:14:41 -0700 (PDT)
From: jeff@forys.cranbury.nj.us
To: freebsd-gnats-submit@freebsd.org
Subject: inetd can leak file descriptors +FIX
X-Send-Pr-Version: www-1.0

>Number:         7286
>Category:       i386
>Synopsis:       inetd can leak file descriptors +FIX
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jul 14 20:20:01 PDT 1998
>Closed-Date:    Tue Jul 21 22:54:02 PDT 1998
>Last-Modified:  Tue Jul 21 22:54:13 PDT 1998
>Originator:     Jeff Forys
>Release:        2.2.5-RELEASE
>Organization:
>Environment:
FreeBSD topaz.syl.nj.nec.com 2.2.5-RELEASE FreeBSD 2.2.5-RELEASE #8: Tue Mar 17 00:41:38 EST 1998     forys@topaz.syl.nj.nec.com:/usr/src/sys/compile/TOPAZ  i386

>Description:
This may apply to all known versions of inetd.

For a tcp/nowait connection, inetd invokes accept(2) for
each pending connection; this call returns a file descriptor
associated with the new connection.

Twelve years ago, code was added to inetd to detect "failing
servers".  The heuristic that identifies a failing server is
one that has been invoked a large number of times over some
specified interval (e.g., more than 128 ftp services started
in 60 seconds may flag the ftp service as "failing").  These
compile-time constants vary depending on vendor.

The problem is that, when a failing server is detected, the
code neglects to close the file descriptor returned by the
accept(2).

Security-Implications:
  I suppose someone with ample free time could orchestrate an
  attack buy pummeling services until the inetd process finally
  runs out of file descriptors thus rendering inetd useless to
  any new connections that require a new descriptor.

If you examine the source, you will see a call to close_sep(sep).
Note that, in the tcp/nowait case, this does not actually close
the fd returned by accept(2).  Rather, "sep" holds the control
socket that is listening for connections on that port; Since the
service was identified as "failing", the port is shut down (it
will be reopened after some specified timeout).

>How-To-Repeat:
Pummel one of inetd's tcp/nowait services so that it exceeds
the failing server threshold and logs a message like:

   "svc/proto server failing (looping), service terminated"

If your inetd has this bug, it will have leaked a file descriptor.
You'll have to come up with your own OS-independent way of finding
out how many file descriptors your inetd process is holding open.

>Fix:
*** inetd.c_orig        Mon Sep 22 02:23:24 1997
--- inetd.c     Fri Jun 26 12:40:36 1998
***************
*** 462,465 ****
--- 462,468 ----
                        "%s/%s server failing (looping), service terminated",
                                            sep->se_service, sep->se_proto);
+                                       if (sep->se_accept &&
+                                           sep->se_socktype == SOCK_STREAM)
+                                               close(ctrl);
                                        close_sep(sep);
                                        sigsetmask(0L);

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: phk 
State-Changed-When: Tue Jul 21 22:54:02 PDT 1998 
State-Changed-Why:  
committed, thanks! 
>Unformatted:
