This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch allan/2.19/backport created. glibc-2.19-25-g7e09ce5


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, allan/2.19/backport has been created
        at  7e09ce56759640a4bf10e4d6ddca77757e115f13 (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7e09ce56759640a4bf10e4d6ddca77757e115f13

commit 7e09ce56759640a4bf10e4d6ddca77757e115f13
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Mon May 26 11:40:08 2014 +0530

    Use NSS_STATUS_TRYAGAIN to indicate insufficient buffer (BZ #16878)
    
    The netgroups nss modules in the glibc tree use NSS_STATUS_UNAVAIL
    (with errno as ERANGE) when the supplied buffer does not have
    sufficient space for the result.  This is wrong, because the canonical
    way to indicate insufficient buffer is to set the errno to ERANGE and
    the status to NSS_STATUS_TRYAGAIN, as is used by all other modules.
    
    This fixes nscd behaviour when the nss_ldap module returns
    NSS_STATUS_TRYAGAIN to indicate that a netgroup entry is too long to
    fit into the supplied buffer.
    
    (cherry picked from commit c3ec475c5dd16499aa040908e11d382c3ded9692)
    
    Conflicts:
    	NEWS

diff --git a/ChangeLog b/ChangeLog
index 87e0851..c0f5bb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-05-26  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	[BZ #16878]
+	* nscd/netgroupcache.c (addgetnetgrentX): Look for
+	NSS_STATUS_TRYAGAIN to indicate insufficient buffer space.
+	* nscd/nss_files/files-netgrp.c (_nss_netgroup_parseline): Use
+	NSS_STATUS_TRYAGAIN to indicate insufficient buffer space.
+
 2014-03-12  Siddhesh Poyarekar  <siddhesh@redhat.com>
 
 	[BZ #16695]
diff --git a/NEWS b/NEWS
index 58fe721..e84bae5 100644
--- a/NEWS
+++ b/NEWS
@@ -9,8 +9,8 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  15946, 16545, 16574, 16623, 16695, 16882, 16885, 16916, 16932, 16943,
-  16958, 17048, 17069.
+  15946, 16545, 16574, 16623, 16695, 16878, 16882, 16885, 16916, 16932,
+  16943, 16958, 17048, 17069.
 
 * CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
   copy the path argument.  This allowed programs to cause posix_spawn to
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index fe7fc75..084f74d 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -203,11 +203,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 		    int e;
 		    status = getfct.f (&data, buffer + buffilled,
 				       buflen - buffilled - req->key_len, &e);
-		    if (status == NSS_STATUS_RETURN
-			|| status == NSS_STATUS_NOTFOUND)
-		      /* This was either the last one for this group or the
-			 group was empty.  Look at next group if available.  */
-		      break;
 		    if (status == NSS_STATUS_SUCCESS)
 		      {
 			if (data.type == triple_val)
@@ -322,11 +317,18 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 			      }
 			  }
 		      }
-		    else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
+		    else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
 		      {
 			buflen *= 2;
 			buffer = xrealloc (buffer, buflen);
 		      }
+		    else if (status == NSS_STATUS_RETURN
+			     || status == NSS_STATUS_NOTFOUND
+			     || status == NSS_STATUS_UNAVAIL)
+		      /* This was either the last one for this group or the
+			 group was empty or the NSS module had an internal
+			 failure.  Look at next group if available.  */
+		      break;
 		  }
 
 	      enum nss_status (*endfct) (struct __netgrent *);
diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c
index 34eae4c..bc0b367 100644
--- a/nss/nss_files/files-netgrp.c
+++ b/nss/nss_files/files-netgrp.c
@@ -252,7 +252,7 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
   if (cp - host > buflen)
     {
       *errnop = ERANGE;
-      status = NSS_STATUS_UNAVAIL;
+      status = NSS_STATUS_TRYAGAIN;
     }
   else
     {

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=6489b92b735504bbb124c0a29967e52906101e56

commit 6489b92b735504bbb124c0a29967e52906101e56
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Wed Mar 12 17:27:22 2014 +0530

    Provide correct buffer length to netgroup queries in nscd (BZ #16695)
    
    The buffer to query netgroup entries is allocated sufficient space for
    the netgroup entries and the key to be appended at the end, but it
    sends in an incorrect available length to the NSS netgroup query
    functions, resulting in overflow of the buffer in some special cases.
    The fix here is to factor in the key length when sending the available
    buffer and buffer length to the query functions.
    
    (cherry picked from commit c44496df2f090a56d3bf75df930592dac6bba46f)
    
    Conflicts:
    	NEWS

diff --git a/ChangeLog b/ChangeLog
index db1d39f..87e0851 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-03-12  Siddhesh Poyarekar  <siddhesh@redhat.com>
+
+	[BZ #16695]
+	* nscd/netgroupcache.c (addgetnetgrentX): Factor in space for
+	key in the buffer.
+
 2014-06-20  Maciej W. Rozycki  <macro@codesourcery.com>
 
 	[BZ #16046]
diff --git a/NEWS b/NEWS
index 3f762d1..58fe721 100644
--- a/NEWS
+++ b/NEWS
@@ -9,8 +9,8 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  15946, 16545, 16574, 16623, 16882, 16885, 16916, 16932, 16943, 16958,
-  17048, 17069.
+  15946, 16545, 16574, 16623, 16695, 16882, 16885, 16916, 16932, 16943,
+  16958, 17048, 17069.
 
 * CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
   copy the path argument.  This allowed programs to cause posix_spawn to
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index be01fe8..fe7fc75 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -202,7 +202,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 		  {
 		    int e;
 		    status = getfct.f (&data, buffer + buffilled,
-				       buflen - buffilled, &e);
+				       buflen - buffilled - req->key_len, &e);
 		    if (status == NSS_STATUS_RETURN
 			|| status == NSS_STATUS_NOTFOUND)
 		      /* This was either the last one for this group or the

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=00e1e5950611a1d8d5d6605906d11432ecd6e7c5

commit 00e1e5950611a1d8d5d6605906d11432ecd6e7c5
Author: Maciej W. Rozycki <macro@codesourcery.com>
Date:   Fri Jun 20 21:52:53 2014 +0100

    [BZ #16046] dl_iterate_phdr static executable test
    
    (cherry picked from commit 257ce7127e2f64a6a959b146786cd43de0e42b5f)

diff --git a/ChangeLog b/ChangeLog
index 49ebab5..db1d39f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-20  Maciej W. Rozycki  <macro@codesourcery.com>
+
+	[BZ #16046]
+	* elf/tst-dl-iter-static.c: New file.
+	* elf/Makefile (tests-static): Add tst-dl-iter-static.
+
 2014-06-20  Andreas Schwab  <schwab@linux-m68k.org>
 
 	[BZ #17069]
diff --git a/elf/Makefile b/elf/Makefile
index 4c58fc9..b9da0b8 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -123,7 +123,7 @@ tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1 \
 	tst-auxv
 tests-static = tst-tls1-static tst-tls2-static tst-stackguard1-static \
 	       tst-leaks1-static tst-array1-static tst-array5-static \
-	       tst-ptrguard1-static
+	       tst-ptrguard1-static tst-dl-iter-static
 ifeq (yes,$(build-shared))
 tests-static += tst-tls9-static
 tst-tls9-static-ENV = \
diff --git a/elf/tst-dl-iter-static.c b/elf/tst-dl-iter-static.c
new file mode 100644
index 0000000..7303d7c
--- /dev/null
+++ b/elf/tst-dl-iter-static.c
@@ -0,0 +1,47 @@
+/* BZ #16046 dl_iterate_phdr static executable test.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <link.h>
+
+/* Check that the link map of the static executable itself is iterated
+   over exactly once.  */
+
+static int
+callback (struct dl_phdr_info *info, size_t size, void *data)
+{
+  int *count = data;
+
+  if (info->dlpi_name[0] == '\0')
+    (*count)++;
+
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  int count = 0;
+  int status;
+
+  status = dl_iterate_phdr (callback, &count);
+
+  return status || count != 1;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0625ebcc25a4eda851b53b50f99fa49f790b9ee8

commit 0625ebcc25a4eda851b53b50f99fa49f790b9ee8
Author: Andreas Schwab <schwab@linux-m68k.org>
Date:   Fri Jun 20 12:41:27 2014 +0200

    Fix another memory leak in regexp compiler (BZ #17069)
    
    (cherry picked from commit aa6ec754f3b4b1df81d186480c534b6486a1e6ee)
    
    Conflicts:
    	NEWS

diff --git a/ChangeLog b/ChangeLog
index 1a3b62d..49ebab5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-06-20  Andreas Schwab  <schwab@linux-m68k.org>
+
+	[BZ #17069]
+	* posix/regcomp.c (parse_reg_exp): Deallocate partially
+	constructed tree before returning error.
+	* posix/bug-regexp36.c: Expand test case.
+
 2014-06-19  Andreas Schwab  <schwab@linux-m68k.org>
 
 	[BZ #17069]
diff --git a/NEWS b/NEWS
index 4eebd67..3f762d1 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,7 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   15946, 16545, 16574, 16623, 16882, 16885, 16916, 16932, 16943, 16958,
-  17048.
+  17048, 17069.
 
 * CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
   copy the path argument.  This allowed programs to cause posix_spawn to
diff --git a/posix/bug-regex36.c b/posix/bug-regex36.c
index 3dda026..59e2b6d 100644
--- a/posix/bug-regex36.c
+++ b/posix/bug-regex36.c
@@ -1,4 +1,4 @@
-/* Test regcomp not leaking memory on invalid repetition operator
+/* Test regcomp not leaking memory on parse errors
    Copyright (C) 2014 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -24,6 +24,6 @@ main (int argc, char **argv)
 {
   regex_t r;
   mtrace ();
-  regcomp (&r, "[a]\\{-2,}", 0);
+  regcomp (&r, "[a]\\|[a]\\{-2,}", 0);
   regfree (&r);
 }
diff --git a/posix/regcomp.c b/posix/regcomp.c
index a5020be..076eca3 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -2154,7 +2154,11 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
 	{
 	  branch = parse_branch (regexp, preg, token, syntax, nest, err);
 	  if (BE (*err != REG_NOERROR && branch == NULL, 0))
-	    return NULL;
+	    {
+	      if (tree != NULL)
+		postorder (tree, free_tree, NULL);
+	      return NULL;
+	    }
 	}
       else
 	branch = NULL;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fc93c8a02c25e2486f3057ae06cf79209c381832

commit fc93c8a02c25e2486f3057ae06cf79209c381832
Author: Andreas Schwab <schwab@linux-m68k.org>
Date:   Thu Jun 19 15:38:03 2014 +0200

    Fix memory leak in regexp compiler (BZ #17069)
    
    (cherry picked from commit 4d43ef1e7434d7d419afbcd754931cb0c794763c)
    
    Conflicts:
    	posix/Makefile

diff --git a/ChangeLog b/ChangeLog
index d833701..1a3b62d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2014-06-19  Andreas Schwab  <schwab@linux-m68k.org>
+
+	[BZ #17069]
+	* posix/regcomp.c (parse_expression): Deallocate partially
+	constructed tree before returning error.
+	* posix/Makefile.c (tests): Add bug-regex36.
+	(generated): Add bug-regex36.mtrace.
+	(tests-special): Add $(objpfx)bug-regex36-mem.out
+	(bug-regex36-ENV): New variable.
+	($(objpfx)bug-regex36-mem.out): New rule.
+	* posix/bug-regex36.c: New file.
+
 2014-06-03  Andreas Schwab  <schwab@suse.de>
 
 	[BZ #15946]
diff --git a/posix/Makefile b/posix/Makefile
index 6709900..c99964d 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -86,7 +86,7 @@ tests		:= tstgetopt testfnm runtests runptests	     \
 		   tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
 		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
 		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
-		   tst-pathconf tst-getaddrinfo4
+		   tst-pathconf tst-getaddrinfo4 bug-regex36
 xtests		:= bug-ga2
 ifeq (yes,$(build-shared))
 test-srcs	:= globtest
@@ -101,6 +101,7 @@ install-others-programs	:= $(inst_libexecdir)/getconf
 before-compile	:= testcases.h ptestcases.h
 
 # So they get cleaned up.
+<<<<<<< HEAD
 generated := $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
 	     annexc annexc.out wordexp-tst.out bug-regex2-mem \
 	     bug-regex2.mtrace bug-regex14-mem bug-regex14.mtrace \
@@ -111,6 +112,39 @@ generated := $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
 	     bug-ga2.mtrace bug-ga2-mem bug-glob2.mtrace bug-glob2-mem \
 	     tst-vfork3-mem tst-vfork3.mtrace getconf.speclist \
 	     tst-fnmatch-mem tst-fnmatch.mtrace
+=======
+generated += $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \
+	     annexc annexc.out wordexp-tst.out bug-regex2-mem.out \
+	     bug-regex2.mtrace bug-regex14-mem.out bug-regex14.mtrace \
+	     bug-regex21-mem.out bug-regex21.mtrace \
+	     bug-regex31-mem.out bug-regex31.mtrace \
+	     tst-rxspencer-no-utf8-mem.out tst-rxspencer-no-utf8.mtrace \
+	     tst-getconf.out \
+	     tst-pcre-mem.out tst-pcre.mtrace tst-boost-mem.out \
+	     tst-boost.mtrace bug-ga2.mtrace bug-ga2-mem.out \
+	     bug-glob2.mtrace bug-glob2-mem.out tst-vfork3-mem.out \
+	     tst-vfork3.mtrace getconf.speclist tst-fnmatch-mem.out \
+	     tst-fnmatch.mtrace bug-regex36.mtrace
+
+ifeq ($(run-built-tests),yes)
+ifeq (yes,$(build-shared))
+tests-special += $(objpfx)globtest.out $(objpfx)wordexp-tst.out
+endif
+endif
+
+# Run a test on the header files we use.
+# XXX Please note that for now we ignore the result of this test.
+tests-special += $(objpfx)annexc.out
+ifeq ($(run-built-tests),yes)
+tests-special += $(objpfx)bug-regex2-mem.out $(objpfx)bug-regex14-mem.out \
+		 $(objpfx)bug-regex21-mem.out $(objpfx)bug-regex31-mem.out \
+		 $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
+		 $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
+		 $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
+		 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
+xtests-special += $(objpfx)bug-ga2-mem.out
+endif
+>>>>>>> 4d43ef1... Fix memory leak in regexp compiler (BZ #17069)
 
 include ../Rules
 
@@ -260,6 +294,12 @@ bug-regex31-ENV = MALLOC_TRACE=$(objpfx)bug-regex31.mtrace
 $(objpfx)bug-regex31-mem: $(objpfx)bug-regex31.out
 	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex31.mtrace > $@
 
+bug-regex36-ENV = MALLOC_TRACE=$(objpfx)bug-regex36.mtrace
+
+$(objpfx)bug-regex36-mem.out: $(objpfx)bug-regex36.out
+	$(common-objpfx)malloc/mtrace $(objpfx)bug-regex36.mtrace > $@; \
+	$(evaluate-test)
+
 tst-vfork3-ENV = MALLOC_TRACE=$(objpfx)tst-vfork3.mtrace
 
 $(objpfx)tst-vfork3-mem: $(objpfx)tst-vfork3.out
diff --git a/posix/bug-regex36.c b/posix/bug-regex36.c
new file mode 100644
index 0000000..3dda026
--- /dev/null
+++ b/posix/bug-regex36.c
@@ -0,0 +1,29 @@
+/* Test regcomp not leaking memory on invalid repetition operator
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <mcheck.h>
+#include <regex.h>
+
+int
+main (int argc, char **argv)
+{
+  regex_t r;
+  mtrace ();
+  regcomp (&r, "[a]\\{-2,}", 0);
+  regfree (&r);
+}
diff --git a/posix/regcomp.c b/posix/regcomp.c
index 921d0f4..a5020be 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -2415,14 +2415,21 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
   while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
 	 || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
     {
-      tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
-      if (BE (*err != REG_NOERROR && tree == NULL, 0))
-	return NULL;
+      bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
+      if (BE (*err != REG_NOERROR && dup_tree == NULL, 0))
+	{
+	  if (tree != NULL)
+	    postorder (tree, free_tree, NULL);
+	  return NULL;
+	}
+      tree = dup_tree;
       /* In BRE consecutive duplications are not allowed.  */
       if ((syntax & RE_CONTEXT_INVALID_DUP)
 	  && (token->type == OP_DUP_ASTERISK
 	      || token->type == OP_OPEN_DUP_NUM))
 	{
+	  if (tree != NULL)
+	    postorder (tree, free_tree, NULL);
 	  *err = REG_BADRPT;
 	  return NULL;
 	}

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7b17d60f13089585c2b63d46cbc660c4b85d169d

commit 7b17d60f13089585c2b63d46cbc660c4b85d169d
Author: Andreas Schwab <schwab@suse.de>
Date:   Mon May 26 18:01:31 2014 +0200

    Fix invalid file descriptor reuse while sending DNS query (BZ #15946)
    
    (cherry picked from commit f9d2d03254a58d92635a311a42253eeed5a40a47)
    
    Conflicts:
    	NEWS

diff --git a/ChangeLog b/ChangeLog
index 150016c..d833701 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-03  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #15946]
+	* resolv/res_send.c (send_dg): Reload file descriptor after
+	calling reopen.
+
 2014-02-18  Andreas Schwab  <schwab@suse.de>
 
 	[BZ #16574]
diff --git a/NEWS b/NEWS
index d2b3419..4eebd67 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,8 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16574, 16623, 16882, 16885, 16916, 16932, 16943, 16958, 17048.
+  15946, 16545, 16574, 16623, 16882, 16885, 16916, 16932, 16943, 16958,
+  17048.
 
 * CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
   copy the path argument.  This allowed programs to cause posix_spawn to
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 704542c..416da87 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -1410,6 +1410,7 @@ send_dg(res_state statp,
 					retval = reopen (statp, terrno, ns);
 					if (retval <= 0)
 						return retval;
+					pfd[0].fd = EXT(statp).nssocks[ns];
 				}
 			}
 			goto wait;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=76aebfbb87ecc33e59d29a8adda76dfcdbc9213d

commit 76aebfbb87ecc33e59d29a8adda76dfcdbc9213d
Author: Andreas Schwab <schwab@suse.de>
Date:   Tue Feb 18 10:57:25 2014 +0100

    Properly fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
    
    Instead of trying to guess whether the second buffer needs to be freed
    set a flag at the place it is allocated
    
    (cherry picked from commit ab09bf616ad527b249aca5f2a4956fd526f0712f)

diff --git a/ChangeLog b/ChangeLog
index 2efb7a2..150016c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2014-02-18  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #16574]
+	* resolv/res_send.c (send_vc): Add parameter ansp2_malloced.
+	Store non-zero if the second buffer was newly allocated.
+	(send_dg): Likewise.
+	(__libc_res_nsend): Add parameter ansp2_malloced and pass it down
+	to send_vc and send_dg.
+	(res_nsend): Pass NULL for ansp2_malloced.
+	* resolv/res_query.c (__libc_res_nquery): Add parameter
+	answerp2_malloced and pass it down to __libc_res_nsend.
+	(res_nquery): Pass additional NULL to __libc_res_nquery.
+	(__libc_res_nsearch): Add parameter answerp2_malloced and pass it
+	down to __libc_res_nquery and __libc_res_nquerydomain.  Deallocate
+	second answer buffer if answerp2_malloced was set.
+	(res_nsearch): Pass additional NULL to __libc_res_nsearch.
+	(__libc_res_nquerydomain): Add parameter
+	answerp2_malloced and pass it down to __libc_res_nquery.
+	(res_nquerydomain): Pass additional NULL to
+	__libc_res_nquerydomain.
+	* resolv/nss_dns/dns-network.c (_nss_dns_getnetbyname_r): Pass
+	additional NULL to __libc_res_nsend and __libc_res_nquery.
+	* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname3_r): Pass
+	additional NULL to __libc_res_nsearch.
+	(_nss_dns_gethostbyname4_r): Revert last change.  Use new
+	parameter of __libc_res_nsearch to check for separately allocated
+	second buffer.
+	(_nss_dns_gethostbyaddr2_r): Pass additional NULL to
+	__libc_res_nquery.
+	* resolv/nss_dns/dns-canon.c (_nss_dns_getcanonname_r): Pass
+	additional NULL to __libc_res_nquery.
+	* resolv/gethnamaddr.c (gethostbyname2): Pass additional NULL to
+	__libc_res_nsearch.
+	(gethostbyaddr): Pass additional NULL to __libc_res_nquery.
+	* include/resolv.h: Update prototypes of __libc_res_nquery,
+	__libc_res_nsearch, __libc_res_nsend.
+
 2014-02-13  Andreas Schwab  <schwab@suse.de>
 
 	[BZ #16574]
diff --git a/include/resolv.h b/include/resolv.h
index 87b3598..3904cb7 100644
--- a/include/resolv.h
+++ b/include/resolv.h
@@ -48,11 +48,11 @@ libc_hidden_proto (__res_randomid)
 libc_hidden_proto (__res_state)
 
 int __libc_res_nquery (res_state, const char *, int, int, u_char *, int,
-		       u_char **, u_char **, int *, int *);
+		       u_char **, u_char **, int *, int *, int *);
 int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int,
-			u_char **, u_char **, int *, int *);
+			u_char **, u_char **, int *, int *, int *);
 int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int,
-		      u_char *, int, u_char **, u_char **, int *, int *)
+		      u_char *, int, u_char **, u_char **, int *, int *, int *)
   attribute_hidden;
 
 libresolv_hidden_proto (_sethtent)
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index 1fd8f92..c73a0dc 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -621,7 +621,7 @@ gethostbyname2(name, af)
 	buf.buf = origbuf = (querybuf *) alloca (1024);
 
 	if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
-				    &buf.ptr, NULL, NULL, NULL)) < 0) {
+				    &buf.ptr, NULL, NULL, NULL, NULL)) < 0) {
 		if (buf.buf != origbuf)
 			free (buf.buf);
 		Dprintf("res_nsearch failed (%d)\n", n);
@@ -716,12 +716,12 @@ gethostbyaddr(addr, len, af)
 	buf.buf = orig_buf = (querybuf *) alloca (1024);
 
 	n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
-			      &buf.ptr, NULL, NULL, NULL);
+			      &buf.ptr, NULL, NULL, NULL, NULL);
 	if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
 		strcpy(qp, "ip6.int");
 		n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
 				      buf.buf != orig_buf ? MAXPACKET : 1024,
