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;
+}
diff --git a/sway/main.c b/sway/main.c
index b9549b12..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;
 
@@ -288,6 +310,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");
@@ -317,6 +348,7 @@ int main(int argc, char **argv) {
 		return 0;
 	}
 
+	executable_sanity_check();
 #ifdef __linux__
 	bool suid = false;
 	if (getuid() != geteuid() || getgid() != getegid()) {
@@ -329,14 +361,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();