summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-07-03 14:12:46 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-07-03 14:12:46 +0200
commitb8d4983147141310383d423b1bcb9d19a490977a (patch)
treec6d00677cfb115e148b2355fa7712de2562861c3
parentb51a3ab10fad0d00c6fe2aa4d4c1afc6cfcf371f (diff)
Fix: don't blindly strcpy() the tar header name
If the tar header name is exactely 100 bytes long, it does not have a trailing null byte. Using strlen/strcpy on it effectively concatenates the following fields contents to it. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--lib/tar/read_header.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/lib/tar/read_header.c b/lib/tar/read_header.c
index 067b1df..1506037 100644
--- a/lib/tar/read_header.c
+++ b/lib/tar/read_header.c
@@ -199,23 +199,27 @@ fail:
static int decode_header(const tar_header_t *hdr, unsigned int set_by_pax,
tar_header_decoded_t *out, int version)
{
+ size_t len1, len2;
uint64_t field;
- size_t count;
if (!(set_by_pax & PAX_NAME)) {
if (hdr->tail.posix.prefix[0] != '\0' &&
version == ETV_POSIX) {
- count = strlen(hdr->name) + 1;
- count += strlen(hdr->tail.posix.prefix) + 1;
+ len1 = strnlen(hdr->name, sizeof(hdr->name));
+ len2 = strnlen(hdr->tail.posix.prefix,
+ sizeof(hdr->tail.posix.prefix));
- out->name = malloc(count);
+ out->name = malloc(len1 + 1 + len2 + 1);
if (out->name != NULL) {
- sprintf(out->name, "%s/%s",
- hdr->tail.posix.prefix, hdr->name);
+ memcpy(out->name, hdr->name, len1);
+ out->name[len1] = '/';
+ memcpy(out->name + len1 + 1,
+ hdr->tail.posix.prefix, len2);
+ out->name[len1 + 1 + len2] = '\0';
}
} else {
- out->name = strdup(hdr->name);
+ out->name = strndup(hdr->name, sizeof(hdr->name));
}
if (out->name == NULL) {