unarchive: fix possible segmentation fault in deb_extract()
authorJo-Philipp Wich <jo@mein.io>
Tue, 28 Feb 2017 23:46:39 +0000 (00:46 +0100)
committerJo-Philipp Wich <jo@mein.io>
Tue, 28 Feb 2017 23:52:41 +0000 (00:52 +0100)
When a not existing or unreachable file path is passed to deb_extract(),
the wfopen() call fails, causing a jump to the cleanup: label which leads
to a call to gzip_close() on the tar_outer structure.

The tar_outer structure however contains uninitialized memory at this point,
causing gzip_close() to operate on garbage data. Depending on the nature of
the unitialized memory, this might lead to all sorts of issues, e.g. freeing
of not allocated memory or invoking fclose() on garbage pointers.

Solve this problem by initializing the tar_outer and tar_inner structures
right at the declaration.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
libbb/unarchive.c

index 08f50bf..6edb5b6 100644 (file)
@@ -529,7 +529,7 @@ char *deb_extract(const char *package_filename, FILE * out_stream,
        char *ared_file = NULL;
        char ar_magic[8];
        int gz_err;
-       struct gzip_handle tar_outer, tar_inner;
+       struct gzip_handle tar_outer = { }, tar_inner = { };
        file_header_t *tar_header;
        ssize_t len;
 
@@ -561,7 +561,6 @@ char *deb_extract(const char *package_filename, FILE * out_stream,
        /* set the buffer size */
        setvbuf(deb_stream, NULL, _IOFBF, 0x8000);
 
-       memset(&tar_outer, 0, sizeof(tar_outer));
        tar_outer.file = deb_stream;
        gzip_exec(&tar_outer, NULL);
 
@@ -572,7 +571,6 @@ char *deb_extract(const char *package_filename, FILE * out_stream,
                        name_offset = 2;
 
                if (strcmp(ared_file, tar_header->name + name_offset) == 0) {
-                       memset(&tar_inner, 0, sizeof(tar_inner));
                        tar_inner.gzip = &tar_outer;
                        gzip_exec(&tar_inner, NULL);