From 3ef6d4e4c97c937e82b873399d76900ebb498389 Mon Sep 17 00:00:00 2001 From: sin Date: Mon, 20 Apr 2015 16:29:21 +0100 Subject: [PATCH] Fix tar(1) handling of terminated fields Numeric fields can be terminated. Ensure those are patched with NULs so we can perform string operations. There is more work to be done in this area, namely some fields like name, linkname and prefix are not always null-terminated. --- tar.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tar.c b/tar.c index 72fd3b2..afe7854 100644 --- a/tar.c +++ b/tar.c @@ -279,6 +279,33 @@ c(const char *path, struct stat *st, void *data, struct recursor *r) recurse(path, NULL, r); } +static void +sanitize(struct header *h) +{ + size_t i, j; + struct { + char *f; + size_t l; + } fields[] = { + { h->mode, sizeof(h->mode) }, + { h->uid, sizeof(h->uid) }, + { h->gid, sizeof(h->gid) }, + { h->size, sizeof(h->size) }, + { h->mtime, sizeof(h->mtime) }, + { h->chksum, sizeof(h->chksum) }, + { h->major, sizeof(h->major) }, + { h->minor, sizeof(h->minor) } + }; + + /* Numeric fields can be terminated with spaces instead of + * NULs as per the ustar specification. Patch all of them to + * use NULs so we can perform string operations on them. */ + for (i = 0; i < LEN(fields); i++) + for (j = 0; j < fields[i].l; j++) + if (fields[i].f[j] == ' ') + fields[i].f[j] = '\0'; +} + static void xt(int (*fn)(char *, ssize_t, char[BLKSIZ])) { @@ -289,6 +316,7 @@ xt(int (*fn)(char *, ssize_t, char[BLKSIZ])) h = (void *)b; while (fread(b, BLKSIZ, 1, tarfile) == 1 && *(h->name)) { + sanitize(h); fname[0] = '\0'; if (*(h->prefix)) { estrlcat(fname, h->prefix, sizeof(fname));