diff options
author | Matthias Maennich <maennich@google.com> | 2020-03-20 17:38:55 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2020-03-20 18:08:10 +0100 |
commit | 2092865a7e589ff805caa47e69ac9630f34d4f2a (patch) | |
tree | 0ecdb7c4d6e22c6faa5cb64284264752a3b9c7a2 /libelf | |
parent | a5cf9ba6bbdd1d565cfed671eea401ce8e6260b7 (diff) | |
download | elfutils-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/ChangeLog | 6 | ||||
-rw-r--r-- | libelf/elf_compress.c | 11 |
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; } |