summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2016-08-07 22:13:46 +0200
committerMark Wielaard <mjw@redhat.com>2016-08-15 09:58:12 +0200
commite93f2d801fccbe5a4ffd71f07baed66453b8a56c (patch)
treefaf2178368ee667d7d94846f0ad58a5ffd8749f6
parent6ff6c215bfa4153874751cdc0bae26acfbba4a81 (diff)
downloadelfutils-e93f2d801fccbe5a4ffd71f07baed66453b8a56c.tar.gz
libelf: Fix memory leak in elf_compress for mmapped ELF files.
The testcase added to run-strip-reloc.sh for strip-compressed.o showed a memory leak when ran under valgrind (configure --enable-valgrind). For a mmapped ELF file when existing section data was compressed elf_end would fail to release the new compressed data buffer assigned to rawdata_base. For non-mapped files rawdata_base is always freed. For decompressed data rawdata_base is released together with zdata_base. Use the Elf_Scn flag ELF_T_MALLOCED to track whether rawdata_base points to malloced memory and free it in elf_end even for mmapped ELF files. Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r--libelf/ChangeLog8
-rw-r--r--libelf/elf_compress.c7
-rw-r--r--libelf/elf_end.c5
-rw-r--r--libelf/libelfP.h10
4 files changed, 24 insertions, 6 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 3df89703..77991446 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,11 @@
+2016-08-07 Mark Wielaard <mjw@redhat.com>
+
+ * elf_compress.c (__libelf_reset_rawdata): Check scn->flags and
+ free rawdata_base when malloced. Set ELF_F_MALLOCED for scn->flags.
+ * elf_end.c (elf_end): Check scn->flags and free rawdata_base if
+ malloced.
+ * libelfP.h (struct Elf_Scn): Document flags ELF_F_MALLOCED usage.
+
2016-07-06 Mark Wielaard <mjw@redhat.com>
* elf-knowledge.h (SH_FLAGS_COMBINE): Removed.
diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
index 10574eae..3aebe820 100644
--- a/libelf/elf_compress.c
+++ b/libelf/elf_compress.c
@@ -1,5 +1,5 @@
/* Compress or decompress a section.
- Copyright (C) 2015 Red Hat, Inc.
+ Copyright (C) 2015, 2016 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -295,6 +295,7 @@ __libelf_decompress_elf (Elf_Scn *scn, size_t *size_out, size_t *addralign)
return buf_out;
}
+/* Assumes buf is a malloced buffer. */
void
internal_function
__libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align,
@@ -314,10 +315,12 @@ __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align,
free (scn->data_base);
scn->data_base = NULL;
if (scn->elf->map_address == NULL
- || scn->rawdata_base == scn->zdata_base)
+ || scn->rawdata_base == scn->zdata_base
+ || (scn->flags & ELF_F_MALLOCED) != 0)
free (scn->rawdata_base);
scn->rawdata_base = buf;
+ scn->flags |= ELF_F_MALLOCED;
}
int
diff --git a/libelf/elf_end.c b/libelf/elf_end.c
index fde17b50..160f0b88 100644
--- a/libelf/elf_end.c
+++ b/libelf/elf_end.c
@@ -1,5 +1,5 @@
/* Free resources associated with Elf descriptor.
- Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007,2015 Red Hat, Inc.
+ Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007,2015,2016 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -166,7 +166,8 @@ elf_end (Elf *elf)
/* The section data is allocated if we couldn't mmap
the file. Or if we had to decompress. */
if (elf->map_address == NULL
- || scn->rawdata_base == scn->zdata_base)
+ || scn->rawdata_base == scn->zdata_base
+ || (scn->flags & ELF_F_MALLOCED) != 0)
free (scn->rawdata_base);
/* Free the list of data buffers for the section.
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 57ccbce4..44599827 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -1,5 +1,5 @@
/* Internal interfaces for libelf.
- Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+ Copyright (C) 1998-2010, 2015, 2016 Red Hat, Inc.
This file is part of elfutils.
Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -233,7 +233,13 @@ struct Elf_Scn
} shdr;
unsigned int shdr_flags; /* Section header modified? */
- unsigned int flags; /* Section changed in size? */
+ unsigned int flags; /* Section changed in size?
+ ELF_F_MALLOCED for a Elf_Data_Chunk
+ dummy_scn means the rawchunks
+ data.d.d_buf was malloced. For normal
+ sections it means rawdata_base was
+ malloced (by elf_compress) even if
+ the Elf was mmapped. */
char *rawdata_base; /* The unmodified data of the section. */
char *data_base; /* The converted data of the section. */