Quoth Dimitris Papastamos: 
> Some things that need to be done for tar:
> 
> ...
> - Strip leading / from filenames and dangerous things like ../../ etc.

OK, attached is a patch that does that. I think it covers all the 
bases.
>From b5acf1e9254080c2f283c623f59e412cdb29939a Mon Sep 17 00:00:00 2001
From: Nick White <g...@njw.name>
Date: Mon, 27 Apr 2015 12:25:44 +0100
Subject: [PATCH] Strip dangerous path traversal stuff from paths

Specifically, this removes '../' from anywhere in a path, and any
number of '/' at the start of a path
---
 tar.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/tar.c b/tar.c
index b1f3b27..0bd3fcf 100644
--- a/tar.c
+++ b/tar.c
@@ -359,6 +359,27 @@ sanitize(struct header *h)
 }
 
 static void
+sanitizepath(char *p)
+{
+	size_t l;
+	char *s;
+
+	/* Strip leading '/' characters */
+	while(*p == '/') {
+		l = strlen(p);
+		memmove(p, p+1, l - 1);
+		*(p + l - 1) = '\0';
+	}
+
+	/* Strip '../' from anywhere */
+	while((s = strstr(p, "../")) != NULL) {
+		l = strlen(s);
+		memmove(s, s + 3, l - 3);
+		*(s + l - 3) = '\0';
+	}
+}
+
+static void
 chktar(struct header *h)
 {
 	char tmp[8], *err;
@@ -407,6 +428,7 @@ xt(int argc, char *argv[], int (*fn)(char *, ssize_t, char[BLKSIZ]))
 			             (int)sizeof(h->prefix), h->prefix);
 		snprintf(fname + n, sizeof(fname) - n, "%.*s",
 		         (int)sizeof(h->name), h->name);
+		sanitizepath(fname);
 
 		if ((size = strtol(h->size, &p, 8)) < 0 || *p != '\0')
 			eprintf("strtol %s: invalid number\n", h->size);
-- 
1.7.10.4

Reply via email to