-				      &buf.ptr, NULL, NULL, NULL);
+				      &buf.ptr, NULL, NULL, NULL, NULL);
 	}
 	if (n < 0) {
 		if (buf.buf != orig_buf)
diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c
index a9db232..e8c112c 100644
--- a/resolv/nss_dns/dns-canon.c
+++ b/resolv/nss_dns/dns-canon.c
@@ -62,7 +62,7 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen,
     {
       int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
 				 buf, sizeof (buf), &ansp.ptr, NULL, NULL,
-				 NULL);
+				 NULL, NULL);
       if (r > 0)
 	{
 	  /* We need to decode the response.  Just one question record.
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 71b3b96..f0b4b17 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -190,7 +190,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
   host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
 
   n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
-			  1024, &host_buffer.ptr, NULL, NULL, NULL);
+			  1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
   if (n < 0)
     {
       switch (errno)
@@ -225,7 +225,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
 	n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
 				host_buffer.buf != orig_host_buffer
 				? MAXPACKET : 1024, &host_buffer.ptr,
-				NULL, NULL, NULL);
+				NULL, NULL, NULL, NULL);
 
       if (n < 0)
 	{
@@ -298,23 +298,23 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 	name = cp;
     }
 
-  int anslen = 2048;
   union
   {
     querybuf *buf;
     u_char *ptr;
   } host_buffer;
   querybuf *orig_host_buffer;
-  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (anslen);
+  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048);
   u_char *ans2p = NULL;
   int nans2p = 0;
   int resplen2 = 0;
+  int ans2p_malloced = 0;
 
   int olderr = errno;
   enum nss_status status;
   int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
-			      host_buffer.buf->buf, anslen, &host_buffer.ptr,
-			      &ans2p, &nans2p, &resplen2);
+			      host_buffer.buf->buf, 2048, &host_buffer.ptr,
+			      &ans2p, &nans2p, &resplen2, &ans2p_malloced);
   if (n >= 0)
     {
       status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
@@ -351,10 +351,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
     }
 
   /* Check whether ans2p was separately allocated.  */
-  if (host_buffer.buf != orig_host_buffer)
-    anslen = MAXPACKET;
-  if (ans2p != NULL
-      && (ans2p < host_buffer.ptr || ans2p >= host_buffer.ptr + anslen))
+  if (ans2p_malloced)
     free (ans2p);
 
   if (host_buffer.buf != orig_host_buffer)
@@ -465,7 +462,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
 	  strcpy (qp, "].ip6.arpa");
 	  n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
 				 host_buffer.buf->buf, 1024, &host_buffer.ptr,
-				 NULL, NULL, NULL);
+				 NULL, NULL, NULL, NULL);
 	  if (n >= 0)
 	    goto got_it_already;
 	}
