From: Mark Wielaard Date: Sun, 17 May 2015 08:30:57 +0000 (+0200) Subject: libelf: Fix possible unbounded stack usage in updatefile. X-Git-Tag: elfutils-0.162~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e6261005eaa1cf19107fb8963f8cb55e2c1367a7;p=thirdparty%2Felfutils.git libelf: Fix possible unbounded stack usage in updatefile. Allocate shdr_data and scns with malloc, not alloca. Free after writing section headers. Signed-off-by: Mark Wielaard --- diff --git a/libelf/ChangeLog b/libelf/ChangeLog index f1f8faca7..5f66135f1 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2015-05-17 Mark Wielaard + + * elf32_updatefile.c (updatefile): Allocate shdr_data and scns + with malloc, not alloca. Free after writing section headers. + 2015-05-16 Mark Wielaard * elf32_updatefile.c (updatemmap): Allocate temporary shdr storage diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index f625b3084..e90ad47d4 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 (unlikely (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 (unlikely (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. */