From f736198c315bb91bfa7faff095181a3e8e89df94 Mon Sep 17 00:00:00 2001
From: Mykyta Holubakha <hilobakho@gmail.com>
Date: Thu, 11 May 2017 19:29:10 +0300
Subject: [PATCH 1/3] Initialise logging earlier

---
 sway/main.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/sway/main.c b/sway/main.c
index b9549b12..3d2d6c68 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -288,6 +288,15 @@ int main(int argc, char **argv) {
 		}
 	}
 
+	// we need to setup logging before wlc_init in case it fails.
+	if (debug) {
+		init_log(L_DEBUG);
+	} else if (verbose || validate) {
+		init_log(L_INFO);
+	} else {
+		init_log(L_ERROR);
+	}
+
 	if (optind < argc) { // Behave as IPC client
 		if(optind != 1) {
 			sway_log(L_ERROR, "Don't use options with the IPC client");
@@ -329,14 +338,6 @@ int main(int argc, char **argv) {
 	}
 #endif
 
-	// we need to setup logging before wlc_init in case it fails.
-	if (debug) {
-		init_log(L_DEBUG);
-	} else if (verbose || validate) {
-		init_log(L_INFO);
-	} else {
-		init_log(L_ERROR);
-	}
 	wlc_log_set_handler(wlc_log_handler);
 	log_kernel();
 	log_distro();

From 93cf21fb9afd8205f01399ed2d8dcbe16b522fa4 Mon Sep 17 00:00:00 2001
From: Mykyta Holubakha <hilobakho@gmail.com>
Date: Wed, 10 May 2017 02:51:28 +0300
Subject: [PATCH 2/3] Terminate when both suid bit and filecaps are set

---
 sway/main.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/sway/main.c b/sway/main.c
index 3d2d6c68..819788b1 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -27,6 +27,7 @@
 #include "stringop.h"
 #include "sway.h"
 #include "log.h"
+#include "util.h"
 
 static bool terminate_request = false;
 static int exit_value = 0;
@@ -209,6 +210,27 @@ static void security_sanity_check() {
 #endif
 }
 
+static void executable_sanity_check() {
+#ifdef __linux__
+		struct stat sb;
+		char *exe = realpath("/proc/self/exe", NULL);
+		stat(exe, &sb);
+		// We assume that cap_get_file returning NULL implies ENODATA
+		if (sb.st_mode & (S_ISUID|S_ISGID) && cap_get_file(exe)) {
+			sway_log(L_ERROR,
+				"sway executable has both the s(g)uid bit AND file caps set.");
+			sway_log(L_ERROR,
+				"This is strongly discouraged (and completely broken).");
+			sway_log(L_ERROR,
+				"Please clear one of them (either the suid bit, or the file caps).");
+			sway_log(L_ERROR,
+				"If unsure, strip the file caps.");
+			exit(EXIT_FAILURE);
+		}
+		free(exe);
+#endif
+}
+
 int main(int argc, char **argv) {
 	static int verbose = 0, debug = 0, validate = 0;
 
@@ -326,6 +348,7 @@ int main(int argc, char **argv) {
 		return 0;
 	}
 
+	executable_sanity_check();
 #ifdef __linux__
 	bool suid = false;
 	if (getuid() != geteuid() || getgid() != getegid()) {

From f470fa58a3fb56f456f83f08e3509d9785ad06d5 Mon Sep 17 00:00:00 2001
From: Mykyta Holubakha <hilobakho@gmail.com>
Date: Thu, 11 May 2017 19:38:32 +0300
Subject: [PATCH 3/3] Replace spaces with tabs in resolve_path

---
 common/util.c | 64 +++++++++++++++++++++++++--------------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/common/util.c b/common/util.c
index a9e6a9c2..34bb5ec1 100644
--- a/common/util.c
+++ b/common/util.c
@@ -124,38 +124,38 @@ uint32_t parse_color(const char *color) {
 }
 
 char* resolve_path(const char* path) {
-    struct stat sb;
-    ssize_t r;
-    int i;
-    char *current = NULL;
-    char *resolved = NULL;
+	struct stat sb;
+	ssize_t r;
+	int i;
+	char *current = NULL;
+	char *resolved = NULL;
 
-    if(!(current = strdup(path))) {
-           return NULL;
-    }
-    for (i = 0; i < 16; ++i) {
-        if (lstat(current, &sb) == -1) {
-           goto failed;
-        }
-        if((sb.st_mode & S_IFMT) != S_IFLNK) {
-            return current;
-        }
-        if (!(resolved = malloc(sb.st_size + 1))) {
-           goto failed;
-        }
-        r = readlink(current, resolved, sb.st_size);
-        if (r == -1 || r > sb.st_size) {
-           goto failed;
-        }
-        resolved[r] = '\0';
-        free(current);
-        current = strdup(resolved);
-        free(resolved);
-        resolved = NULL;
-    }
+	if(!(current = strdup(path))) {
+		return NULL;
+	}
+	for (i = 0; i < 16; ++i) {
+		if (lstat(current, &sb) == -1) {
+			goto failed;
+		}
+		if((sb.st_mode & S_IFMT) != S_IFLNK) {
+			return current;
+		}
+		if (!(resolved = malloc(sb.st_size + 1))) {
+			goto failed;
+		}
+		r = readlink(current, resolved, sb.st_size);
+		if (r == -1 || r > sb.st_size) {
+			goto failed;
+		}
+		resolved[r] = '\0';
+		free(current);
+		current = strdup(resolved);
+		free(resolved);
+		resolved = NULL;
+	}
 
 failed:
-    free(resolved);
-    free(current);
-    return NULL;
-}
\ No newline at end of file
+	free(resolved);
+	free(current);
+	return NULL;
+}