diff options
author | Mark Wielaard <mjw@redhat.com> | 2015-05-16 22:41:36 +0200 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2015-05-27 23:04:31 +0200 |
commit | 2e5df0c35099fc6bb9a114fabd01006b5dc767cc (patch) | |
tree | 684c4adfbd68541ba17e607a1c1ae7a325c4723f /libelf | |
parent | bfb9a752c323b97bfcfb11f4f9dbf4ca25fe3c95 (diff) | |
download | android_external_elfutils-2e5df0c35099fc6bb9a114fabd01006b5dc767cc.tar.gz android_external_elfutils-2e5df0c35099fc6bb9a114fabd01006b5dc767cc.tar.bz2 android_external_elfutils-2e5df0c35099fc6bb9a114fabd01006b5dc767cc.zip |
libelf: Fix possible unbounded stack usage in updatemmap.
Allocate temporary shdr storage 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 | 31 |
2 files changed, 28 insertions, 8 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 17ab7406..f1f8faca 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,5 +1,10 @@ 2015-05-16 Mark Wielaard <mjw@redhat.com> + * elf32_updatefile.c (updatemmap): Allocate temporary shdr storage + with malloc, not alloca. Free after writing section header. + +2015-05-16 Mark Wielaard <mjw@redhat.com> + * elf_getarsym.c (elf_getarsym): Allocate temporary file_date with malloc, not alloca. Call free after out. diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c index 153e377f..f625b308 100644 --- a/libelf/elf32_updatefile.c +++ b/libelf/elf32_updatefile.c @@ -1,5 +1,5 @@ /* Write changed data structures. - Copyright (C) 2000-2010, 2014 Red Hat, Inc. + Copyright (C) 2000-2010, 2014, 2015 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2000. @@ -206,7 +206,12 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) return 1; 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; + } char *const shdr_start = ((char *) elf->map_address + elf->start_offset + ehdr->e_shoff); char *const shdr_end = shdr_start + ehdr->e_shnum * ehdr->e_shentsize; @@ -238,7 +243,12 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) < ((char *) elf->map_address + elf->start_offset + elf->maximum_size)); - void *p = alloca (sizeof (ElfW2(LIBELFBITS,Shdr))); + void *p = malloc (sizeof (ElfW2(LIBELFBITS,Shdr))); + if (unlikely (p == NULL)) + { + __libelf_seterrno (ELF_E_NOMEM); + return -1; + } scn->shdr.ELFW(e,LIBELFBITS) = memcpy (p, scn->shdr.ELFW(e,LIBELFBITS), sizeof (ElfW2(LIBELFBITS,Shdr))); @@ -260,7 +270,7 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) > (char *) scn->data_list.data.d.d_buf)) { void *p = malloc (scn->data_list.data.d.d_size); - if (p == NULL) + if (unlikely (p == NULL)) { __libelf_seterrno (ELF_E_NOMEM); return -1; @@ -421,12 +431,17 @@ __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum) entry we now have to adjust the pointer again so point to new place in the mapping. */ if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced - && (scn->shdr_flags & ELF_F_MALLOCED) == 0) - scn->shdr.ELFW(e,LIBELFBITS) = &shdr_dest[scn->index]; + && (scn->shdr_flags & ELF_F_MALLOCED) == 0 + && scn->shdr.ELFW(e,LIBELFBITS) != &shdr_dest[scn->index]) + { + free (scn->shdr.ELFW(e,LIBELFBITS)); + scn->shdr.ELFW(e,LIBELFBITS) = &shdr_dest[scn->index]; + } scn->shdr_flags &= ~ELF_F_DIRTY; } } + free (scns); } /* That was the last part. Clear the overall flag. */ @@ -582,7 +597,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) /* Allocate sufficient memory. */ tmp_phdr = (ElfW2(LIBELFBITS,Phdr) *) malloc (sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum); - if (tmp_phdr == NULL) + if (unlikely (tmp_phdr == NULL)) { __libelf_seterrno (ELF_E_NOMEM); return 1; @@ -714,7 +729,7 @@ __elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum) if (dl->data.d.d_size > MAX_TMPBUF) { buf = malloc (dl->data.d.d_size); - if (buf == NULL) + if (unlikely (buf == NULL)) { __libelf_seterrno (ELF_E_NOMEM); return 1; |