@@ -486,14 +483,14 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
     }
 
   n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
-			 1024, &host_buffer.ptr, NULL, NULL, NULL);
+			 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
   if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
     {
       strcpy (qp, "ip6.int");
       n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
 			     host_buffer.buf != orig_host_buffer
 			     ? MAXPACKET : 1024, &host_buffer.ptr,
-			     NULL, NULL, NULL);
+			     NULL, NULL, NULL, NULL);
     }
   if (n < 0)
     {
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
index 8e80a60..13ad38c 100644
--- a/resolv/nss_dns/dns-network.c
+++ b/resolv/nss_dns/dns-network.c
@@ -129,7 +129,7 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
 
   anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
-			       1024, &net_buffer.ptr, NULL, NULL, NULL);
+			       1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
   if (anslen < 0)
     {
       /* Nothing found.  */
@@ -205,7 +205,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result,
   net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
 
   anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
-			      1024, &net_buffer.ptr, NULL, NULL, NULL);
+			      1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
   if (anslen < 0)
     {
       /* Nothing found.  */
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 1325f97..c5c3402 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -98,7 +98,7 @@ static int
 __libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
 			int class, int type, u_char *answer, int anslen,
 			u_char **answerp, u_char **answerp2, int *nanswerp2,
-			int *resplen2);
+			int *resplen2, int *answerp2_malloced);
 
 /*
  * Formulate a normal query, send, and await answer.
@@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp,
 		  u_char **answerp,	/* if buffer needs to be enlarged */
 		  u_char **answerp2,
 		  int *nanswerp2,
