From 4d4c53bc13fb1dc04ebe1cb3edd7125ab8852d2e Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Wed, 22 Sep 2010 12:06:30 +0200 Subject: [PATCH] Fix memory leak on init/fini dependency list --- ChangeLog | 7 +++++++ elf/dl-deps.c | 2 ++ elf/dl-libc.c | 6 +++++- elf/rtld.c | 1 + include/link.h | 3 +++ 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e08b060d99d..3351f492004 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2010-09-27 Andreas Schwab + * 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. diff --git a/elf/dl-deps.c b/elf/dl-deps.c index a58de5c985e..e5b9cdfc5a0 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -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 (); diff --git a/elf/dl-libc.c b/elf/dl-libc.c index 7be9483de6f..a13fce3b4ba 100644 --- a/elf/dl-libc.c +++ b/elf/dl-libc.c @@ -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 diff --git a/elf/rtld.c b/elf/rtld.c index 2e266b1d278..9a560b3ced6 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -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, diff --git a/include/link.h b/include/link.h index 9d1fc1a8fe7..051b99a47c8 100644 --- a/include/link.h +++ b/include/link.h @@ -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; -- 2.47.2