From: Michihiro NAKAJIMA Date: Tue, 18 Sep 2012 11:14:18 +0000 (+0900) Subject: Fix a possibility of memory leaks when realloc fails. X-Git-Tag: v3.1.0~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0ddb050474551e3a4888fa865879a6ed2c39893b;p=thirdparty%2Flibarchive.git Fix a possibility of memory leaks when realloc fails. Do not assign the return value of realloc into the variable that has the original pointer because if realloc failed we will lose the chance to release the address. --- diff --git a/libarchive/archive_match.c b/libarchive/archive_match.c index 6b533e6ba..6170dc539 100644 --- a/libarchive/archive_match.c +++ b/libarchive/archive_match.c @@ -1675,13 +1675,16 @@ add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id) unsigned i; if (ids->count + 1 >= ids->size) { + void *p; + if (ids->size == 0) ids->size = 8; else ids->size *= 2; - ids->ids = realloc(ids->ids, sizeof(*ids->ids) * ids->size); - if (ids->ids == NULL) + p = realloc(ids->ids, sizeof(*ids->ids) * ids->size); + if (p == NULL) return (error_nomem(a)); + ids->ids = (int64_t *)p; } /* Find an insert point. */ diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c index 502d7f45f..faadbea41 100644 --- a/libarchive/archive_read.c +++ b/libarchive/archive_read.c @@ -407,7 +407,9 @@ archive_read_add_callback_data(struct archive *_a, void *client_data, unsigned int iindex) { struct archive_read *a = (struct archive_read *)_a; + void *p; unsigned int i; + archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, "archive_read_add_callback_data"); if (iindex > a->client.nodes) @@ -416,14 +418,14 @@ archive_read_add_callback_data(struct archive *_a, void *client_data, "Invalid index specified."); return ARCHIVE_FATAL; } - if ((a->client.dataset = - (struct archive_read_data_node *)realloc(a->client.dataset, - sizeof(*a->client.dataset) * (++(a->client.nodes)))) == NULL) - { + p = realloc(a->client.dataset, sizeof(*a->client.dataset) + * (++(a->client.nodes))); + if (p == NULL) { archive_set_error(&a->archive, ENOMEM, "No memory."); return ARCHIVE_FATAL; } + a->client.dataset = (struct archive_read_data_node *)p; for (i = a->client.nodes - 1; i > iindex && i > 0; i--) a->client.dataset[i].data = a->client.dataset[i-1].data; a->client.dataset[iindex].data = client_data; diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c index 1b8cf87f9..9b019b154 100644 --- a/libarchive/archive_read_disk_posix.c +++ b/libarchive/archive_read_disk_posix.c @@ -1359,15 +1359,17 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev) fid = t->max_filesystem_id++; if (t->max_filesystem_id > t->allocated_filesytem) { size_t s; + void *p; s = t->max_filesystem_id * 2; - t->filesystem_table = realloc(t->filesystem_table, - s * sizeof(*t->filesystem_table)); - if (t->filesystem_table == NULL) { + p = realloc(t->filesystem_table, + s * sizeof(*t->filesystem_table)); + if (p == NULL) { archive_set_error(&a->archive, ENOMEM, "Can't allocate tar data"); return (ARCHIVE_FATAL); } + t->filesystem_table = (struct filesystem *)p; t->allocated_filesytem = s; } t->current_filesystem_id = fid; diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c index c14ab9f27..7bc141f41 100644 --- a/libarchive/archive_read_disk_windows.c +++ b/libarchive/archive_read_disk_windows.c @@ -1257,15 +1257,17 @@ update_current_filesystem(struct archive_read_disk *a, int64_t dev) fid = t->max_filesystem_id++; if (t->max_filesystem_id > t->allocated_filesytem) { size_t s; + void *p; s = t->max_filesystem_id * 2; - t->filesystem_table = realloc(t->filesystem_table, - s * sizeof(*t->filesystem_table)); - if (t->filesystem_table == NULL) { + p = realloc(t->filesystem_table, + s * sizeof(*t->filesystem_table)); + if (p == NULL) { archive_set_error(&a->archive, ENOMEM, "Can't allocate tar data"); return (ARCHIVE_FATAL); } + t->filesystem_table = (struct filesystem *)p; t->allocated_filesytem = s; } t->current_filesystem_id = fid; diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c index ee3751f25..e9576b472 100644 --- a/libarchive/archive_read_support_format_7zip.c +++ b/libarchive/archive_read_support_format_7zip.c @@ -2966,16 +2966,19 @@ extract_pack_stream(struct archive_read *a, size_t minimum) * Expand the uncompressed buffer up to * the minimum size. */ - zip->uncompressed_buffer_size = minimum + 1023; - zip->uncompressed_buffer_size &= ~0x3ff; - zip->uncompressed_buffer = - realloc(zip->uncompressed_buffer, - zip->uncompressed_buffer_size); - if (zip->uncompressed_buffer == NULL) { + void *p; + size_t new_size; + + new_size = minimum + 1023; + new_size &= ~0x3ff; + p = realloc(zip->uncompressed_buffer, new_size); + if (p == NULL) { archive_set_error(&a->archive, ENOMEM, "No memory for 7-Zip decompression"); return (ARCHIVE_FATAL); } + zip->uncompressed_buffer = (unsigned char *)p; + zip->uncompressed_buffer_size = new_size; } /* * Move unconsumed bytes to the head. diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c index 87a729eec..63eea0806 100644 --- a/libarchive/archive_read_support_format_rar.c +++ b/libarchive/archive_read_support_format_rar.c @@ -1998,17 +1998,21 @@ parse_codes(struct archive_read *a) /* Seems as though dictionary sizes are not used. Even so, minimize * memory usage as much as possible. */ + void *new_window; + unsigned int new_size; + if (rar->unp_size >= DICTIONARY_MAX_SIZE) - rar->dictionary_size = DICTIONARY_MAX_SIZE; + new_size = DICTIONARY_MAX_SIZE; else - rar->dictionary_size = rar_fls((unsigned int)rar->unp_size) << 1; - rar->lzss.window = (unsigned char *)realloc(rar->lzss.window, - rar->dictionary_size); - if (rar->lzss.window == NULL) { + new_size = rar_fls((unsigned int)rar->unp_size) << 1; + new_window = realloc(rar->lzss.window, new_size); + if (new_window == NULL) { archive_set_error(&a->archive, ENOMEM, "Unable to allocate memory for uncompressed data."); return (ARCHIVE_FATAL); } + rar->lzss.window = (unsigned char *)new_window; + rar->dictionary_size = new_size; memset(rar->lzss.window, 0, rar->dictionary_size); rar->lzss.mask = rar->dictionary_size - 1; } @@ -2246,10 +2250,12 @@ add_value(struct archive_read *a, struct huffman_code *code, int value, static int new_node(struct huffman_code *code) { - code->tree = (struct huffman_tree_node *)realloc(code->tree, - (code->numentries + 1) * sizeof(*code->tree)); - if (code->tree == NULL) + void *new_tree; + + new_tree = realloc(code->tree, (code->numentries + 1) * sizeof(*code->tree)); + if (new_tree == NULL) return (-1); + code->tree = (struct huffman_tree_node *)new_tree; code->tree[code->numentries].branches[0] = -1; code->tree[code->numentries].branches[1] = -2; return 1; diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c index 483de9086..c6a4c2d5b 100644 --- a/libarchive/archive_write_set_format_iso9660.c +++ b/libarchive/archive_write_set_format_iso9660.c @@ -5818,17 +5818,18 @@ idr_ensure_poolsize(struct archive_write *a, struct idr *idr, { if (idr->pool_size < cnt) { + void *p; const int bk = (1 << 7) - 1; int psize; psize = (cnt + bk) & ~bk; - idr->idrent_pool = realloc(idr->idrent_pool, - sizeof(struct idrent) * psize); - if (idr->idrent_pool == NULL) { + p = realloc(idr->idrent_pool, sizeof(struct idrent) * psize); + if (p == NULL) { archive_set_error(&a->archive, ENOMEM, "Can't allocate memory"); return (ARCHIVE_FATAL); } + idr->idrent_pool = (struct idrent *)p; idr->pool_size = psize; } return (ARCHIVE_OK);