-		  int *resplen2)
+		  int *resplen2,
+		  int *answerp2_malloced)
 {
 	HEADER *hp = (HEADER *) answer;
 	HEADER *hp2;
@@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp,
 	}
 	assert (answerp == NULL || (void *) *answerp == (void *) answer);
 	n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
-			     anslen, answerp, answerp2, nanswerp2, resplen2);
+			     anslen, answerp, answerp2, nanswerp2, resplen2,
+			     answerp2_malloced);
 	if (use_malloc)
 		free (buf);
 	if (n < 0) {
@@ -316,7 +318,7 @@ res_nquery(res_state statp,
 	   int anslen)		/* size of answer buffer */
 {
 	return __libc_res_nquery(statp, name, class, type, answer, anslen,
-				 NULL, NULL, NULL, NULL);
+				 NULL, NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nquery)
 
@@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp,
 		   u_char **answerp,
 		   u_char **answerp2,
 		   int *nanswerp2,
-		   int *resplen2)
+		   int *resplen2,
+		   int *answerp2_malloced)
 {
 	const char *cp, * const *domain;
 	HEADER *hp = (HEADER *) answer;
@@ -360,7 +363,7 @@ __libc_res_nsearch(res_state statp,
 	if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
 		return (__libc_res_nquery(statp, cp, class, type, answer,
 					  anslen, answerp, answerp2,
-					  nanswerp2, resplen2));
+					  nanswerp2, resplen2, answerp2_malloced));
 
 #ifdef DEBUG
 	if (statp->options & RES_DEBUG)
