summaryrefslogtreecommitdiff
path: root/libelf
diff options
context:
space:
mode:
authorMatthias Maennich <maennich@google.com>2020-03-20 17:38:55 +0100
committerMark Wielaard <mark@klomp.org>2020-03-20 18:08:10 +0100
commit2092865a7e589ff805caa47e69ac9630f34d4f2a (patch)
tree0ecdb7c4d6e22c6faa5cb64284264752a3b9c7a2 /libelf
parenta5cf9ba6bbdd1d565cfed671eea401ce8e6260b7 (diff)
downloadelfutils-2092865a7e589ff805caa47e69ac9630f34d4f2a.tar.gz
libelf: {de,}compress: ensure zlib resource cleanup
__libelf_decompress would only cleanup zlib resources via inflateEnd() in case inflating was successful, but would leak memory if not. Fix this by calling inflateEnd() unconditionally. __libelf_decompress did this all the time already, but called deflateEnd() twice. That is not a (known) issue, but can be cleaned up by ensuring all error paths use 'return deflate_cleanup' and the success path calls deflateEnd() only once. Note, the deflate() needs to return Z_STREAM_END to indicate we are done. Hence change the condition. Fixes: 272018bba1f2 ("libelf: Add elf_compress and elf_compress_gnu.") Signed-off-by: Matthias Maennich <maennich@google.com>
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog6
-rw-r--r--libelf/elf_compress.c11
2 files changed, 11 insertions, 6 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index dde6c81d..482ef32a 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,9 @@
+2019-03-20 Matthias Maennich <maennich@google.com>
+
+ * elf_compress.c (__libelf_compress): Always call deflate_cleanup
+ in failure path. Call deflateEnd only once.
+ (__libelf_decompress): Call inflateEnd only once.
+
2019-06-18 Mark Wielaard <mark@klomp.org>
* common.h (allocate_elf): Use int64_t instead of off_t for offset.
diff --git a/libelf/elf_compress.c b/libelf/elf_compress.c
index 244467b5..b1b89689 100644
--- a/libelf/elf_compress.c
+++ b/libelf/elf_compress.c
@@ -115,7 +115,7 @@ __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
{
free (out_buf);
__libelf_seterrno (ELF_E_COMPRESS_ERROR);
- return NULL;
+ return deflate_cleanup(NULL, NULL);
}
Elf_Data cdata;
@@ -197,13 +197,13 @@ __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
}
while (flush != Z_FINISH); /* More data blocks. */
- zrc = deflateEnd (&z);
- if (zrc != Z_OK)
+ if (zrc != Z_STREAM_END)
{
__libelf_seterrno (ELF_E_COMPRESS_ERROR);
return deflate_cleanup (NULL, NULL);
}
+ deflateEnd (&z);
*new_size = used;
return out_buf;
}
@@ -251,16 +251,15 @@ __libelf_decompress (void *buf_in, size_t size_in, size_t size_out)
}
zrc = inflateReset (&z);
}
- if (likely (zrc == Z_OK))
- zrc = inflateEnd (&z);
if (unlikely (zrc != Z_OK) || unlikely (z.avail_out != 0))
{
free (buf_out);
+ buf_out = NULL;
__libelf_seterrno (ELF_E_DECOMPRESS_ERROR);
- return NULL;
}
+ inflateEnd(&z);
return buf_out;
}