Signed-off-by: Mark Wielaard <[email protected]>
---
 libdwfl/ChangeLog  |  5 +++++
 libdwfl/link_map.c | 32 +++++++++++++++++++++++---------
 2 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 772de3e..90fc0f3 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,10 @@
 2015-05-22  Mark Wielaard  <[email protected]>
 
+       * link_map.c (dwfl_link_map_report): Allocate phdrs and dyn with
+       malloc instead of stack allocating. Call free when done with data.
+
+2015-05-22  Mark Wielaard  <[email protected]>
+
        * 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.
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c
index eaf43b5..8236901 100644
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -1,5 +1,5 @@
 /* Report modules by examining dynamic linker data structures.
-   Copyright (C) 2008-2014 Red Hat, Inc.
+   Copyright (C) 2008-2015 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -856,18 +856,24 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, 
size_t auxv_size,
            }
          if (in_ok)
            {
-             union
+             typedef union
              {
                Elf32_Phdr p32;
                Elf64_Phdr p64;
                char data[phnum * phent];
-             } buf;
+             } data_buf;
+             data_buf *buf = malloc (sizeof (data_buf));
+             if (buf == NULL)
+               {
+                 __libdwfl_seterrno (DWFL_E_NOMEM);
+                 return false;
+               }
              Elf_Data out =
                {
                  .d_type = ELF_T_PHDR,
                  .d_version = EV_CURRENT,
                  .d_size = phnum * phent,
-                 .d_buf = &buf
+                 .d_buf = buf
                };
              in.d_size = out.d_size;
              if (likely ((elfclass == ELFCLASS32
@@ -879,7 +885,7 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t 
auxv_size,
                  {
                    Elf32_Phdr p32[phnum];
                    Elf64_Phdr p64[phnum];
-                 } *u = (void *) &buf;
+                 } *u = (void *) buf;
                  if (elfclass == ELFCLASS32)
                    {
                      for (size_t i = 0; i < phnum; ++i)
@@ -900,6 +906,7 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t 
auxv_size,
 
              (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
                                  memory_callback_arg);
+             free (buf);
            }
          else
            /* We could not read the executable's phdrs from the
@@ -943,18 +950,24 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, 
size_t auxv_size,
          if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size,
                                  dyn_vaddr, dyn_filesz, memory_callback_arg))
            {
-             union
+             typedef union
              {
                Elf32_Dyn d32;
                Elf64_Dyn d64;
                char data[dyn_filesz];
-             } buf;
+             } data_buf;
+             data_buf *buf = malloc (sizeof (data_buf));
+             if (buf == NULL)
+               {
+                 __libdwfl_seterrno (DWFL_E_NOMEM);
+                 return false;
+               }
              Elf_Data out =
                {
                  .d_type = ELF_T_DYN,
                  .d_version = EV_CURRENT,
                  .d_size = dyn_filesz,
-                 .d_buf = &buf
+                 .d_buf = buf
                };
              in.d_size = out.d_size;
              if (likely ((elfclass == ELFCLASS32
@@ -966,7 +979,7 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t 
auxv_size,
                  {
                    Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
                    Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
-                 } *u = (void *) &buf;
+                 } *u = (void *) buf;
                  if (elfclass == ELFCLASS32)
                    {
                      size_t n = dyn_filesz / sizeof (Elf32_Dyn);
@@ -991,6 +1004,7 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t 
auxv_size,
 
              (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
                                  memory_callback_arg);
+             free (buf);
            }
        }
     }
-- 
1.8.3.1

Reply via email to