@@ -377,7 +380,8 @@ __libc_res_nsearch(res_state statp,
 	if (dots >= statp->ndots || trailing_dot) {
 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
 					      answer, anslen, answerp,
-					      answerp2, nanswerp2, resplen2);
+					      answerp2, nanswerp2, resplen2,
+					      answerp2_malloced);
 		if (ret > 0 || trailing_dot)
 			return (ret);
 		saved_herrno = h_errno;
@@ -386,11 +390,11 @@ __libc_res_nsearch(res_state statp,
 			answer = *answerp;
 			anslen = MAXPACKET;
 		}
-		if (answerp2
-		    && (*answerp2 < answer || *answerp2 >= answer + anslen))
+		if (answerp2 && *answerp2_malloced)
 		  {
 		    free (*answerp2);
 		    *answerp2 = NULL;
+		    *answerp2_malloced = 0;
 		  }
 	}
 
@@ -417,7 +421,7 @@ __libc_res_nsearch(res_state statp,
 						      class, type,
 						      answer, anslen, answerp,
 						      answerp2, nanswerp2,
-						      resplen2);
+						      resplen2, answerp2_malloced);
 			if (ret > 0)
 				return (ret);
 
@@ -425,12 +429,11 @@ __libc_res_nsearch(res_state statp,
 				answer = *answerp;
 				anslen = MAXPACKET;
 			}
-			if (answerp2
-			    && (*answerp2 < answer
-				|| *answerp2 >= answer + anslen))
+			if (answerp2 && *answerp2_malloced)
 			  {
 			    free (*answerp2);
 			    *answerp2 = NULL;
+			    *answerp2_malloced = 0;
 			  }
 
 			/*
@@ -486,7 +489,8 @@ __libc_res_nsearch(res_state statp,
 	    && !(tried_as_is || root_on_list)) {
 		ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
 					      answer, anslen, answerp,
-					      answerp2, nanswerp2, resplen2);
+					      answerp2, nanswerp2, resplen2,
+					      answerp2_malloced);
 		if (ret > 0)
 			return (ret);
 	}
@@ -498,10 +502,11 @@ __libc_res_nsearch(res_state statp,
 	 * else send back meaningless H_ERRNO, that being the one from
 	 * the last DNSRCH we did.
 	 */
-	if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen))
+	if (answerp2 && *answerp2_malloced)
 	  {
 	    free (*answerp2);
 	    *answerp2 = NULL;
+	    *answerp2_malloced = 0;
 	  }
 	if (saved_herrno != -1)
 		RES_SET_H_ERRNO(statp, saved_herrno);
@@ -521,7 +526,7 @@ res_nsearch(res_state statp,
 	    int anslen)		/* size of answer */
 {
 	return __libc_res_nsearch(statp, name, class, type, answer,
-				  anslen, NULL, NULL, NULL, NULL);
+				  anslen, NULL, NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nsearch)
 
@@ -539,7 +544,8 @@ __libc_res_nquerydomain(res_state statp,
 			u_char **answerp,
 			u_char **answerp2,
 			int *nanswerp2,
-			int *resplen2)
+			int *resplen2,
+			int *answerp2_malloced)
 {
 	char nbuf[MAXDNAME];
 	const char *longname = nbuf;
@@ -581,7 +587,7 @@ __libc_res_nquerydomain(res_state statp,
 	}
 	return (__libc_res_nquery(statp, longname, class, type, answer,
 				  anslen, answerp, answerp2, nanswerp2,
-				  resplen2));
+				  resplen2, answerp2_malloced));
 }
 
 int
