summaryrefslogtreecommitdiffstats
path: root/libelf/elf_compress.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2016-08-07 22:13:46 +0200
committerMark Wielaard <[email protected]>2016-08-15 09:58:12 +0200
commite93f2d801fccbe5a4ffd71f07baed66453b8a56c (patch)
treefaf2178368ee667d7d94846f0ad58a5ffd8749f6 /libelf/elf_compress.c
parent6ff6c215bfa4153874751cdc0bae26acfbba4a81 (diff)
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 <[email protected]>
Diffstat (limited to 'libelf/elf_compress.c')
-rw-r--r--libelf/elf_compress.c7
1 files changed, 5 insertions, 2 deletions
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