aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-deps.c
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-02-08 15:22:49 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-04-27 08:36:09 -0300
commit3a0588ae48fb35384a6bd33f9b66403badfa1262 (patch)
tree8f4b424ebe3df7a96dc5054c0d6461d861239b13 /elf/dl-deps.c
parent4f7b7d00e02e22acdda8c13e6db47d12a791c5e3 (diff)
downloadglibc-3a0588ae48fb35384a6bd33f9b66403badfa1262.zip
glibc-3a0588ae48fb35384a6bd33f9b66403badfa1262.tar.gz
glibc-3a0588ae48fb35384a6bd33f9b66403badfa1262.tar.bz2
elf: Fix DFS sorting algorithm for LD_TRACE_LOADED_OBJECTS with missing libraries (BZ #28868)
On _dl_map_object the underlying file is not opened in trace mode (in other cases where the underlying file can't be opened, _dl_map_object quits with an error). If there any missing libraries being processed, they will not be considered on final nlist size passed on _dl_sort_maps later in the function. And it is then used by _dl_sort_maps_dfs on the stack allocated working maps: 222 /* Array to hold RPO sorting results, before we copy back to maps[]. */ 223 struct link_map *rpo[nmaps]; 224 225 /* The 'head' position during each DFS iteration. Note that we start at 226 one past the last element due to first-decrement-then-store (see the 227 bottom of above dfs_traversal() routine). */ 228 struct link_map **rpo_head = &rpo[nmaps]; However while transversing the 'l_initfini' on dfs_traversal it will still consider the l_faked maps and thus update rpo more times than the allocated working 'rpo', overflowing the stack object. As suggested in bugzilla, one option would be to avoid sorting the maps for trace mode. However I think ignoring l_faked object does make sense (there is one less constraint to call the sorting function), it allows a slight less stack usage for trace, and it is slight simpler solution. The tests does trigger the stack overflow, however I tried to make it more generic to check different scenarios or missing objects. Checked on x86_64-linux-gnu. Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Diffstat (limited to 'elf/dl-deps.c')
-rw-r--r--elf/dl-deps.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index a2fc278..06005a0 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -473,6 +473,8 @@ _dl_map_object_deps (struct link_map *map,
for (nlist = 0, runp = known; runp; runp = runp->next)
{
+ /* _dl_sort_maps ignores l_faked object, so it is safe to not consider
+ them for nlist. */
if (__builtin_expect (trace_mode, 0) && runp->map->l_faked)
/* This can happen when we trace the loading. */
--map->l_searchlist.r_nlist;