@@ -593,7 +599,8 @@ res_nquerydomain(res_state statp,
 	    int anslen)		/* size of answer */
 {
 	return __libc_res_nquerydomain(statp, name, domain, class, type,
-				       answer, anslen, NULL, NULL, NULL, NULL);
+				       answer, anslen, NULL, NULL, NULL, NULL,
+				       NULL);
 }
 libresolv_hidden_def (res_nquerydomain)
 
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 7f2e85f..704542c 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -186,12 +186,12 @@ evNowTime(struct timespec *res) {
 static int		send_vc(res_state, const u_char *, int,
 				const u_char *, int,
 				u_char **, int *, int *, int, u_char **,
-				u_char **, int *, int *);
+				u_char **, int *, int *, int *);
 static int		send_dg(res_state, const u_char *, int,
 				const u_char *, int,
 				u_char **, int *, int *, int,
 				int *, int *, u_char **,
-				u_char **, int *, int *);
+				u_char **, int *, int *, int *);
 #ifdef DEBUG
 static void		Aerror(const res_state, FILE *, const char *, int,
 			       const struct sockaddr *);
@@ -343,7 +343,7 @@ int
 __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 		 const u_char *buf2, int buflen2,
 		 u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
-		 int *nansp2, int *resplen2)
+		 int *nansp2, int *resplen2, int *ansp2_malloced)
 {
   int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
 
@@ -546,7 +546,8 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 			try = statp->retry;
 			n = send_vc(statp, buf, buflen, buf2, buflen2,
 				    &ans, &anssiz, &terrno,
-				    ns, ansp, ansp2, nansp2, resplen2);
+				    ns, ansp, ansp2, nansp2, resplen2,
+				    ansp2_malloced);
 			if (n < 0)
 				return (-1);
 			if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -556,7 +557,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
 			n = send_dg(statp, buf, buflen, buf2, buflen2,
 				    &ans, &anssiz, &terrno,
 				    ns, &v_circuit, &gotsomewhere, ansp,
-				    ansp2, nansp2, resplen2);
+				    ansp2, nansp2, resplen2, ansp2_malloced);
 			if (n < 0)
 				return (-1);
 			if (n == 0 && (buf2 == NULL || *resplen2 == 0))
@@ -646,7 +647,7 @@ res_nsend(res_state statp,
 	  const u_char *buf, int buflen, u_char *ans, int anssiz)
 {
   return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
-			  NULL, NULL, NULL, NULL);
+			  NULL, NULL, NULL, NULL, NULL);
 }
 libresolv_hidden_def (res_nsend)
 
@@ -657,7 +658,7 @@ send_vc(res_state statp,
 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
 	u_char **ansp, int *anssizp,
 	int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
-	int *resplen2)
+	int *resplen2, int *ansp2_malloced)
 {
 	const HEADER *hp = (HEADER *) buf;
 	const HEADER *hp2 = (HEADER *) buf2;
@@ -823,6 +824,8 @@ send_vc(res_state statp,
 			}
 			*thisanssizp = MAXPACKET;
 			*thisansp = newp;
+			if (thisansp == ansp2)
+			  *ansp2_malloced = 1;
 			anhp = (HEADER *) newp;
 			len = rlen;
 		} else {
@@ -992,7 +995,7 @@ send_dg(res_state statp,
 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
 	u_char **ansp, int *anssizp,
 	int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
-	u_char **ansp2, int *anssizp2, int *resplen2)
+	u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
 {
 	const HEADER *hp = (HEADER *) buf;
 	const HEADER *hp2 = (HEADER *) buf2;
@@ -1238,6 +1241,8 @@ send_dg(res_state statp,
 			if (newp != NULL) {
 				*anssizp = MAXPACKET;
 				*thisansp = ans = newp;
+				if (thisansp == ansp2)
+				  *ansp2_malloced = 1;
 			}
 		}
 		HEADER *anhp = (HEADER *) *thisansp;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c6ce0dadcfd14973ba880f4e043058a9367f00ce

commit c6ce0dadcfd14973ba880f4e043058a9367f00ce
Author: OndÅ?ej Bílka <neleai@seznam.cz>
Date:   Sun Feb 16 12:59:23 2014 +0100

    Deduplicate resolv/nss_dns/dns-host.c
    
    In resolv/nss_dns/dns-host.c one of code path duplicated code after
    that. We merge these paths.
    
    (cherry picked from commit ab7ac0f2cf8731fe4c3f3aea6088a7c0127b5725)

diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index f56dd35..71b3b96 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -315,7 +315,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
   int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
 			      host_buffer.buf->buf, anslen, &host_buffer.ptr,
 			      &ans2p, &nans2p, &resplen2);
-  if (n < 0)
+  if (n >= 0)
+    {
+      status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
+			       resplen2, name, pat, buffer, buflen,
+			       errnop, herrnop, ttlp);
+    }
+  else
     {
       switch (errno)
 	{
@@ -342,17 +348,8 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 	*errnop = EAGAIN;
       else
 	__set_errno (olderr);
-
-      if (host_buffer.buf != orig_host_buffer)
-	free (host_buffer.buf);
-
-      return status;
     }
 
-  status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
-			  resplen2, name, pat, buffer, buflen,
-			  errnop, herrnop, ttlp);
-
   /* Check whether ans2p was separately allocated.  */
   if (host_buffer.buf != orig_host_buffer)
     anslen = MAXPACKET;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4ad0ab7bdb6c4afb3fc561c6497759eb939d2a73

commit 4ad0ab7bdb6c4afb3fc561c6497759eb939d2a73
Author: Andreas Schwab <schwab@suse.de>
Date:   Thu Feb 13 11:01:57 2014 +0100

    Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer
    
    (cherry picked from commit d668061994a7486a3ba9c7d5e7882d85a2883707)
    
    Conflicts:
    	NEWS

diff --git a/ChangeLog b/ChangeLog
index 60db892..2efb7a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-02-13  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #16574]
+	* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname4_r): Free the
+	second answer buffer if it was separately allocated.
+
 2014-05-12  Andreas Schwab  <schwab@suse.de>
 
 	[BZ #16932]
diff --git a/NEWS b/NEWS
index d10a3aa..d2b3419 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16623, 16882, 16885, 16916, 16932, 16943, 16958, 17048.
+  16545, 16574, 16623, 16882, 16885, 16916, 16932, 16943, 16958, 17048.
 
 * CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
   copy the path argument.  This allowed programs to cause posix_spawn to
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index f8f192e..f56dd35 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -298,13 +298,14 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 	name = cp;
     }
 
+  int anslen = 2048;
   union
   {
     querybuf *buf;
     u_char *ptr;
   } host_buffer;
   querybuf *orig_host_buffer;
-  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048);
+  host_buffer.buf = orig_host_buffer = (querybuf *) alloca (anslen);
   u_char *ans2p = NULL;
   int nans2p = 0;
   int resplen2 = 0;
