Fix invalid memory access in do_lookup_x.

[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.
This commit is contained in:
Andreas Schwab 2012-06-22 11:10:31 -07:00 committed by Carlos O'Donell
parent 0e3933b963
commit 0479b305c5
7 changed files with 43 additions and 34 deletions

View File

@ -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.

25
NEWS
View File

@ -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:

View 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))

View 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,

View 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

View 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,

View 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