Allocate shdr_data and scns with malloc, not alloca. Free after writing section headers.
Signed-off-by: Mark Wielaard <[email protected]> --- libelf/ChangeLog | 5 +++++ libelf/elf32_updatefile.c | 24 +++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/libelf/ChangeLog b/libelf/ChangeLog index f1f8fac..5f66135 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2015-05-17 Mark Wielaard <[email protected]> + + * elf32_updatefile.c (updatefile): Allocate shdr_data and scns + with malloc, not alloca. Free after writing section headers. + 2015-05-16 Mark Wielaard <[email protected]> * elf32_updatefile.c (updatemmap): Allocate temporary shdr storage diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index d45abcd..eeb946c 100644 --- a/libelf/elf32_updatefile.c +++ b/libelf/elf32_updatefile.c @@ -657,15 +657,27 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) ElfW2(LIBELFBITS,Shdr) *shdr_data; if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL || (elf->flags & ELF_F_DIRTY)) - shdr_data = (ElfW2(LIBELFBITS,Shdr) *) - alloca (shnum * sizeof (ElfW2(LIBELFBITS,Shdr))); + { + shdr_data = (ElfW2(LIBELFBITS,Shdr) *) + malloc (shnum * sizeof (ElfW2(LIBELFBITS,Shdr))); + if (shdr_data == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } + } else shdr_data = elf->state.ELFW(elf,LIBELFBITS).shdr; int shdr_flags = elf->flags; /* Get all sections into the array and sort them. */ Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns; - Elf_Scn **scns = (Elf_Scn **) alloca (shnum * sizeof (Elf_Scn *)); + Elf_Scn **scns = (Elf_Scn **) malloc (shnum * sizeof (Elf_Scn *)); + if (scns == NULL) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } sort_sections (scns, list); for (size_t cnt = 0; cnt < shnum; ++cnt) @@ -814,6 +826,12 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) __libelf_seterrno (ELF_E_WRITE_ERROR); return 1; } + + if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL + || (elf->flags & ELF_F_DIRTY)) + free (shdr_data); + + free (scns); } /* That was the last part. Clear the overall flag. */ -- 1.8.3.1
