From 9d178fe573818764a2d15e0a39691f5eb4e300f6 Mon Sep 17 00:00:00 2001
From: Ondrej Dubaj <odubaj@redhat.com>
Date: Mon, 27 May 2019 10:52:51 +0200
Subject: [PATCH] Fix a few obvious resource leaks and strcpy() misuses
Per Coverity report.
---
cpio/cpio.c | 4 +++-
libarchive/archive_acl.c | 8 ++++++--
libarchive/archive_write_set_format_iso9660.c | 4 ++--
libarchive/archive_write_set_format_mtree.c | 4 ++--
libarchive/archive_write_set_format_pax.c | 6 ++++--
libarchive/archive_write_set_format_xar.c | 10 ++++++----
6 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/cpio/cpio.c b/cpio/cpio.c
index 5beedd0..6696bb5 100644
--- a/cpio/cpio.c
+++ b/cpio/cpio.c
@@ -744,8 +744,10 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
}
if (cpio->option_rename)
destpath = cpio_rename(destpath);
- if (destpath == NULL)
+ if (destpath == NULL) {
+ archive_entry_free(entry);
return (0);
+ }
archive_entry_copy_pathname(entry, destpath);
/*
diff --git a/libarchive/archive_acl.c b/libarchive/archive_acl.c
index b8b6b63..503f379 100644
--- a/libarchive/archive_acl.c
+++ b/libarchive/archive_acl.c
@@ -753,8 +753,10 @@ archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
append_entry_w(&wp, prefix, ap->type, ap->tag, flags,
wname, ap->permset, id);
count++;
- } else if (r < 0 && errno == ENOMEM)
+ } else if (r < 0 && errno == ENOMEM) {
+ free(ws);
return (NULL);
+ }
}
/* Add terminating character */
@@ -975,8 +977,10 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
prefix = NULL;
r = archive_mstring_get_mbs_l(
&ap->name, &name, &len, sc);
- if (r != 0)
+ if (r != 0) {
+ free(s);
return (NULL);
+ }
if (count > 0)
*p++ = separator;
if (name == NULL ||
diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c
index c0ca435..badc88b 100644
--- a/libarchive/archive_write_set_format_iso9660.c
+++ b/libarchive/archive_write_set_format_iso9660.c
@@ -4899,10 +4899,10 @@ isofile_gen_utility_names(struct archive_write *a, struct isofile *file)
if (p[0] == '/') {
if (p[1] == '/')
/* Convert '//' --> '/' */
- strcpy(p, p+1);
+ memmove(p, p+1, strlen(p+1) + 1);
else if (p[1] == '.' && p[2] == '/')
/* Convert '/./' --> '/' */
- strcpy(p, p+2);
+ memmove(p, p+2, strlen(p+2) + 1);
else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
/* Convert 'dir/dir1/../dir2/'
* --> 'dir/dir2/'
diff --git a/libarchive/archive_write_set_format_mtree.c b/libarchive/archive_write_set_format_mtree.c
index 493d473..0f2431e 100644
--- a/libarchive/archive_write_set_format_mtree.c
+++ b/libarchive/archive_write_set_format_mtree.c
@@ -1810,10 +1810,10 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
if (p[0] == '/') {
if (p[1] == '/')
/* Convert '//' --> '/' */
- strcpy(p, p+1);
+ memmove(p, p+1, strlen(p+1) + 1);
else if (p[1] == '.' && p[2] == '/')
/* Convert '/./' --> '/' */
- strcpy(p, p+2);
+ memmove(p, p+2, strlen(p+2) + 1);
else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
/* Convert 'dir/dir1/../dir2/'
* --> 'dir/dir2/'
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
index 0eaf733..4863e46 100644
--- a/libarchive/archive_write_set_format_pax.c
+++ b/libarchive/archive_write_set_format_pax.c
@@ -522,11 +522,13 @@ add_pax_acl(struct archive_write *a,
ARCHIVE_ERRNO_FILE_FORMAT, "%s %s %s",
"Can't translate ", attr, " to UTF-8");
return(ARCHIVE_WARN);
- } else if (*p != '\0') {
+ }
+
+ if (*p != '\0') {
add_pax_attr(&(pax->pax_header),
attr, p);
- free(p);
}
+ free(p);
return(ARCHIVE_OK);
}
diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c
index 495f0d4..56cd33c 100644
--- a/libarchive/archive_write_set_format_xar.c
+++ b/libarchive/archive_write_set_format_xar.c
@@ -2120,10 +2120,10 @@ file_gen_utility_names(struct archive_write *a, struct file *file)
if (p[0] == '/') {
if (p[1] == '/')
/* Convert '//' --> '/' */
- strcpy(p, p+1);
+ memmove(p, p+1, strlen(p+1) + 1);
else if (p[1] == '.' && p[2] == '/')
/* Convert '/./' --> '/' */
- strcpy(p, p+2);
+ memmove(p, p+2, strlen(p+2) + 1);
else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
/* Convert 'dir/dir1/../dir2/'
* --> 'dir/dir2/'
@@ -3169,8 +3169,10 @@ save_xattrs(struct archive_write *a, struct file *file)
checksum_update(&(xar->a_sumwrk),
xar->wbuff, size);
if (write_to_temp(a, xar->wbuff, size)
- != ARCHIVE_OK)
- return (ARCHIVE_FATAL);
+ != ARCHIVE_OK) {
+ free(heap);
+ return (ARCHIVE_FATAL);
+ }
if (r == ARCHIVE_OK) {
xar->stream.next_out = xar->wbuff;
xar->stream.avail_out = sizeof(xar->wbuff);
--
2.17.1