summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2015-06-18 10:57:53 +0200
committerMark Wielaard <[email protected]>2015-06-19 13:08:43 +0200
commit90a7bd23b1f4ffcace0721634f97ce34553c2288 (patch)
tree9c8c69c46bf8d7b8cd1e1c3d5ec02c0f64306977
parent3c57452a45b9ab3ce9fa7994c42eda677483cb46 (diff)
readelf: Don't leak memory on failure path in handle_gnu_hash.
Signed-off-by: Mark Wielaard <[email protected]>
-rw-r--r--src/ChangeLog4
-rw-r--r--src/readelf.c4
2 files changed, 7 insertions, 1 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 13e66e1c..d11b0e6b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,9 @@
2015-06-18 Mark Wielaard <[email protected]>
+ * readelf.c (handle_gnu_hash): Free lengths on invalid_data.
+
+2015-06-18 Mark Wielaard <[email protected]>
+
* elflint.c (check_symtab): Only check the PT_TLS phdr if it actually
exists. Warn otherwise.
diff --git a/src/readelf.c b/src/readelf.c
index b4cb3a82..9afe8dba 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3092,6 +3092,7 @@ handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
static void
handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
{
+ uint32_t *lengths = NULL;
Elf_Data *data = elf_getdata (scn, NULL);
if (unlikely (data == NULL))
{
@@ -3103,6 +3104,7 @@ handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
{
invalid_data:
+ free (lengths);
error (0, 0, gettext ("invalid data in gnu.hash section %d"),
(int) elf_ndxscn (scn));
return;
@@ -3131,7 +3133,7 @@ handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
if (used_buf > data->d_size)
goto invalid_data;
- uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
+ lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];