From be4cc756b7a04fcc66f2dd6093f0d7afe29d4b5a Mon Sep 17 00:00:00 2001
From: Julian Rother <julianr@fsmpi.rwth-aachen.de>
Date: Thu, 30 Nov 2017 12:33:31 +0100
Subject: [PATCH] Extended overwrite_check to check source file hash

---
 remux.c                | 7 ++++---
 transcode.c            | 4 ++--
 util.h                 | 2 +-
 util/overwrite_check.c | 4 +++-
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/remux.c b/remux.c
index ef6c0d1..973b79b 100644
--- a/remux.c
+++ b/remux.c
@@ -7,7 +7,7 @@ int main(int argc, char *argv[])
 {
 	int i, err;
 	int *idxmap;
-	char *p, *path, *tmp;
+	char *p, *path, *srcpath, *tmp;
 	AVFormatContext *demux, *mux;
 	AVPacket pkt;
 	AVStream *stream;
@@ -22,8 +22,9 @@ int main(int argc, char *argv[])
 
 	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"), ""));
 	tmp = mprintf("%s/.tmp-%i", getenv(WORKER_TMP), jobid);
-	overwrite_check(path);
+	overwrite_check(path, srcpath, jstr(jlookup(argv[4], "srchash"), ""));
 	ping_job(jobid, "running", 0);
 
 	demux = 0;
@@ -79,7 +80,7 @@ int main(int argc, char *argv[])
 	avio_closep(&mux->pb);
 	if (!filesize(tmp))
 		job_failed("Sanity check failed: Output file is empty");
-	overwrite_check(path);
+	overwrite_check(path, srcpath, jstr(jlookup(argv[4], "srchash"), ""));
 	if (rename(tmp, path))
 		job_failed("Overwriting output file failed: %s", strerror(errno));
 	unlink(tmp);
diff --git a/transcode.c b/transcode.c
index ab3581a..f4765d6 100644
--- a/transcode.c
+++ b/transcode.c
@@ -274,7 +274,7 @@ int main(int argc, char *argv[])
 	output = jlookup(argv[4], "output");
 	outpath = mprintf("%s/%s", getenv(WORKER_RELEASED), jstr(jlookup(output, "path"), ""));
 	tmppath = mprintf("%s/.tmp-%i", getenv(WORKER_TMP), jobid);
-	overwrite_check(outpath);
+	overwrite_check(outpath, inpath, jstr(jlookup(input, "hash"), ""));
 
 	demux = 0;
 	opts = 0;
@@ -359,7 +359,7 @@ int main(int argc, char *argv[])
 	avio_closep(&mux->pb);
 	if (!filesize(tmppath))
 		job_failed("Sanity check failed: Output file is empty");
-	overwrite_check(outpath);
+	overwrite_check(outpath, 0, 0);
 	if (rename(tmppath, outpath))
 		job_failed("Overwriting output file \"%s\" failed: %s", outpath, strerror(errno));
 	unlink(tmppath);
diff --git a/util.h b/util.h
index 434c32f..7997699 100644
--- a/util.h
+++ b/util.h
@@ -16,7 +16,7 @@ char *hashfile(char *path);
 double fileduration(char *path);
 size_t filesize(char *path);
 char *json_fileinfo(char *path);
-void overwrite_check(char *path);
+void overwrite_check(char *path, char *srcpath, char *srchash);
 int checktime(time_t min);
 
 #define WORKER_APIKEY "WORKER_APIKEY"
diff --git a/util/overwrite_check.c b/util/overwrite_check.c
index 9842c32..e08e63e 100644
--- a/util/overwrite_check.c
+++ b/util/overwrite_check.c
@@ -3,11 +3,13 @@
 
 #include "../util.h"
 
-void overwrite_check(char *path)
+void overwrite_check(char *path, char *srcpath, char *srchash)
 {
 	struct stat s;
 	if (stat(path, &s) || !s.st_size)
 		return; /* We can overwrite non-existing or empty files */
+	if (srcpath && strcmp(hashfile(srcpath), srchash))
+		job_failed("Refusing to overwrite output file \"%s\": Source file hash mismatch", path);
 	if (s.st_uid != getuid())
 		job_failed("Refusing to overwrite output file \"%s\": File was not created by worker", path);
 }
-- 
GitLab