]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix memory leak on init/fini dependency list
authorAndreas Schwab <schwab@redhat.com>
Wed, 22 Sep 2010 10:06:30 +0000 (12:06 +0200)
committerAndreas Schwab <schwab@redhat.com>
Mon, 27 Sep 2010 13:41:56 +0000 (15:41 +0200)
ChangeLog
elf/dl-deps.c
elf/dl-libc.c
elf/rtld.c
include/link.h

index e08b060d99d7fa94977ece3a90a98c2596797d70..3351f49200478fa4ed6037be451945c7e4f1fa87 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2010-09-27  Andreas Schwab  <schwab@redhat.com>
 
+       * include/link.h (struct link_map): Add l_free_initfini.
+       * elf/dl-deps.c (_dl_map_object_deps): Set it when assigning
+       l_initfini.
+       * elf/rtld.c (dl_main): Clear it on all objects loaded on startup.
+       * elf/dl-libc.c (free_mem): Free l_initfini if l_free_initfini is
+       set.
+
        [BZ #11561]
        * posix/regcomp.c (parse_bracket_exp): When looking up collating
        elements compare against the byte sequence of it, not its name.
index a58de5c985eb640d0764f59089ba2be3b8957057..e5b9cdfc5a0bd8c3045c742a6d6089eb03ebe425 100644 (file)
@@ -478,6 +478,7 @@ _dl_map_object_deps (struct link_map *map,
                  nneeded * sizeof needed[0]);
          atomic_write_barrier ();
          l->l_initfini = l_initfini;
+         l->l_free_initfini = 1;
        }
 
       /* If we have no auxiliary objects just go on to the next map.  */
@@ -662,6 +663,7 @@ Filters not supported with LD_TRACE_PRELINKING"));
   l_initfini[nlist] = NULL;
   atomic_write_barrier ();
   map->l_initfini = l_initfini;
+  map->l_free_initfini = 1;
   if (l_reldeps != NULL)
     {
       atomic_write_barrier ();
index 7be9483de6f86234450204728390feab8bedd9c5..a13fce3b4ba08d65deea99e523f0f18e0b74c458 100644 (file)
@@ -265,13 +265,13 @@ libc_freeres_fn (free_mem)
 
   for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
     {
-      /* Remove all additional names added to the objects.  */
       for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
        {
          struct libname_list *lnp = l->l_libname->next;
 
          l->l_libname->next = NULL;
 
+         /* Remove all additional names added to the objects.  */
          while (lnp != NULL)
            {
              struct libname_list *old = lnp;
@@ -279,6 +279,10 @@ libc_freeres_fn (free_mem)
              if (! old->dont_free)
                free (old);
            }
+
+         /* Free the initfini dependency list.  */
+         if (l->l_free_initfini)
+           free (l->l_initfini);
        }
 
       if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
index 2e266b1d278c1dc0e754e9f847043b5cff578561..9a560b3ced60daa7f0f52ca8b2191dbb0b2a5eec 100644 (file)
@@ -2240,6 +2240,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
              lnp->dont_free = 1;
              lnp = lnp->next;
            }
+         l->l_free_initfini = 0;
 
          if (l != &GL(dl_rtld_map))
            _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0,
index 9d1fc1a8fe71efce8fa3ebc8814a7f406c19ff3c..051b99a47c8a99cfb813edf9794235043fbde5f6 100644 (file)
@@ -192,6 +192,9 @@ struct link_map
                                                 during LD_TRACE_PRELINKING=1
                                                 contains any DT_SYMBOLIC
                                                 libraries.  */
+    unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be
+                                      freed, ie. not allocated with
+                                      the dummy malloc in ld.so.  */
 
     /* Collected information about own RPATH directories.  */
     struct r_search_path_struct l_rpath_dirs;