From 1513ea4aef457f20788d9d61db9f2ddbcb29e12d Mon Sep 17 00:00:00 2001
From: Julian Rother <julianr@fsmpi.rwth-aachen.de>
Date: Tue, 5 Dec 2017 01:33:30 +0100
Subject: [PATCH] Introduced path sanitizing

---
 probe.c          |  4 ++--
 publish_video.c  |  4 ++--
 remux.c          |  4 ++--
 thumbnail.c      |  2 +-
 transcode.c      |  4 ++--
 util.h           |  1 +
 util/buildpath.c | 21 +++++++++++++++++++++
 7 files changed, 31 insertions(+), 9 deletions(-)
 create mode 100644 util/buildpath.c

diff --git a/probe.c b/probe.c
index 5c60658..7866807 100644
--- a/probe.c
+++ b/probe.c
@@ -75,9 +75,9 @@ int main(int argc, char *argv[])
 
 	jobid = atoi(argv[1]);
 	if (!strcmp(argv[2], "probe-raw"))
-		path = mprintf("%s/%s", getenv(WORKER_RAW), jstr(jlookup(argv[4], "path"), ""));
+		path = buildpath(getenv(WORKER_RAW), jstr(jlookup(argv[4], "path"), 0));
 	else
-		path = mprintf("%s/%s", getenv(WORKER_RELEASED), jstr(jlookup(argv[4], "path"), ""));
+		path = buildpath(getenv(WORKER_RELEASED), jstr(jlookup(argv[4], "path"), 0));
 	ping_job(jobid, "running", 0);
 
 	opts = 0;
diff --git a/publish_video.c b/publish_video.c
index b84810a..3ef95b8 100644
--- a/publish_video.c
+++ b/publish_video.c
@@ -13,8 +13,8 @@ int main(int argc, char *argv[])
 	init_env();
 	init_avlogbuf();
 	jobid = atoi(argv[1]);
-	src = mprintf("%s/%s", getenv(WORKER_TMP), jstr(jlookup(argv[4], "source"), ""));
-	dest = mprintf("%s/%s", getenv(WORKER_RELEASED), jstr(jlookup(argv[4], "path"), ""));
+	src = buildpath(getenv(WORKER_TMP), jstr(jlookup(argv[4], "source"), 0));
+	dest = buildpath(getenv(WORKER_RELEASED), jstr(jlookup(argv[4], "path"), 0));
 	destdir = dirname(mprintf("%s/%s", getenv(WORKER_RELEASED), jstr(jlookup(argv[4], "path"), "")));
 	ping_job(jobid, "running", 0);
 	overwrite_check(dest, 0, 0);
diff --git a/remux.c b/remux.c
index 973b79b..725c680 100644
--- a/remux.c
+++ b/remux.c
@@ -21,8 +21,8 @@ int main(int argc, char *argv[])
 	av_init_packet(&pkt);
 
 	jobid = atoi(argv[1]);
-	path = mprintf("%s/%s", getenv(WORKER_RELEASED), jstr(jlookup(argv[4], "path"), ""));
-	srcpath = mprintf("%s/%s", getenv(WORKER_RAW), jstr(jlookup(argv[4], "srcpath"), ""));
+	path = buildpath(getenv(WORKER_RELEASED), jstr(jlookup(argv[4], "path"), 0));
+	srcpath = buildpath(getenv(WORKER_RAW), jstr(jlookup(argv[4], "srcpath"), 0));
 	tmp = mprintf("%s/.tmp-%i", getenv(WORKER_TMP), jobid);
 	overwrite_check(path, srcpath, jstr(jlookup(argv[4], "srchash"), ""));
 	ping_job(jobid, "running", 0);
diff --git a/thumbnail.c b/thumbnail.c
index bfc0ebc..720a036 100644
--- a/thumbnail.c
+++ b/thumbnail.c
@@ -37,7 +37,7 @@ int main(int argc, char *argv[])
 
 	/* Prepare arguments */
 	jobid = atoi(argv[1]);
-	src = mprintf("%s/%s", getenv(WORKER_RELEASED), jstr(jlookup(argv[4], "path"), ""));
+	src = buildpath(getenv(WORKER_RELEASED), jstr(jlookup(argv[4], "path"), 0));
 	tmp = mprintf("%s/.tmp-%i", getenv(WORKER_TMP), jobid);
 	dest = mprintf("%s/thumbnail/l_%s.jpg", getenv(WORKER_RELEASED),
 			jstr(jlookup(argv[4], "lectureid"), "0"));
diff --git a/transcode.c b/transcode.c
index f4765d6..b01cbe7 100644
--- a/transcode.c
+++ b/transcode.c
@@ -270,9 +270,9 @@ int main(int argc, char *argv[])
 
 	jobid = atoi(argv[1]);
 	input = jlookup(argv[4], "input");
-	inpath = mprintf("%s/%s", getenv(WORKER_RAW), jstr(jlookup(input, "path"), ""));
+	inpath = buildpath(getenv(WORKER_RAW), jstr(jlookup(input, "path"), 0));
 	output = jlookup(argv[4], "output");
-	outpath = mprintf("%s/%s", getenv(WORKER_RELEASED), jstr(jlookup(output, "path"), ""));
+	outpath = buildpath(getenv(WORKER_RELEASED), jstr(jlookup(output, "path"), 0));
 	tmppath = mprintf("%s/.tmp-%i", getenv(WORKER_TMP), jobid);
 	overwrite_check(outpath, inpath, jstr(jlookup(input, "hash"), ""));
 
diff --git a/util.h b/util.h
index 7997699..fef2e13 100644
--- a/util.h
+++ b/util.h
@@ -18,6 +18,7 @@ size_t filesize(char *path);
 char *json_fileinfo(char *path);
 void overwrite_check(char *path, char *srcpath, char *srchash);
 int checktime(time_t min);
+char *buildpath(char *root, char *path);
 
 #define WORKER_APIKEY "WORKER_APIKEY"
 #define WORKER_APIBASE "WORKER_APIBASE"
diff --git a/util/buildpath.c b/util/buildpath.c
new file mode 100644
index 0000000..4057d18
--- /dev/null
+++ b/util/buildpath.c
@@ -0,0 +1,21 @@
+#include <stdlib.h>
+
+#include "../util.h"
+
+char *buildpath(char *root, char *path)
+{
+	char *tmp;
+	if (!path)
+		job_failed("Cannot build path: Value is empty");
+	if (!(root = realpath(root, 0)))
+		exit(99);
+	tmp = mprintf("%s/%s", root, path);
+	if (!(path = realpath(tmp, 0)))
+		exit(99);
+	free(tmp);
+	if (strncmp(root, path, strlen(root)))
+		job_failed("Cannot build path: Path points out of root directory");
+	free(root);
+	return path;
+}
+
-- 
GitLab