From dcb8de96ab47d1932ce313adbac5a673210b1c91 Mon Sep 17 00:00:00 2001 From: kientzle Date: Wed, 21 Sep 2005 04:25:06 +0000 Subject: Add a lot of error checks, based on the patches provided by Dan Lukes. Also fixes a memory leak reported by Andrew Turner. PR: bin/83476 Thanks to: Dan Lukes, Andrew Turner --- lib/libarchive/Makefile | 2 +- lib/libarchive/archive_entry.c | 23 ++++++++++++++++++++-- lib/libarchive/archive_read.c | 9 +++++++++ lib/libarchive/archive_read_open_fd.c | 6 ++++++ lib/libarchive/archive_read_open_file.c | 4 ++++ lib/libarchive/archive_read_open_filename.c | 4 ++++ lib/libarchive/archive_read_support_format_cpio.c | 8 ++++++++ .../archive_read_support_format_iso9660.c | 13 +++++++++++- lib/libarchive/archive_read_support_format_tar.c | 16 ++++++++++++++- lib/libarchive/archive_read_support_format_zip.c | 4 ++++ lib/libarchive/archive_util.c | 2 +- lib/libarchive/archive_write_set_format_cpio.c | 2 +- lib/libarchive/archive_write_set_format_pax.c | 3 +++ lib/libarchive/archive_write_set_format_ustar.c | 2 +- 14 files changed, 90 insertions(+), 8 deletions(-) (limited to 'lib/libarchive') diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile index 6aeff8f..82d99968 100644 --- a/lib/libarchive/Makefile +++ b/lib/libarchive/Makefile @@ -7,7 +7,7 @@ LIB= archive -VERSION= 1.02.032 +VERSION= 1.02.033 ARCHIVE_API_FEATURE= 2 ARCHIVE_API_VERSION= 2 SHLIB_MAJOR= ${ARCHIVE_API_VERSION} diff --git a/lib/libarchive/archive_entry.c b/lib/libarchive/archive_entry.c index 742a232..1a0febd 100644 --- a/lib/libarchive/archive_entry.c +++ b/lib/libarchive/archive_entry.c @@ -63,6 +63,7 @@ static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2) #include "archive.h" #include "archive_entry.h" +#include "archive_private.h" #undef max #define max(a, b) ((a)>(b)?(a):(b)) @@ -185,12 +186,16 @@ aes_copy(struct aes *dest, struct aes *src) if (src->aes_mbs != NULL) { dest->aes_mbs_alloc = strdup(src->aes_mbs); dest->aes_mbs = dest->aes_mbs_alloc; + if (dest->aes_mbs == NULL) + __archive_errx(1, "No memory for aes_copy()"); } if (src->aes_wcs != NULL) { dest->aes_wcs_alloc = malloc((wcslen(src->aes_wcs) + 1) * sizeof(wchar_t)); dest->aes_wcs = dest->aes_wcs_alloc; + if (dest->aes_wcs == NULL) + __archive_errx(1, "No memory for aes_copy()"); wcscpy(dest->aes_wcs_alloc, src->aes_wcs); } } @@ -208,6 +213,8 @@ aes_get_mbs(struct aes *aes) int mbs_length = wcslen(aes->aes_wcs) * 3 + 64; aes->aes_mbs_alloc = malloc(mbs_length); aes->aes_mbs = aes->aes_mbs_alloc; + if (aes->aes_mbs == NULL) + __archive_errx(1, "No memory for aes_get_mbs()"); wcstombs(aes->aes_mbs_alloc, aes->aes_wcs, mbs_length - 1); aes->aes_mbs_alloc[mbs_length - 1] = 0; } @@ -226,6 +233,8 @@ aes_get_wcs(struct aes *aes) aes->aes_wcs_alloc = malloc((wcs_length + 1) * sizeof(wchar_t)); aes->aes_wcs = aes->aes_wcs_alloc; + if (aes->aes_wcs == NULL) + __archive_errx(1, "No memory for aes_get_wcs()"); mbstowcs(aes->aes_wcs_alloc, aes->aes_mbs, wcs_length); aes->aes_wcs_alloc[wcs_length] = 0; } @@ -259,6 +268,8 @@ aes_copy_mbs(struct aes *aes, const char *mbs) aes->aes_wcs_alloc = NULL; } aes->aes_mbs_alloc = malloc((strlen(mbs) + 1) * sizeof(char)); + if (aes->aes_mbs_alloc == NULL) + __archive_errx(1, "No memory for aes_copy_mbs()"); strcpy(aes->aes_mbs_alloc, mbs); aes->aes_mbs = aes->aes_mbs_alloc; aes->aes_wcs = NULL; @@ -294,6 +305,8 @@ aes_copy_wcs(struct aes *aes, const wchar_t *wcs) } aes->aes_mbs = NULL; aes->aes_wcs_alloc = malloc((wcslen(wcs) + 1) * sizeof(wchar_t)); + if (aes->aes_wcs_alloc == NULL) + __archive_errx(1, "No memory for aes_copy_wcs()"); wcscpy(aes->aes_wcs_alloc, wcs); aes->aes_wcs = aes->aes_wcs_alloc; } @@ -319,7 +332,7 @@ archive_entry_clone(struct archive_entry *entry) /* Allocate new structure and copy over all of the fields. */ entry2 = malloc(sizeof(*entry2)); - if(entry2 == NULL) + if (entry2 == NULL) return (NULL); memset(entry2, 0, sizeof(*entry2)); entry2->ae_stat = entry->ae_stat; @@ -350,7 +363,7 @@ archive_entry_new(void) struct archive_entry *entry; entry = malloc(sizeof(*entry)); - if(entry == NULL) + if (entry == NULL) return (NULL); memset(entry, 0, sizeof(*entry)); return (entry); @@ -841,6 +854,8 @@ acl_new_entry(struct archive_entry *entry, /* Add a new entry to the list. */ ap = malloc(sizeof(*ap)); + if (ap == NULL) + return (NULL); memset(ap, 0, sizeof(*ap)); ap->next = entry->acl_head; entry->acl_head = ap; @@ -1021,6 +1036,8 @@ archive_entry_acl_text_w(struct archive_entry *entry, int flags) /* Now, allocate the string and actually populate it. */ wp = entry->acl_text_w = malloc(length * sizeof(wchar_t)); + if (wp == NULL) + __archive_errx(1, "No memory to generate the text version of the ACL"); count = 0; if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL, @@ -1274,6 +1291,8 @@ __archive_entry_acl_parse_w(struct archive_entry *entry, namebuff_length = name_end - name_start + 256; namebuff = malloc(namebuff_length * sizeof(wchar_t)); + if (namebuff == NULL) + goto fail; } wmemcpy(namebuff, name_start, name_end - name_start); namebuff[name_end - name_start] = L'\0'; diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c index 7e81fb2..1d8f86d 100644 --- a/lib/libarchive/archive_read.c +++ b/lib/libarchive/archive_read.c @@ -58,6 +58,10 @@ archive_read_new(void) char *nulls; a = malloc(sizeof(*a)); + if (a == NULL) { + archive_set_error(a, ENOMEM, "Can't allocate archive object"); + return (NULL); + } memset(a, 0, sizeof(*a)); a->user_uid = geteuid(); @@ -66,6 +70,11 @@ archive_read_new(void) a->null_length = 1024; nulls = malloc(a->null_length); + if (nulls == NULL) { + archive_set_error(a, ENOMEM, "Can't allocate archive object 'nulls' element"); + free(a); + return (NULL); + } memset(nulls, 0, a->null_length); a->nulls = nulls; diff --git a/lib/libarchive/archive_read_open_fd.c b/lib/libarchive/archive_read_open_fd.c index e3b2527..c5d1195 100644 --- a/lib/libarchive/archive_read_open_fd.c +++ b/lib/libarchive/archive_read_open_fd.c @@ -58,6 +58,11 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size) } mine->block_size = block_size; mine->buffer = malloc(mine->block_size); + if (mine->buffer == NULL) { + archive_set_error(a, ENOMEM, "No memory"); + free(mine); + return (ARCHIVE_FATAL); + } mine->fd = fd; return (archive_read_open(a, mine, file_open, file_read, file_close)); } @@ -94,6 +99,7 @@ file_close(struct archive *a, void *client_data) struct read_fd_data *mine = client_data; (void)a; /* UNUSED */ + free(mine->buffer); free(mine); return (ARCHIVE_OK); } diff --git a/lib/libarchive/archive_read_open_file.c b/lib/libarchive/archive_read_open_file.c index ea8ebbd..b0db61c 100644 --- a/lib/libarchive/archive_read_open_file.c +++ b/lib/libarchive/archive_read_open_file.c @@ -83,6 +83,10 @@ file_open(struct archive *a, void *client_data) struct stat st; mine->buffer = malloc(mine->block_size); + if (mine->buffer == NULL) { + archive_set_error(a, ENOMEM, "No memory"); + return (ARCHIVE_FATAL); + } if (mine->filename[0] != '\0') mine->fd = open(mine->filename, O_RDONLY); else diff --git a/lib/libarchive/archive_read_open_filename.c b/lib/libarchive/archive_read_open_filename.c index ea8ebbd..b0db61c 100644 --- a/lib/libarchive/archive_read_open_filename.c +++ b/lib/libarchive/archive_read_open_filename.c @@ -83,6 +83,10 @@ file_open(struct archive *a, void *client_data) struct stat st; mine->buffer = malloc(mine->block_size); + if (mine->buffer == NULL) { + archive_set_error(a, ENOMEM, "No memory"); + return (ARCHIVE_FATAL); + } if (mine->filename[0] != '\0') mine->fd = open(mine->filename, O_RDONLY); else diff --git a/lib/libarchive/archive_read_support_format_cpio.c b/lib/libarchive/archive_read_support_format_cpio.c index 5a0ac70..e74ca3a 100644 --- a/lib/libarchive/archive_read_support_format_cpio.c +++ b/lib/libarchive/archive_read_support_format_cpio.c @@ -134,6 +134,10 @@ archive_read_support_format_cpio(struct archive *a) int r; cpio = malloc(sizeof(*cpio)); + if (cpio == NULL) { + archive_set_error(a, ENOMEM, "Can't allocate cpio data"); + return (ARCHIVE_FATAL); + } memset(cpio, 0, sizeof(*cpio)); cpio->magic = CPIO_MAGIC; @@ -576,6 +580,8 @@ record_hardlink(struct cpio *cpio, struct archive_entry *entry, } le = malloc(sizeof(struct links_entry)); + if (le == NULL) + __archive_errx(1, "Out of memory adding file to list"); if (cpio->links_head != NULL) cpio->links_head->previous = le; le->next = cpio->links_head; @@ -585,4 +591,6 @@ record_hardlink(struct cpio *cpio, struct archive_entry *entry, le->ino = st->st_ino; le->links = st->st_nlink - 1; le->name = strdup(archive_entry_pathname(entry)); + if (le->name == NULL) + __archive_errx(1, "Out of memory adding file to list"); } diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c index a66ec18..6a47d7a 100644 --- a/lib/libarchive/archive_read_support_format_iso9660.c +++ b/lib/libarchive/archive_read_support_format_iso9660.c @@ -121,7 +121,6 @@ struct iso9660_directory_record { char name[1]; }; - /* * Our private data. */ @@ -203,6 +202,10 @@ archive_read_support_format_iso9660(struct archive *a) int r; iso9660 = malloc(sizeof(*iso9660)); + if (iso9660 == NULL) { + archive_set_error(a, ENOMEM, "Can't allocate iso9660 data"); + return (ARCHIVE_FATAL); + } memset(iso9660, 0, sizeof(*iso9660)); iso9660->magic = ISO9660_MAGIC; iso9660->bid = -1; /* We haven't yet bid. */ @@ -465,6 +468,8 @@ parse_file_info(struct iso9660 *iso9660, struct file_info *parent, /* Create a new file entry and copy data from the ISO dir record. */ file = malloc(sizeof(*file)); + if (file == NULL) + return (NULL); memset(file, 0, sizeof(*file)); file->parent = parent; if (parent != NULL) @@ -475,6 +480,10 @@ parse_file_info(struct iso9660 *iso9660, struct file_info *parent, file->mtime = isodate7(isodirrec->date); file->ctime = file->atime = file->mtime; file->name = malloc(isodirrec->name_len[0] + 1); + if (file->name == NULL) { + free(file); + return (NULL); + } memcpy(file->name, isodirrec->name, isodirrec->name_len[0]); file->name[(int)isodirrec->name_len[0]] = '\0'; if (isodirrec->flags[0] & 0x02) @@ -531,6 +540,8 @@ add_entry(struct iso9660 *iso9660, struct file_info *file) if (new_size < 1024) new_size = 1024; new_pending_files = malloc(new_size * sizeof(new_pending_files[0])); + if (new_pending_files == NULL) + __archive_errx(1, "Out of memory"); memcpy(new_pending_files, iso9660->pending_files, iso9660->pending_files_allocated * sizeof(new_pending_files[0])); if (iso9660->pending_files != NULL) diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c index b79140d..c565cec 100644 --- a/lib/libarchive/archive_read_support_format_tar.c +++ b/lib/libarchive/archive_read_support_format_tar.c @@ -230,6 +230,10 @@ archive_read_support_format_tar(struct archive *a) int r; tar = malloc(sizeof(*tar)); + if (tar == NULL) { + archive_set_error(a, ENOMEM, "Can't allocate tar data"); + return (ARCHIVE_FATAL); + } memset(tar, 0, sizeof(*tar)); r = __archive_read_register_format(a, tar, @@ -1080,14 +1084,22 @@ pax_header(struct archive *a, struct tar *tar, struct archive_entry *entry, /* Ensure pax_entry buffer is big enough. */ if (tar->pax_entry_length <= line_length) { + wchar_t *old_entry = tar->pax_entry; + if (tar->pax_entry_length <= 0) tar->pax_entry_length = 1024; while (tar->pax_entry_length <= line_length + 1) tar->pax_entry_length *= 2; - /* XXX Error handling here */ + old_entry = tar->pax_entry; tar->pax_entry = realloc(tar->pax_entry, tar->pax_entry_length * sizeof(wchar_t)); + if (tar->pax_entry == NULL) { + free(old_entry); + archive_set_error(a, ENOMEM, + "No memory"); + return (ARCHIVE_FATAL); + } } /* Decode UTF-8 to wchar_t, null-terminate result. */ @@ -1409,6 +1421,8 @@ gnu_parse_sparse_data(struct archive *a, struct tar *tar, while (length > 0 && sparse->offset[0] != 0) { p = malloc(sizeof(*p)); + if (p == NULL) + __archive_errx(1, "Out of memory"); memset(p, 0, sizeof(*p)); if (last != NULL) last->next = p; diff --git a/lib/libarchive/archive_read_support_format_zip.c b/lib/libarchive/archive_read_support_format_zip.c index 931ea9f..d788e86 100644 --- a/lib/libarchive/archive_read_support_format_zip.c +++ b/lib/libarchive/archive_read_support_format_zip.c @@ -138,6 +138,10 @@ archive_read_support_format_zip(struct archive *a) int r; zip = malloc(sizeof(*zip)); + if (zip == NULL) { + archive_set_error(a, ENOMEM, "Can't allocate zip data"); + return (ARCHIVE_FATAL); + } memset(zip, 0, sizeof(*zip)); r = __archive_read_register_format(a, diff --git a/lib/libarchive/archive_util.c b/lib/libarchive/archive_util.c index de9656d..1567234 100644 --- a/lib/libarchive/archive_util.c +++ b/lib/libarchive/archive_util.c @@ -131,7 +131,7 @@ archive_set_error(struct archive *a, int error_number, const char *fmt, ...) va_start(ap, fmt); archive_string_vsprintf(&(a->error_string), fmt, ap); - if(error_number > 0) { + if (error_number > 0) { archive_strcat(&(a->error_string), ": "); #ifdef HAVE_STRERROR_R #ifdef STRERROR_R_CHAR_P diff --git a/lib/libarchive/archive_write_set_format_cpio.c b/lib/libarchive/archive_write_set_format_cpio.c index c4e6698..659b0a1 100644 --- a/lib/libarchive/archive_write_set_format_cpio.c +++ b/lib/libarchive/archive_write_set_format_cpio.c @@ -128,7 +128,7 @@ archive_write_cpio_header(struct archive *a, struct archive_entry *entry) format_octal(st->st_uid, &h.c_uid, sizeof(h.c_uid)); format_octal(st->st_gid, &h.c_gid, sizeof(h.c_gid)); format_octal(st->st_nlink, &h.c_nlink, sizeof(h.c_nlink)); - if(S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode)) + if (S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode)) format_octal(st->st_rdev, &h.c_rdev, sizeof(h.c_rdev)); else format_octal(0, &h.c_rdev, sizeof(h.c_rdev)); diff --git a/lib/libarchive/archive_write_set_format_pax.c b/lib/libarchive/archive_write_set_format_pax.c index 54e8581..547ada9 100644 --- a/lib/libarchive/archive_write_set_format_pax.c +++ b/lib/libarchive/archive_write_set_format_pax.c @@ -208,6 +208,9 @@ add_pax_attr_w(struct archive_string *as, const char *key, const wchar_t *wval) } utf8_value = malloc(utf8len + 1); + if (utf8_value == NULL) + __archive_errx(1, "Not enough memory for attributes"); + for (wp = wval, p = utf8_value; *wp != L'\0'; ) { wc = *wp++; if (wc <= 0x7f) { diff --git a/lib/libarchive/archive_write_set_format_ustar.c b/lib/libarchive/archive_write_set_format_ustar.c index 51ca575..f2f123d 100644 --- a/lib/libarchive/archive_write_set_format_ustar.c +++ b/lib/libarchive/archive_write_set_format_ustar.c @@ -230,7 +230,7 @@ __archive_write_format_header_ustar(struct archive *a, char buff[512], } p = archive_entry_hardlink(entry); - if(p != NULL) + if (p != NULL) mytartype = '1'; else p = archive_entry_symlink(entry); -- cgit v1.1