[Fwd: Xinetd 2.3.10 Memory Leaks]

Christopher Nehren apeiron at comcast.net
Fri Apr 18 12:50:21 PDT 2003


I just submitted a PR for this (haven't even gotten the confirmation
email), but since not everyone tracks the GNATS CVS distribution, I
figured that I'd send it here as well.

-----Forwarded Message-----

> From: Steve Grubb <linux_4ever at yahoo.com>
> To: bugtraq at securityfocus.com
> Subject: Xinetd 2.3.10 Memory Leaks
> Date: 18 Apr 2003 16:18:36 +0000
> 
> 
> 
> BACKGROUND
> 
> -----------
> 
> 
> 
> Xinetd is a popular inetd replacement. Shortly after the 2.3.9 release in 
> 
> September 2002, it was realized that xinetd was leaking file descriptors. 
> 
> That problem turned out to be that file descriptors were not always being 
> 
> closed whenever a connection was rejected. 2.3.10 was released with this 
> 
> fixup among others in January.
> 
> 
> 
> Sometime in February, a machine that I admin was hit by an ftp worm. It 
> 
> created > 5000 connections in 1 second. Xinetd promptly keeled over. 
> 
> Xinetd had been running for over a month with no downtime. The machine has 
> 
> next to no ftp traffic and only from 2 sources, so it was configured to be 
> 
> run via xinetd rejecting connections via tcp_wrappers. The machine had 
> 
> weathered worm attacks in the past, so this puzzled me.
> 
> 
> 
> 
> 
> TESTING
> 
> -------
> 
> 
> 
> Eventually, I started looking at xinetd with valgrind. I used the 
> 
> following commandline:
> 
> 
> 
> valgrind --leak-check=yes --leak-resolution=med --num-callers=8  \
> 
>  --logfile-fd=9 /usr/sbin/xinetd -d -pidfile /var/run/xinetd.pid \
> 
>  -stayalive  9> out.txt
> 
> 
> 
> Depending on your setup, you may need to use something higher than 9. 
> 
> Xinetd was tested on connections that succeed and connections that are 
> 
> rejected due to configuration settings. The easiest way to test this is to 
> 
> use the following setup for chargen:
> 
> 
> 
> service chargen
> 
> {
> 
>         type = INTERNAL
> 
>         user = root
> 
>         protocol = tcp
> 
>         wait = no
> 
>         access_times = 2:00-3:00
> 
> #       only_from               = 192.168.1.3/24
> 
> #       no_access               = 192.168.1.3/24
> 
> }
> 
> 
> 
> The point is to set it up in a way that the connection is guaranteed to be 
> 
> rejected. Then do a:
> 
> 
> 
> telnet localhost chargen
> 
> After a couple seconds "ctl-] quit"
> 
> Then, /etc/rc.d/init.d/xinetd stop
> 
> 
> 
> Valgrind reports the following:
> 
> 
> 
> ==18939== 144 bytes in 1 blocks are definitely lost in loss record 36 of 45
> 
> ==18939==    at 0x40160DB8: malloc (vg_clientfuncs.c:103)
> 
> ==18939==    by 0x804FE22: (within /usr/sbin/xinetd)
> 
> ==18939==    by 0x805A496: (within /usr/sbin/xinetd)
> 
> ==18939==    by 0x8053611: (within /usr/sbin/xinetd)
> 
> ==18939==    by 0x805340D: (within /usr/sbin/xinetd)
> 
> ==18939==    by 0x40294A46: __libc_start_main (in /lib/libc-2.3.2.so)
> 
> ==18939==    by 0x804A310: (within /usr/sbin/xinetd)
> 
> ==18939==
> 
>             
> 
> 
> 
> THE PROBLEM
> 
> -----------
> 
>                                                                     
> 
> Using objdump -S /usr/sbin/xinetd, the block of code in question comes 
> 
> from service.c:
> 
> 
> 
> void svc_request( struct service *sp )
> 
> {
> 
>    connection_s *cp ;
> 
>    status_e ret_code;
> 
>                                                                            
> 
>      
> 
>    cp = conn_new( sp ) ;
> 
>    if ( cp == CONN_NULL )
> 
>       return ;
> 
>    if (sp->svc_not_generic)
> 
>            ret_code = spec_service_handler(sp, cp);
> 
>    else
> 
>            ret_code = svc_generic_handler(sp, cp);
> 
>                                                                            
> 
>      
> 
>    if ( ret_code != OK )
> 
>    {
> 
>       if ( SVC_LOGS_USERID_ON_FAILURE( sp ) )
> 
>          if( spec_service_handler( LOG_SERVICE( ps ), cp ) == FAILED ) {
> 
>             conn_free( cp, 1 );
> 
>             return;
> 
>          }
> 
>       CONN_CLOSE(cp);
> 
>    }
> 
> }
> 
> 
> 
> The above code has several problems. One background piece of information 
> 
> is that the sigchld handler in xinetd (child_exit->server_end-> 
> 
> svc_postmortem) normally frees the connection's data. If the ret_code is 
> 
> not OK, the connection was only closed. This is little more than close(cp-
> 
> >co_descriptor); This does not free cp since sigchld will not be called. 
> 
> It was only if the log service call failed that the connection was freed. 
> 
> 
> 
> The above code also did not take into account ret_code == OK if the 
> 
> service was no_wait or special. In both of those cases, the sigchld 
> 
> handler is not invoked so the memory pointed to by cp is lost when the 
> 
> call returns.
> 
> 
> 
> 
> 
> CONSEQUENCES
> 
> ------------
> 
> 
> 
> The memory area pointed to by cp is 144 bytes. Since the variable goes out 
> 
> of scope, it is permanently lost with no way of finding it again. The 
> 
> memory losses are cumulative, too. It would take little more than
> 
> 
> 
> while true; do telnet localhost chargen < /dev/null; done;
> 
> 
> 
> to DOS the services provided by xinetd if you could identify a machine 
> 
> that uses xinetd to reject connections. Xinetd provides a rich set of 
> 
> options for rejecting connections, this includes: tcp_wrappers, only_from, 
> 
> no_access, sensors, access_times, cps, load_avg, etc.
> 
> 
> 
> It should also be noted that if you DO NOT have any statements in the 
> 
> xinetd.conf file that would cause xinetd to reject a connection, then you 
> 
> are free from this problem.
> 
> 
> 
> 
> 
> SOLUTION
> 
> --------
> 
> 
> 
> Xinetd 2.3.11 fixes the memory leaks as well as other problems discovered 
> 
> since 2.3.10 was released. All users of xinetd 2.3.10 are strongly urged 
> 
> to upgrade ASAP to avoid DOS conditions. Anyone running 2.3.9 is also 
> 
> strongly urged to upgrade since they are leaking file descriptors.
> 
> 
> 
> Your xinetd version can be determined by typing "xinetd -version" (that's 
> 
> version with 1 dash).
> 
> 
> 
> The new tarball is: www.xinetd.org/xinetd-2.3.11.tar.gz
> 
> 
> 
> This problem has been assigned CAN-2003-0211 to track the bug. 
> 
> 
> 
> This bug was also reported here: 
> 
> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=88537
> 
> 
> 
> If you are affected, see if your vendor has an updated xinetd for you.
> 
> 
> 
> -Steve Grubb
> 
> 
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: This is a digitally signed message part
Url : http://lists.freebsd.org/pipermail/freebsd-security/attachments/20030418/fbb371a5/attachment.bin


More information about the freebsd-security mailing list