From c9f65bd9f509de9c468304159378e49b307a1c56adcb2b5f2d740d645ad02b4c Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Tue, 22 Feb 2011 12:33:01 +0000 Subject: [PATCH] - Fix potential removal of required local scope from shared objects marked as NODELETE [bnc#657627] OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=49 --- glibc-elf-localscope.diff | 82 +++++++++++++++++++++++++++++++++++++++ glibc.changes | 6 +++ glibc.spec | 2 + 3 files changed, 90 insertions(+) create mode 100644 glibc-elf-localscope.diff diff --git a/glibc-elf-localscope.diff b/glibc-elf-localscope.diff new file mode 100644 index 0000000..edcd44a --- /dev/null +++ b/glibc-elf-localscope.diff @@ -0,0 +1,82 @@ +diff -ru elf~/dl-close.c elf/dl-close.c +--- elf~/dl-close.c 2011-02-04 00:35:03.000000000 +0100 ++++ elf/dl-close.c 2011-02-22 02:16:12.367883000 +0100 +@@ -180,24 +186,28 @@ + /* Signal the object is still needed. */ + l->l_idx = IDX_STILL_USED; + ++#define mark_used(dmap) \ ++ do { \ ++ if ((dmap)->l_idx != IDX_STILL_USED) \ ++ { \ ++ assert ((dmap)->l_idx >= 0 && (dmap)->l_idx < nloaded); \ ++ \ ++ if (!used[(dmap)->l_idx]) \ ++ { \ ++ used[(dmap)->l_idx] = 1; \ ++ if ((dmap)->l_idx - 1 < done_index) \ ++ done_index = (dmap)->l_idx - 1; \ ++ } \ ++ } \ ++ } while (0) ++ + /* Mark all dependencies as used. */ + if (l->l_initfini != NULL) + { + struct link_map **lp = &l->l_initfini[1]; + while (*lp != NULL) + { +- if ((*lp)->l_idx != IDX_STILL_USED) +- { +- assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded); +- +- if (!used[(*lp)->l_idx]) +- { +- used[(*lp)->l_idx] = 1; +- if ((*lp)->l_idx - 1 < done_index) +- done_index = (*lp)->l_idx - 1; +- } +- } +- ++ mark_used(*lp); + ++lp; + } + } +@@ -206,19 +216,25 @@ + for (unsigned int j = 0; j < l->l_reldeps->act; ++j) + { + struct link_map *jmap = l->l_reldeps->list[j]; +- +- if (jmap->l_idx != IDX_STILL_USED) +- { +- assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded); +- +- if (!used[jmap->l_idx]) +- { +- used[jmap->l_idx] = 1; +- if (jmap->l_idx - 1 < done_index) +- done_index = jmap->l_idx - 1; +- } +- } ++ mark_used(jmap); + } ++ /* And the same for owners of our scopes; normally, our last ++ scope provider would render us unused, but this can be ++ prevented by the NODELETE flag. */ ++ if (__builtin_expect(l->l_type == lt_loaded ++ && (l->l_flags_1 & DF_1_NODELETE), 0)) ++ for (size_t cnt = 0; l->l_scope[cnt] != NULL; ++cnt) ++ /* This relies on l_scope[] entries being always set either ++ to its own l_symbolic_searchlist address, or some map's ++ l_searchlist address. */ ++ if (l->l_scope[cnt] != &l->l_symbolic_searchlist) ++ { ++ struct link_map *ls = (struct link_map *) ++ ((char *) l->l_scope[cnt] ++ - offsetof (struct link_map, l_searchlist)); ++ assert (ls->l_ns == nsid); ++ mark_used(ls); ++ } + } + + /* Sort the entries. */ diff --git a/glibc.changes b/glibc.changes index 0fa266b..a04f7e7 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Feb 22 12:57:07 CET 2011 - pbaudis@suse.cz + +- Fix potential removal of required local scope from shared objects + marked as NODELETE [bnc#657627] + ------------------------------------------------------------------- Fri Feb 4 00:46:40 CET 2011 - pbaudis@suse.cz diff --git a/glibc.spec b/glibc.spec index 5b40911..174c6ae 100644 --- a/glibc.spec +++ b/glibc.spec @@ -137,6 +137,7 @@ Patch48: glibc-malloc-arena-max.diff Patch49: glibc-fini-unwind.diff Patch50: glibc-gconvcache-s390.diff Patch51: glibc-vfprintf-positional.diff +Patch52: glibc-elf-localscope.diff Patch500: ARM_glibc-2.10.1-local-eabi-wchar.diff Patch501: ARM_glibc-2.10.1-local-hwcap-updates.diff Patch502: ARM_glibc-2.10.1-local-lowlevellock.diff @@ -355,6 +356,7 @@ rm nscd/s-stamp %patch49 %patch50 %patch51 -p1 +%patch52 %ifarch %arm armv5tel armv7l %patch500 %patch501