@@ -312,7 +313,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
   int olderr = errno;
   enum nss_status status;
   int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
-			      host_buffer.buf->buf, 2048, &host_buffer.ptr,
+			      host_buffer.buf->buf, anslen, &host_buffer.ptr,
 			      &ans2p, &nans2p, &resplen2);
   if (n < 0)
     {
@@ -352,6 +353,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 			  resplen2, name, pat, buffer, buflen,
 			  errnop, herrnop, ttlp);
 
+  /* Check whether ans2p was separately allocated.  */
+  if (host_buffer.buf != orig_host_buffer)
+    anslen = MAXPACKET;
+  if (ans2p != NULL
+      && (ans2p < host_buffer.ptr || ans2p >= host_buffer.ptr + anslen))
+    free (ans2p);
+
   if (host_buffer.buf != orig_host_buffer)
     free (host_buffer.buf);
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=00a84253c5bc7dffb7a0a666cea21ea5e0288771

commit 00a84253c5bc7dffb7a0a666cea21ea5e0288771
Author: Andreas Schwab <schwab@suse.de>
Date:   Thu May 8 16:53:01 2014 +0200

    Fix unbound stack use in NIS NSS module
    
    (cherry picked from commit 315eb1d86aea489cd6325fd1c2521dcfb4fc0e1c)
    
    Conflicts:
    	NEWS

