diff options
author | Mark Wielaard <mjw@redhat.com> | 2015-05-17 10:30:57 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2015-05-27 23:04:31 +0200 |
commit | e6261005eaa1cf19107fb8963f8cb55e2c1367a7 (patch) | |
tree | 0f9b1fee5915cfc76b78dc9ae755a30b8137bb78 /libelf | |
parent | 2e5df0c35099fc6bb9a114fabd01006b5dc767cc (diff) | |
download | android_external_elfutils-e6261005eaa1cf19107fb8963f8cb55e2c1367a7.tar.gz android_external_elfutils-e6261005eaa1cf19107fb8963f8cb55e2c1367a7.tar.bz2 android_external_elfutils-e6261005eaa1cf19107fb8963f8cb55e2c1367a7.zip |
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 <mjw@redhat.com>
Diffstat (limited to 'libelf')
-rw-r--r-- | libelf/ChangeLog | 5 | ||||
-rw-r--r-- | libelf/elf32_updatefile.c | 24 |
2 files changed, 26 insertions, 3 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog index f1f8faca..5f66135f 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2015-05-17 Mark Wielaard <mjw@redhat.com> + + * elf32_updatefile.c (updatefile): Allocate shdr_data and scns + with malloc, not alloca. Free after writing section headers. + 2015-05-16 Mark Wielaard <mjw@redhat.com> * elf32_updatefile.c (updatemmap): Allocate temporary shdr storage diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index f625b308..e90ad47d 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. */ |