sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

commit 3ef6d4e4c97c937e82b873399d76900ebb498389
parent d6885987e5f8fabd486d94d649206d0c34fc5ef0
Author: sin <sin@2f30.org>
Date:   Mon, 20 Apr 2015 16:29:21 +0100

Fix tar(1) handling of <space> terminated fields

Numeric fields can be <space> 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.

Diffstat:
Mtar.c | 28++++++++++++++++++++++++++++
1 file changed, 28 insertions(+), 0 deletions(-)

diff --git a/tar.c b/tar.c @@ -280,6 +280,33 @@ c(const char *path, struct stat *st, void *data, struct recursor *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])) { struct header *h; @@ -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));