Browse code

fuzz-30038: Fix leak in PNG zlib initialization

Fix a memory leak caused by improperly tracking zlib stream
initalization.

Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30038

Micah Snyder authored on 2021/02/14 07:49:50
Showing 1 changed files
... ...
@@ -114,6 +114,7 @@ cl_error_t cli_parsepng(cli_ctx *ctx)
114 114
     int err                    = Z_OK;
115 115
     uint8_t *decompressed_data = NULL;
116 116
 
117
+    bool zstrm_initialized = false;
117 118
     z_stream zstrm;
118 119
     size_t decompressed_data_len = 0;
119 120
 
... ...
@@ -297,6 +298,7 @@ cl_error_t cli_parsepng(cli_ctx *ctx)
297 297
 
298 298
                     idat_state = PNG_IDAT_DECOMPRESSION_FAILED;
299 299
                 } else {
300
+                    zstrm_initialized = true;
300 301
                     uint64_t cur_width, cur_linebytes;
301 302
                     int64_t cur_xoff  = 0;
302 303
                     int64_t cur_xskip = interlace_method ? 8 : 1;
... ...
@@ -343,6 +345,7 @@ cl_error_t cli_parsepng(cli_ctx *ctx)
343 343
                     if (err != Z_OK && err != Z_STREAM_END) {
344 344
                         cli_dbgmsg("PNG: zlib: inflate error: %d, Image decompression failed!\n", err);
345 345
                         inflateEnd(&zstrm);
346
+                        zstrm_initialized = false;
346 347
                         idat_state = PNG_IDAT_DECOMPRESSION_FAILED;
347 348
                         break;
348 349
                     }
... ...
@@ -351,6 +354,7 @@ cl_error_t cli_parsepng(cli_ctx *ctx)
351 351
                 if (err == Z_STREAM_END) {
352 352
                     cli_dbgmsg("  TOTAL decompressed:    %zu\n", decompressed_data_len);
353 353
                     inflateEnd(&zstrm);
354
+                    zstrm_initialized = false;
354 355
                     idat_state = PNG_IDAT_DECOMPRESSION_COMPLETE;
355 356
 
356 357
                     if (decompressed_data_len > image_size) {
... ...
@@ -436,7 +440,7 @@ done:
436 436
     if (NULL != decompressed_data) {
437 437
         free(decompressed_data);
438 438
     }
439
-    if (idat_state == PNG_IDAT_DECOMPRESSION_IN_PROGRESS) {
439
+    if (zstrm_initialized) {
440 440
         inflateEnd(&zstrm);
441 441
     }
442 442