Author: aurel32
Date: 2012-06-02 14:45:05 +0000 (Sat, 02 Jun 2012)
New Revision: 5263

Added:
   glibc-package/trunk/debian/patches/any/cvs-getpwuid-nsswitch.diff
Modified:
   glibc-package/trunk/debian/changelog
   glibc-package/trunk/debian/patches/series
Log:
  * patches/any/cvs-getpwuid-nsswitch.diff: fix a memory leak in
    getpwuid/nsswitch.c.  Closes: #674072.



Modified: glibc-package/trunk/debian/changelog
===================================================================
--- glibc-package/trunk/debian/changelog        2012-06-02 13:46:44 UTC (rev 
5262)
+++ glibc-package/trunk/debian/changelog        2012-06-02 14:45:05 UTC (rev 
5263)
@@ -39,6 +39,8 @@
     hack.  Closes: #674602.
   * patches/any/cvs-regex.diff: fix access after end of search string in regex
     matcher.  Closes: #672688.
+  * patches/any/cvs-getpwuid-nsswitch.diff: fix a memory leak in
+    getpwuid/nsswitch.c.  Closes: #674072.
 
  -- Clint Adams <[email protected]>  Fri, 04 May 2012 23:39:00 -0400
 

Added: glibc-package/trunk/debian/patches/any/cvs-getpwuid-nsswitch.diff
===================================================================
--- glibc-package/trunk/debian/patches/any/cvs-getpwuid-nsswitch.diff           
                (rev 0)
+++ glibc-package/trunk/debian/patches/any/cvs-getpwuid-nsswitch.diff   
2012-06-02 14:45:05 UTC (rev 5263)
@@ -0,0 +1,169 @@
+2012-05-22  Paul Pluzhnikov  <[email protected]>
+
+       [BZ #14122]
+       * nss/nsswitch.c (defconfig_entries): New variable.
+       (__nss_database_lookup): Don't leak defconfig entries.
+       (nss_parse_service_list): Don't leak on error paths.
+       (free_database_entries): New function.
+       (free_defconfig): New function.
+       (free_mem): Move common code to free_database_entries.
+
+---
+ nss/nsswitch.c |   90 
+++++++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 69 insertions(+), 21 deletions(-)
+
+--- a/nss/nsswitch.c
++++ b/nss/nsswitch.c
+@@ -98,6 +98,12 @@
+ /* The root of the whole data base.  */
+ static name_database *service_table;
+ 
++/* List of default service lists that were generated by glibc because
++   /etc/nsswitch.conf did not provide a value.
++   The list is only maintained so we can free such service lists in
++   __libc_freeres.  */
++static name_database_entry *defconfig_entries;
++
+ #else /* __OPTION_EGLIBC_NSSWITCH */
+ 
+ /* Bring in the statically initialized service table we generated at
+@@ -164,8 +170,27 @@
+      DEFCONFIG specifies the default service list for this database,
+      or null to use the most common default.  */
+   if (*ni == NULL)
+-    *ni = nss_parse_service_list (defconfig
+-                                ?: "nis [NOTFOUND=return] files");
++    {
++      *ni = nss_parse_service_list (defconfig
++                                  ?: "nis [NOTFOUND=return] files");
++      if (*ni != NULL)
++      {
++        /* Record the memory we've just allocated in defconfig_entries list,
++           so we can free it later.  */
++        name_database_entry *entry;
++
++        /* Allocate ENTRY plus size of name (1 here).  */
++        entry = (name_database_entry *) malloc (sizeof (*entry) + 1);
++
++        if (entry != NULL)
++          {
++            entry->next = defconfig_entries;
++            entry->service = *ni;
++            entry->name[0] = '\0';
++            defconfig_entries = entry;
++          }
++      }
++    }
+ #else
+   /* Without the dynamic behavior, we can't process defconfig.  The
+      databases the user specified at library build time are all you
+@@ -677,7 +702,7 @@
+                 else if (__strncasecmp (name, "UNAVAIL", 7) == 0)
+                   status = NSS_STATUS_UNAVAIL;
+                 else
+-                  return result;
++                  goto finish;
+               }
+             else if (line - name == 8)
+               {
+@@ -686,15 +711,15 @@
+                 else if (__strncasecmp (name, "TRYAGAIN", 8) == 0)
+                   status = NSS_STATUS_TRYAGAIN;
+                 else
+-                  return result;
++                  goto finish;
+               }
+             else
+-              return result;
++              goto finish;
+ 
+             while (isspace (line[0]))
+               ++line;
+             if (line[0] != '=')
+-              return result;
++              goto finish;
+             do
+               ++line;
+             while (isspace (line[0]));
+@@ -710,7 +735,7 @@
+                      && __strncasecmp (name, "CONTINUE", 8) == 0)
+               action = NSS_ACTION_CONTINUE;
+             else
+-              return result;
++              goto finish;
+ 
+             if (not)
+               {
+@@ -738,6 +763,11 @@
+ 
+       *nextp = new_service;
+       nextp = &new_service->next;
++      continue;
++
++    finish:
++      free (new_service);
++      return result;
+     }
+ }
+ 
+@@ -825,21 +855,9 @@
+ 
+ 
+ #if __OPTION_EGLIBC_NSSWITCH
+-/* Free all resources if necessary.  */
+-libc_freeres_fn (free_mem)
++static void
++free_database_entries (name_database_entry *entry)
+ {
+-  name_database *top = service_table;
+-  name_database_entry *entry;
+-  service_library *library;
+-
+-  if (top == NULL)
+-    /* Maybe we have not read the nsswitch.conf file.  */
+-    return;
+-
+-  /* Don't disturb ongoing other threads (if there are any).  */
+-  service_table = NULL;
+-
+-  entry = top->entry;
+   while (entry != NULL)
+     {
+       name_database_entry *olde = entry;
+@@ -859,6 +877,36 @@
+       entry = entry->next;
+       free (olde);
+     }
++}
++
++/* Free all resources if necessary.  */
++libc_freeres_fn (free_defconfig)
++{
++  name_database_entry *entry = defconfig_entries;
++
++  if (entry == NULL)
++    /* defconfig was not used.  */
++    return;
++
++  /* Don't disturb ongoing other threads (if there are any).  */
++  defconfig_entries = NULL;
++
++  free_database_entries (entry);
++}
++
++libc_freeres_fn (free_mem)
++{
++  name_database *top = service_table;
++  service_library *library;
++
++  if (top == NULL)
++    /* Maybe we have not read the nsswitch.conf file.  */
++    return;
++
++  /* Don't disturb ongoing other threads (if there are any).  */
++  service_table = NULL;
++
++  free_database_entries (top->entry);
+ 
+   library = top->library;
+   while (library != NULL)

Modified: glibc-package/trunk/debian/patches/series
===================================================================
--- glibc-package/trunk/debian/patches/series   2012-06-02 13:46:44 UTC (rev 
5262)
+++ glibc-package/trunk/debian/patches/series   2012-06-02 14:45:05 UTC (rev 
5263)
@@ -354,3 +354,4 @@
 any/local-linuxthreads-setclock.diff
 any/cvs-FORTIFY_SOURCE-format-strings.diff
 any/cvs-regex.diff
+any/cvs-getpwuid-nsswitch.diff


-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]
Archive: http://lists.debian.org/[email protected]

Reply via email to