Skip to content

Commit

Permalink
Fix invalid memory access in do_lookup_x.
Browse files Browse the repository at this point in the history
[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.
  • Loading branch information
Andreas Schwab authored and Carlos O'Donell committed Jun 22, 2012
1 parent 0e3933b commit 0479b30
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 34 deletions.
11 changes: 11 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
25 changes: 13 additions & 12 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
15 changes: 3 additions & 12 deletions elf/dl-close.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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))
Expand Down
7 changes: 4 additions & 3 deletions elf/dl-deps.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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 ();
Expand All @@ -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,
Expand Down
9 changes: 6 additions & 3 deletions elf/dl-libc.c
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -269,20 +268,24 @@ 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;
lnp = lnp->next;
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
Expand Down
2 changes: 2 additions & 0 deletions elf/rtld.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions include/link.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 0479b30

Please sign in to comment.