From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16878 invoked by alias); 23 Feb 2004 12:53:32 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 16861 invoked from network); 23 Feb 2004 12:53:31 -0000 Received: from unknown (HELO sunsite.ms.mff.cuni.cz) (195.113.19.66) by sources.redhat.com with SMTP; 23 Feb 2004 12:53:31 -0000 Received: from sunsite.ms.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8) with ESMTP id i1NAimvf012532; Mon, 23 Feb 2004 11:44:48 +0100 Received: (from jakub@localhost) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8/Submit) id i1NAimX8012528; Mon, 23 Feb 2004 11:44:48 +0100 Date: Mon, 23 Feb 2004 12:53:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers , Sam Varshavchik Subject: [PATCH] Fix getaddrinfo leaking memory Message-ID: <20040223104447.GF4581@sunsite.ms.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4i X-SW-Source: 2004-02/txt/msg00049.txt.bz2 Hi! If getaddrinfo is called without _res initialized, it will leak memory until some other function is called which initializes it. The problem is that gaih_inet saves old options (0 in this case) and after lookup (which as a side-effect initialized it) restores _res.option from the saved value (which means next time _res will be initialized again). Also, if _res has not been initialized before getaddrinfo, the _res.options &= ~RES_USE_INET6 line is a nop (it will be initialized to RES_USE_INET6 during initialization anyway). The following patch fixes it. 2004-02-23 Jakub Jelinek * sysdeps/posix/getaddrinfo.c (gaih_inet): If _res has not been inited yet, try to init it before saving old _res.options. * posix/Makefile (xtests): Add bug-ga2. (generated): Add bug-ga2.mtrace and bug-ga2-mem. (xtests): Depend on bug-ga2-mem. ($(objpfx)bug-ga2-mem, bug-ga2-ENV): New. * posix/bug-ga2.c: New test. --- libc/sysdeps/posix/getaddrinfo.c.jj 2004-02-19 17:50:44.000000000 +0100 +++ libc/sysdeps/posix/getaddrinfo.c 2004-02-23 11:18:46.516227127 +0100 @@ -604,8 +604,6 @@ gaih_inet (const char *name, const struc struct gaih_addrtuple **pat = &at; int no_data = 0; int no_inet6_data = 0; - int old_res_options = _res.options; - /* If we are looking for both IPv4 and IPv6 address we don't want the lookup functions to automatically promote IPv4 addresses to IPv6 addresses. Currently this is decided @@ -616,6 +614,7 @@ gaih_inet (const char *name, const struc enum nss_status inet6_status, status = NSS_STATUS_UNAVAIL; int no_more; nss_gethostbyname2_r fct; + int old_res_options; if (__nss_hosts_database != NULL) { @@ -626,6 +625,9 @@ gaih_inet (const char *name, const struc no_more = __nss_database_lookup ("hosts", NULL, "dns [!UNAVAIL=return] files", &nip); + if ((_res.options & RES_INIT) == 0 && __res_ninit(&_res) == -1) + no_more = 1; + old_res_options = _res.options; _res.options &= ~RES_USE_INET6; while (!no_more) --- libc/posix/Makefile.jj 2004-02-19 17:50:41.000000000 +0100 +++ libc/posix/Makefile 2004-02-23 11:44:24.020830312 +0100 @@ -82,6 +82,7 @@ tests := tstgetopt testfnm runtests run bug-regex21 bug-regex22 bug-regex23 tst-nice tst-nanosleep \ transbug tst-rxspencer tst-pcre tst-boost \ bug-ga1 +xtests := bug-ga2 ifeq (yes,$(build-shared)) test-srcs := globtest tests += wordexp-test tst-exec tst-spawn @@ -98,7 +99,8 @@ generated := $(addprefix wordexp-test-re bug-regex2.mtrace bug-regex14-mem bug-regex14.mtrace \ bug-regex21-mem bug-regex21.mtrace \ tst-rxspencer-mem tst-rxspencer.mtrace tst-getconf.out \ - tst-pcre-mem tst-pcre.mtrace tst-boost-mem tst-boost.mtrace + tst-pcre-mem tst-pcre.mtrace tst-boost-mem tst-boost.mtrace \ + bug-ga2.mtrace bug-ga2-mem include ../Rules @@ -191,6 +193,7 @@ ifeq (no,$(cross-compiling)) tests: $(objpfx)bug-regex2-mem $(objpfx)bug-regex14-mem \ $(objpfx)bug-regex21-mem $(objpfx)tst-rxspencer-mem \ $(objpfx)tst-pcre-mem $(objpfx)tst-boost-mem $(objpfx)tst-getconf.out +xtests: $(objpfx)bug-ga2-mem endif $(objpfx)annexc.out: $(objpfx)annexc @@ -241,3 +244,8 @@ $(objpfx)tst-regex: $(common-objpfx)rt/l else $(objpfx)tst-regex: $(common-objpfx)rt/librt.a endif + +$(objpfx)bug-ga2-mem: $(objpfx)bug-ga2.out + $(common-objpfx)malloc/mtrace $(objpfx)bug-ga2.mtrace > $@ + +bug-ga2-ENV = MALLOC_TRACE=$(objpfx)bug-ga2.mtrace --- libc/posix/bug-ga2.c.jj 2004-02-23 11:37:37.900002974 +0100 +++ libc/posix/bug-ga2.c 2004-02-23 11:39:39.617084575 +0100 @@ -0,0 +1,30 @@ +/* Test case by Sam Varshavchik . */ +#include +#include +#include +#include + +int +main (void) +{ + struct addrinfo hints, *res; + int i, ret; + + mtrace (); + for (i = 0; i < 100; i++) + { + memset (&hints, 0, sizeof (hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + ret = getaddrinfo ("www.gnu.org", "http", &hints, &res); + + if (ret) + { + printf ("%s\n", gai_strerror (ret)); + return 1; + } + freeaddrinfo (res); + } + return 0; +} Jakub