_dl_map_object_deps: Use struct scratch_buffer [BZ #18023]

The function comment suggests that _dl_map_object_deps cannot use
malloc, but it already allocates the l_initfini array on the heap, so
the additional allocation should be acceptable.
This commit is contained in:
Florian Weimer 2018-06-27 17:55:55 +02:00
parent 890c2ced35
commit 92d6aa8528
2 changed files with 22 additions and 12 deletions

View File

@ -1,3 +1,9 @@
2018-06-27 Florian Weimer <fweimer@redhat.com>
[BZ #18023]
* elf/dl-deps.c (_dl_map_object_deps): Use struct
scratch_buffer instead of extend_alloca.
2018-06-27 Florian Weimer <fweimer@redhat.com> 2018-06-27 Florian Weimer <fweimer@redhat.com>
[BZ #18023] [BZ #18023]

View File

@ -27,6 +27,7 @@
#include <unistd.h> #include <unistd.h>
#include <sys/param.h> #include <sys/param.h>
#include <ldsodefs.h> #include <ldsodefs.h>
#include <scratch_buffer.h>
#include <dl-dst.h> #include <dl-dst.h>
@ -181,9 +182,8 @@ _dl_map_object_deps (struct link_map *map,
/* Pointer to last unique object. */ /* Pointer to last unique object. */
tail = &known[nlist - 1]; tail = &known[nlist - 1];
/* No alloca'd space yet. */ struct scratch_buffer needed_space;
struct link_map **needed_space = NULL; scratch_buffer_init (&needed_space);
size_t needed_space_bytes = 0;
/* Process each element of the search list, loading each of its /* Process each element of the search list, loading each of its
auxiliary objects and immediate dependencies. Auxiliary objects auxiliary objects and immediate dependencies. Auxiliary objects
@ -213,13 +213,12 @@ _dl_map_object_deps (struct link_map *map,
if (l->l_searchlist.r_list == NULL && l->l_initfini == NULL if (l->l_searchlist.r_list == NULL && l->l_initfini == NULL
&& l != map && l->l_ldnum > 0) && l != map && l->l_ldnum > 0)
{ {
size_t new_size = l->l_ldnum * sizeof (struct link_map *); /* l->l_ldnum includes space for the terminating NULL. */
if (!scratch_buffer_set_array_size
if (new_size > needed_space_bytes) (&needed_space, l->l_ldnum, sizeof (struct link_map *)))
needed_space _dl_signal_error (ENOMEM, map->l_name, NULL,
= extend_alloca (needed_space, needed_space_bytes, new_size); N_("cannot allocate dependency buffer"));
needed = needed_space.data;
needed = needed_space;
} }
if (l->l_info[DT_NEEDED] || l->l_info[AUXTAG] || l->l_info[FILTERTAG]) if (l->l_info[DT_NEEDED] || l->l_info[AUXTAG] || l->l_info[FILTERTAG])
@ -438,8 +437,11 @@ _dl_map_object_deps (struct link_map *map,
struct link_map **l_initfini = (struct link_map **) struct link_map **l_initfini = (struct link_map **)
malloc ((2 * nneeded + 1) * sizeof needed[0]); malloc ((2 * nneeded + 1) * sizeof needed[0]);
if (l_initfini == NULL) if (l_initfini == NULL)
_dl_signal_error (ENOMEM, map->l_name, NULL, {
N_("cannot allocate dependency list")); scratch_buffer_free (&needed_space);
_dl_signal_error (ENOMEM, map->l_name, NULL,
N_("cannot allocate dependency list"));
}
l_initfini[0] = l; l_initfini[0] = l;
memcpy (&l_initfini[1], needed, nneeded * sizeof needed[0]); memcpy (&l_initfini[1], needed, nneeded * sizeof needed[0]);
memcpy (&l_initfini[nneeded + 1], l_initfini, memcpy (&l_initfini[nneeded + 1], l_initfini,
@ -457,6 +459,8 @@ _dl_map_object_deps (struct link_map *map,
} }
out: out:
scratch_buffer_free (&needed_space);
if (errno == 0 && errno_saved != 0) if (errno == 0 && errno_saved != 0)
__set_errno (errno_saved); __set_errno (errno_saved);