mirror of
https://github.com/openharmony/third_party_elfutils.git
synced 2026-07-19 19:43:34 -04:00
libdwfl: Don't allocate phdrs and dyn on stack in dwfl_segment_report_module.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
2015-05-22 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
* dwfl_segment_report_module.c (dwfl_segment_report_module):
|
||||
Allocate phdrs with malloc, not on stack. free in finish.
|
||||
Allocate dyn with malloc, not on stack, free after use.
|
||||
|
||||
2015-05-22 Mark Wielaard <mjw@redhat.com>
|
||||
|
||||
* find-debuginfo.c (find_debuginfo_in_path): malloc or strdup,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Sniff out modules from ELF headers visible in memory segments.
|
||||
Copyright (C) 2008-2012, 2014 Red Hat, Inc.
|
||||
Copyright (C) 2008-2012, 2014, 2015 Red Hat, Inc.
|
||||
This file is part of elfutils.
|
||||
|
||||
This file is free software; you can redistribute it and/or modify
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <gelf.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/param.h>
|
||||
#include <alloca.h>
|
||||
#include <endian.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
@@ -278,8 +277,13 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
|
||||
Elf *elf = NULL;
|
||||
int fd = -1;
|
||||
|
||||
/* We might have to reserve some memory for the phdrs. Set to NULL
|
||||
here so we can always safely free it. */
|
||||
void *phdrsp = NULL;
|
||||
|
||||
inline int finish (void)
|
||||
{
|
||||
free (phdrsp);
|
||||
release_buffer (&buffer, &buffer_available);
|
||||
if (elf != NULL)
|
||||
elf_end (elf);
|
||||
@@ -400,14 +404,19 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
|
||||
|
||||
xlatefrom.d_buf = ph_buffer;
|
||||
|
||||
union
|
||||
typedef union
|
||||
{
|
||||
Elf32_Phdr p32[phnum];
|
||||
Elf64_Phdr p64[phnum];
|
||||
} phdrs;
|
||||
} phdrsn;
|
||||
|
||||
xlateto.d_buf = &phdrs;
|
||||
xlateto.d_size = sizeof phdrs;
|
||||
phdrsp = malloc (sizeof (phdrsn));
|
||||
if (unlikely (phdrsp == NULL))
|
||||
return finish ();
|
||||
phdrsn *phdrs = (phdrsn *) phdrsp;
|
||||
|
||||
xlateto.d_buf = phdrs;
|
||||
xlateto.d_size = sizeof (phdrsn);
|
||||
|
||||
/* Track the bounds of the file visible in memory. */
|
||||
GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */
|
||||
@@ -570,10 +579,10 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
|
||||
found_bias = false; /* Trigger error check. */
|
||||
else
|
||||
for (uint_fast16_t i = 0; i < phnum; ++i)
|
||||
consider_phdr (phdrs.p32[i].p_type,
|
||||
phdrs.p32[i].p_vaddr, phdrs.p32[i].p_memsz,
|
||||
phdrs.p32[i].p_offset, phdrs.p32[i].p_filesz,
|
||||
phdrs.p32[i].p_align);
|
||||
consider_phdr (phdrs->p32[i].p_type,
|
||||
phdrs->p32[i].p_vaddr, phdrs->p32[i].p_memsz,
|
||||
phdrs->p32[i].p_offset, phdrs->p32[i].p_filesz,
|
||||
phdrs->p32[i].p_align);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -581,10 +590,10 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
|
||||
found_bias = false; /* Trigger error check. */
|
||||
else
|
||||
for (uint_fast16_t i = 0; i < phnum; ++i)
|
||||
consider_phdr (phdrs.p64[i].p_type,
|
||||
phdrs.p64[i].p_vaddr, phdrs.p64[i].p_memsz,
|
||||
phdrs.p64[i].p_offset, phdrs.p64[i].p_filesz,
|
||||
phdrs.p64[i].p_align);
|
||||
consider_phdr (phdrs->p64[i].p_type,
|
||||
phdrs->p64[i].p_vaddr, phdrs->p64[i].p_memsz,
|
||||
phdrs->p64[i].p_offset, phdrs->p64[i].p_filesz,
|
||||
phdrs->p64[i].p_align);
|
||||
}
|
||||
|
||||
finish_portion (&ph_buffer, &ph_buffer_size);
|
||||
@@ -735,38 +744,44 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
|
||||
|
||||
const size_t dyn_entsize = (ei_class == ELFCLASS32
|
||||
? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
|
||||
void *dyns = NULL;
|
||||
void *dyn_data = NULL;
|
||||
size_t dyn_data_size = 0;
|
||||
if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0
|
||||
&& ! read_portion (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz))
|
||||
{
|
||||
union
|
||||
typedef union
|
||||
{
|
||||
Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
|
||||
Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
|
||||
} dyn;
|
||||
} dynn;
|
||||
dyns = malloc (sizeof (dynn));
|
||||
if (unlikely (dyns == NULL))
|
||||
return finish ();
|
||||
dynn *dyn = (dynn *) dyns;
|
||||
|
||||
xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
|
||||
xlatefrom.d_buf = (void *) dyn_data;
|
||||
xlatefrom.d_size = dyn_filesz;
|
||||
xlateto.d_buf = &dyn;
|
||||
xlateto.d_size = sizeof dyn;
|
||||
xlateto.d_buf = dyn;
|
||||
xlateto.d_size = sizeof (dynn);
|
||||
|
||||
if (ei_class == ELFCLASS32)
|
||||
{
|
||||
if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
|
||||
for (size_t i = 0; i < dyn_filesz / sizeof dyn.d32[0]; ++i)
|
||||
if (consider_dyn (dyn.d32[i].d_tag, dyn.d32[i].d_un.d_val))
|
||||
for (size_t i = 0; i < dyn_filesz / sizeof (Elf32_Dyn); ++i)
|
||||
if (consider_dyn (dyn->d32[i].d_tag, dyn->d32[i].d_un.d_val))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
|
||||
for (size_t i = 0; i < dyn_filesz / sizeof dyn.d64[0]; ++i)
|
||||
if (consider_dyn (dyn.d64[i].d_tag, dyn.d64[i].d_un.d_val))
|
||||
for (size_t i = 0; i < dyn_filesz / sizeof (Elf64_Dyn); ++i)
|
||||
if (consider_dyn (dyn->d64[i].d_tag, dyn->d64[i].d_un.d_val))
|
||||
break;
|
||||
}
|
||||
}
|
||||
free (dyns);
|
||||
finish_portion (&dyn_data, &dyn_data_size);
|
||||
|
||||
/* We'll use the name passed in or a stupid default if not DT_SONAME. */
|
||||
@@ -881,12 +896,12 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
|
||||
|
||||
if (ei_class == ELFCLASS32)
|
||||
for (uint_fast16_t i = 0; i < phnum; ++i)
|
||||
read_phdr (phdrs.p32[i].p_type, phdrs.p32[i].p_vaddr,
|
||||
phdrs.p32[i].p_offset, phdrs.p32[i].p_filesz);
|
||||
read_phdr (phdrs->p32[i].p_type, phdrs->p32[i].p_vaddr,
|
||||
phdrs->p32[i].p_offset, phdrs->p32[i].p_filesz);
|
||||
else
|
||||
for (uint_fast16_t i = 0; i < phnum; ++i)
|
||||
read_phdr (phdrs.p64[i].p_type, phdrs.p64[i].p_vaddr,
|
||||
phdrs.p64[i].p_offset, phdrs.p64[i].p_filesz);
|
||||
read_phdr (phdrs->p64[i].p_type, phdrs->p64[i].p_vaddr,
|
||||
phdrs->p64[i].p_offset, phdrs->p64[i].p_filesz);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user