diff --git a/ChangeLog b/ChangeLog
index ef754cf..60db892 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2014-05-12  Andreas Schwab  <schwab@suse.de>
+
+	[BZ #16932]
+	* nis/nss_nis/nis-hosts.c (internal_gethostbyname2_r)
+	(_nss_nis_gethostbyname4_r): Return error if item length is larger
+	than maximum RPC packet size.
+	* nis/nss_nis/nis-initgroups.c (initgroups_netid): Likewise.
+	* nis/nss_nis/nis-network.c (_nss_nis_getnetbyname_r): Likewise.
+	* nis/nss_nis/nis-service.c (_nss_nis_getservbyname_r)
+	(_nss_nis_getservbyport_r): Likewise.
+
 2014-06-21  Allan McRae  <allan@archlinux.org>
 
 	* NEWS: Mention CVE-2014-4043.
diff --git a/NEWS b/NEWS
index 4a51ac6..d10a3aa 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16623, 16882, 16885, 16916, 16943, 16958, 17048.
+  16545, 16623, 16882, 16885, 16916, 16932, 16943, 16958, 17048.
 
 * CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
   copy the path argument.  This allowed programs to cause posix_spawn to
diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c
index f73a0ec..3006a99 100644
--- a/nis/nss_nis/nis-hosts.c
+++ b/nis/nss_nis/nis-hosts.c
@@ -270,6 +270,13 @@ internal_gethostbyname2_r (const char *name, int af, struct hostent *host,
 
   /* Convert name to lowercase.  */
   size_t namlen = strlen (name);
+  /* Limit name length to the maximum size of an RPC packet.  */
+  if (namlen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char name2[namlen + 1];
   size_t i;
 
@@ -461,6 +468,13 @@ _nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 
   /* Convert name to lowercase.  */
   size_t namlen = strlen (name);
+  /* Limit name length to the maximum size of an RPC packet.  */
+  if (namlen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char name2[namlen + 1];
   size_t i;
 
diff --git a/nis/nss_nis/nis-initgroups.c b/nis/nss_nis/nis-initgroups.c
index 30bc90f..dd8c765 100644
--- a/nis/nss_nis/nis-initgroups.c
+++ b/nis/nss_nis/nis-initgroups.c
@@ -150,6 +150,13 @@ initgroups_netid (uid_t uid, gid_t group, long int *start, long int *size,
 		  gid_t **groupsp, long int limit, int *errnop,
 		  const char *domainname)
 {
+  /* Limit domainname length to the maximum size of an RPC packet.  */
+  if (strlen (domainname) > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   /* Prepare the key.  The form is "unix.UID@DOMAIN" with the UID and
      DOMAIN field filled in appropriately.  */
   char key[sizeof ("unix.@") + sizeof (uid_t) * 3 + strlen (domainname)];
diff --git a/nis/nss_nis/nis-network.c b/nis/nss_nis/nis-network.c
index da28860..6a82302 100644
--- a/nis/nss_nis/nis-network.c
+++ b/nis/nss_nis/nis-network.c
@@ -179,6 +179,13 @@ _nss_nis_getnetbyname_r (const char *name, struct netent *net, char *buffer,
 
   /* Convert name to lowercase.  */
   size_t namlen = strlen (name);
+  /* Limit name length to the maximum size of an RPC packet.  */
+  if (namlen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char name2[namlen + 1];
   size_t i;
 
diff --git a/nis/nss_nis/nis-service.c b/nis/nss_nis/nis-service.c
index fd79d3f..4991ed3 100644
--- a/nis/nss_nis/nis-service.c
+++ b/nis/nss_nis/nis-service.c
@@ -271,6 +271,13 @@ _nss_nis_getservbyname_r (const char *name, const char *protocol,
   /* If the protocol is given, we could try if our NIS server knows
      about services.byservicename map. If yes, we only need one query.  */
   size_t keylen = strlen (name) + (protocol ? 1 + strlen (protocol) : 0);
+  /* Limit key length to the maximum size of an RPC packet.  */
+  if (keylen > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   char key[keylen + 1];
 
   /* key is: "name/proto" */
@@ -355,6 +362,13 @@ _nss_nis_getservbyport_r (int port, const char *protocol,
      Otherwise try first port/tcp, then port/udp and then fallback
      to sequential scanning of services.byname.  */
   const char *proto = protocol != NULL ? protocol : "tcp";
+  /* Limit protocol name length to the maximum size of an RPC packet.  */
+  if (strlen (proto) > UDPMSGSIZE)
+    {
+      *errnop = ERANGE;
+      return NSS_STATUS_UNAVAIL;
+    }
+
   do
     {
       /* key is: "port/proto" */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=30026b69015db3f82407df83dc1118518ee1fa5c

commit 30026b69015db3f82407df83dc1118518ee1fa5c
Author: Allan McRae <allan@archlinux.org>
Date:   Sat Jun 21 17:23:55 2014 +1000

    Mention CVE-2014-4043 in NEWS
    
    (cherry picked from commit d03efb2f979defd473955a455d66b949961d26b2)
    
    Conflicts:
    	NEWS

diff --git a/ChangeLog b/ChangeLog
index 1c9518c..ef754cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-06-21  Allan McRae  <allan@archlinux.org>
+
+	* NEWS: Mention CVE-2014-4043.
+
 2014-06-11  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #17048]
diff --git a/NEWS b/NEWS
index 9539294..4a51ac6 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,12 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   16545, 16623, 16882, 16885, 16916, 16943, 16958, 17048.
+
+* CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
+  copy the path argument.  This allowed programs to cause posix_spawn to
+  deference a dangling pointer, or use an unexpected pathname argument if
+  the string was modified after the posix_spawn_file_actions_addopen
+  invocation.
 
 Version 2.19
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e698ea2c03ddfdfa87459c1a0e53e2a4289de0fa

commit e698ea2c03ddfdfa87459c1a0e53e2a4289de0fa
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed Jun 11 23:12:52 2014 +0200

    posix_spawn_file_actions_addopen needs to copy the path argument (BZ 17048)
    
    POSIX requires that we make a copy, so we allocate a new string
    and free it in posix_spawn_file_actions_destroy.
    
    Reported by David Reid, Alex Gaynor, and Glyph Lefkowitz.  This bug
    may have security implications.
    
    (cherry picked from commit 89e435f3559c53084498e9baad22172b64429362)
    
    Conflicts:
    	NEWS

diff --git a/ChangeLog b/ChangeLog
index 7fa7e06..1c9518c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-06-11  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17048]
+	* posix/spawn_int.h (struct __spawn_action): Make the path string
+	non-const to support deallocation.
+	* posix/spawn_faction_addopen.c
+	(posix_spawn_file_actions_addopen): Make a copy of the pathname.
+	* posix/spawn_faction_destroy.c
+	(posix_spawn_file_actions_destroy): Adjust comment.  Deallocate
+	path in all spawn_do_open actions.
+	* posix/tst-spawn.c (do_test): Exercise the copy operation in
+	posix_spawn_file_actions_addopen.
+
 2014-06-03  Guo Yixuan  <culu.gyx@gmail.com>
 
 	[BZ #16882]
diff --git a/NEWS b/NEWS
index 64b2b11..9539294 100644
--- a/NEWS
+++ b/NEWS
@@ -9,8 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16623, 16882, 16885, 16916, 16943, 16958.
-
+  16545, 16623, 16882, 16885, 16916, 16943, 16958, 17048.
 
 Version 2.19
 
diff --git a/posix/spawn_faction_addopen.c b/posix/spawn_faction_addopen.c
index 47f6242..40800b8 100644
--- a/posix/spawn_faction_addopen.c
+++ b/posix/spawn_faction_addopen.c
@@ -35,17 +35,24 @@ posix_spawn_file_actions_addopen (posix_spawn_file_actions_t *file_actions,
   if (fd < 0 || fd >= maxfd)
     return EBADF;
 
+  char *path_copy = strdup (path);
+  if (path_copy == NULL)
+    return ENOMEM;
+
   /* Allocate more memory if needed.  */
   if (file_actions->__used == file_actions->__allocated
       && __posix_spawn_file_actions_realloc (file_actions) != 0)
-    /* This can only mean we ran out of memory.  */
-    return ENOMEM;
+    {
+      /* This can only mean we ran out of memory.  */
+      free (path_copy);
+      return ENOMEM;
+    }
 
   /* Add the new value.  */
   rec = &file_actions->__actions[file_actions->__used];
   rec->tag = spawn_do_open;
   rec->action.open_action.fd = fd;
-  rec->action.open_action.path = path;
+  rec->action.open_action.path = path_copy;
   rec->action.open_action.oflag = oflag;
   rec->action.open_action.mode = mode;
 
diff --git a/posix/spawn_faction_destroy.c b/posix/spawn_faction_destroy.c
index 4d165aa..1b87010 100644
--- a/posix/spawn_faction_destroy.c
+++ b/posix/spawn_faction_destroy.c
@@ -18,11 +18,29 @@
 #include <spawn.h>
 #include <stdlib.h>
 
-/* Initialize data structure for file attribute for `spawn' call.  */
+#include "spawn_int.h"
+
+/* Deallocate the file actions.  */
 int
 posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
 {
-  /* Free the memory allocated.  */
+  /* Free the paths in the open actions.  */
+  for (int i = 0; i < file_actions->__used; ++i)
+    {
+      struct __spawn_action *sa = &file_actions->__actions[i];
+      switch (sa->tag)
+	{
+	case spawn_do_open:
+	  free (sa->action.open_action.path);
+	  break;
+	case spawn_do_close:
+	case spawn_do_dup2:
+	  /* No cleanup required.  */
+	  break;
+	}
+    }
+
+  /* Free the array of actions.  */
   free (file_actions->__actions);
   return 0;
 }
diff --git a/posix/spawn_int.h b/posix/spawn_int.h
index 5609e58..861e3b4 100644
--- a/posix/spawn_int.h
+++ b/posix/spawn_int.h
@@ -22,7 +22,7 @@ struct __spawn_action
     struct
     {
       int fd;
-      const char *path;
+      char *path;
       int oflag;
       mode_t mode;
     } open_action;
diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c
index 84cecf2..6cd874a 100644
--- a/posix/tst-spawn.c
+++ b/posix/tst-spawn.c
@@ -168,6 +168,7 @@ do_test (int argc, char *argv[])
   char fd2name[18];
   char fd3name[18];
   char fd4name[18];
+  char *name3_copy;
   char *spargv[12];
   int i;
 
@@ -222,9 +223,15 @@ do_test (int argc, char *argv[])
    if (posix_spawn_file_actions_addclose (&actions, fd1) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose");
    /* We want to open the third file.  */
-   if (posix_spawn_file_actions_addopen (&actions, fd3, name3,
+   name3_copy = strdup (name3);
+   if (name3_copy == NULL)
+     error (EXIT_FAILURE, errno, "strdup");
+   if (posix_spawn_file_actions_addopen (&actions, fd3, name3_copy,
 					 O_RDONLY, 0666) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen");
+   /* Overwrite the name to check that a copy has been made.  */
+   memset (name3_copy, 'X', strlen (name3_copy));
+
    /* We dup the second descriptor.  */
    fd4 = MAX (2, MAX (fd1, MAX (fd2, fd3))) + 1;
    if (posix_spawn_file_actions_adddup2 (&actions, fd2, fd4) != 0)
@@ -253,6 +260,7 @@ do_test (int argc, char *argv[])
    /* Cleanup.  */
    if (posix_spawn_file_actions_destroy (&actions) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy");
+   free (name3_copy);
 
   /* Wait for the child.  */
   if (waitpid (pid, &status, 0) != pid)

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]