summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2015-05-17 10:30:57 +0200
committerMark Wielaard <mjw@redhat.com>2015-05-27 23:04:31 +0200
commite6261005eaa1cf19107fb8963f8cb55e2c1367a7 (patch)
tree0f9b1fee5915cfc76b78dc9ae755a30b8137bb78 /libelf
parent2e5df0c35099fc6bb9a114fabd01006b5dc767cc (diff)
downloadandroid_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/ChangeLog5
-rw-r--r--libelf/elf32_updatefile.c24
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. */