]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix invalid memory access in do_lookup_x.
authorAndreas Schwab <schwab@redhat.com>
Fri, 22 Jun 2012 18:10:31 +0000 (11:10 -0700)
committerCarlos O'Donell <carlos_odonell@mentor.com>
Fri, 22 Jun 2012 18:10:31 +0000 (11:10 -0700)
[BZ #13579] Do not free l_initfini and allow it to be reused
on subsequent dl_open calls for the same library. This fixes
the invalid memory access in do_lookup_x when the previously
free'd l_initfini was accessed through l_searchlist when a
library had been opened for the second time.

ChangeLog
NEWS
elf/dl-close.c
elf/dl-deps.c
elf/dl-libc.c
elf/rtld.c
include/link.h

index b7f16994d2681cb8dff0fb124deea5dbd6b9ce07..89997843cfb4f7b09028fa2aa6d365e2e471a451 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2012-06-22  Andreas Schwab  <schwab@redhat.com>
+
+       [BZ #13579]
+       * 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/dl-close.c (_dl_close_worker): Don't free 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.
+
 2012-06-22  Carlos O'Donell  <carlos_odonell@mentor.com>
 
        * configure.in: Use AC_LANG_SOURCE.
diff --git a/NEWS b/NEWS
index 1ce8ee3508adc7a85cffcf78b56a2c8f8fccb68a..a9500faeb6dc0e563a9392fe27f857311670a22f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,18 +19,19 @@ Version 2.16
   12193, 12194, 12297, 12298, 12301, 12340, 12354, 12416, 12495, 13058,
   13223, 13361, 13525, 13526, 13527, 13528, 13529, 13530, 13531, 13532,
   13533, 13547, 13551, 13552, 13553, 13555, 13556, 13559, 13563, 13566,
-  13576, 13583, 13592, 13594, 13613, 13618, 13637, 13656, 13658, 13673,
-  13691, 13695, 13704, 13705, 13706, 13718, 13726, 13738, 13739, 13743,
-  13750, 13758, 13760, 13761, 13775, 13786, 13787, 13792, 13806, 13824,
-  13840, 13841, 13844, 13846, 13848, 13851, 13852, 13854, 13871, 13872,
-  13873, 13879, 13882, 13883, 13884, 13885, 13886, 13892, 13895, 13908,
-  13910, 13911, 13912, 13913, 13914, 13915, 13916, 13917, 13918, 13919,
-  13920, 13921, 13922, 13923, 13924, 13926, 13927, 13928, 13938, 13941,
-  13942, 13954, 13955, 13956, 13963, 13967, 13968, 13970, 13973, 13979,
-  13983, 13986, 13996, 14012, 14027, 14033, 14034, 14036, 14040, 14043,
-  14044, 14048, 14049, 14050, 14053, 14055, 14059, 14064, 14075, 14080,
-  14083, 14103, 14104, 14109, 14112, 14117, 14122, 14123, 14134, 14153,
-  14183, 14188, 14199, 14210, 14218, 14229, 14241, 14273, 14277, 14278
+  13576, 13579, 13583, 13592, 13594, 13613, 13618, 13637, 13656, 13658,
+  13673, 13691, 13695, 13704, 13705, 13706, 13718, 13726, 13738, 13739,
+  13743, 13750, 13758, 13760, 13761, 13775, 13786, 13787, 13792, 13806,
+  13824, 13840, 13841, 13844, 13846, 13848, 13851, 13852, 13854, 13871,
+  13872, 13873, 13879, 13882, 13883, 13884, 13885, 13886, 13892, 13895,
+  13908, 13910, 13911, 13912, 13913, 13914, 13915, 13916, 13917, 13918,
+  13919, 13920, 13921, 13922, 13923, 13924, 13926, 13927, 13928, 13938,
+  13941, 13942, 13954, 13955, 13956, 13963, 13967, 13968, 13970, 13973,
+  13979, 13983, 13986, 13996, 14012, 14027, 14033, 14034, 14036, 14040,
+  14043, 14044, 14048, 14049, 14050, 14053, 14055, 14059, 14064, 14075,
+  14080, 14083, 14103, 14104, 14109, 14112, 14117, 14122, 14123, 14134,
+  14153, 14183, 14188, 14199, 14210, 14218, 14229, 14241, 14273, 14277,
+  14278
 
 * Support for the x32 ABI on x86-64 added.  The x32 target is selected by
   configuring glibc with:
index d232294665572174c1fac7419e55f32a54f729c4..a250ea5e3e4882ec044b09b4cd811c07b8efc594 100644 (file)
@@ -1,5 +1,5 @@
 /* Close a shared object opened by `_dl_open'.
-   Copyright (C) 1996-2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1996-2012 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
@@ -118,17 +118,8 @@ _dl_close_worker (struct link_map *map)
   if (map->l_direct_opencount > 0 || map->l_type != lt_loaded
       || dl_close_state != not_pending)
     {
-      if (map->l_direct_opencount == 0)
-       {
-         if (map->l_type == lt_loaded)
-           dl_close_state = rerun;
-         else if (map->l_type == lt_library)
-           {
-             struct link_map **oldp = map->l_initfini;
-             map->l_initfini = map->l_orig_initfini;
-             _dl_scope_free (oldp);
-           }
-       }
+      if (map->l_direct_opencount == 0 && map->l_type == lt_loaded)
+       dl_close_state = rerun;
 
       /* There are still references to this object.  Do nothing more.  */
       if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
index 69aec461fb929bd51792a2b3ada64ef1cf6a91bb..2ae496d7b508d11375175baba05c0ca74fa2600d 100644 (file)
@@ -1,6 +1,5 @@
 /* Load the dependencies of a mapped object.
-   Copyright (C) 1996-2003, 2004-2007, 2010-2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1996-2012 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
@@ -488,6 +487,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.  */
@@ -688,6 +688,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 ();
@@ -696,7 +697,7 @@ Filters not supported with LD_TRACE_PRELINKING"));
       _dl_scope_free (old_l_reldeps);
     }
   if (old_l_initfini != NULL)
-      map->l_orig_initfini = old_l_initfini;
+    _dl_scope_free (old_l_initfini);
 
   if (errno_reason)
     _dl_signal_error (errno_reason == -1 ? 0 : errno_reason, objname,
index a58e2164f61970418b3655d1cb664be38086fd11..af2e663737ff79724fe48be64960f41c5f8f6bb6 100644 (file)
@@ -1,6 +1,5 @@
 /* Handle loading and unloading shared objects for internal libc purposes.
-   Copyright (C) 1999-2002,2004-2006,2009,2010,2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1999-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999.
 
@@ -269,13 +268,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;
@@ -283,6 +282,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 a5b0ab9815f3161fab83b0da5db89d302a6a7bad..6bcf224c498156614faad2b9b08827eb6aae5b55 100644 (file)
@@ -2292,6 +2292,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
              lnp->dont_free = 1;
              lnp = lnp->next;
            }
+         /* Also allocated with the fake malloc().  */
+         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 2eb3179475b5087da2ee6d804280ff47a3ea14de..f0c8ad521f99d30a9b481427e6282482d47bcfba 100644 (file)
@@ -1,6 +1,6 @@
 /* Data structure for communication from the run-time dynamic linker for
    loaded ELF shared objects.
-   Copyright (C) 1995-2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1995-2012 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
@@ -191,6 +191,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;
@@ -239,9 +242,6 @@ struct link_map
 
     /* List of object in order of the init and fini calls.  */
     struct link_map **l_initfini;
-    /* The init and fini list generated at startup, saved when the
-       object is also loaded dynamically.  */
-    struct link_map **l_orig_initfini;
 
     /* List of the dependencies introduced through symbol binding.  */
     struct link_map_reldeps