aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMykyta Holubakha <hilobakho@gmail.com>2017-01-12 04:25:03 +0200
committerMykyta Holubakha <hilobakho@gmail.com>2017-01-12 04:25:27 +0200
commitea1313d80d5ee1623b00c8cdf6e7ff8a7e14c2ae (patch)
treeeb404bad9c33885a101ff9af396c425bff4d2700
parent527c259d063a4d7ca2bfd62b3b877bb70419535b (diff)
downloadsway-ea1313d80d5ee1623b00c8cdf6e7ff8a7e14c2ae.zip
sway-ea1313d80d5ee1623b00c8cdf6e7ff8a7e14c2ae.tar.gz
sway-ea1313d80d5ee1623b00c8cdf6e7ff8a7e14c2ae.tar.bz2
Keep CAP_SYS_PTRACE with suid binary
-rw-r--r--sway/main.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/sway/main.c b/sway/main.c
index e8a02e7..6c74aab 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -10,6 +10,9 @@
#include <unistd.h>
#include <getopt.h>
#include <sys/capability.h>
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
#include "sway/extensions.h"
#include "sway/layout.h"
#include "sway/config.h"
@@ -289,6 +292,18 @@ int main(int argc, char **argv) {
return 0;
}
+#ifdef __linux__
+ bool suid = false;
+ if (getuid() != geteuid() || getgid() != getegid()) {
+ // Retain capabilities after setuid()
+ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
+ sway_log(L_ERROR, "Cannot keep caps after setuid()");
+ exit(EXIT_FAILURE);
+ }
+ suid = true;
+ }
+#endif
+
// we need to setup logging before wlc_init in case it fails.
if (debug) {
init_log(L_DEBUG);
@@ -311,6 +326,19 @@ int main(int argc, char **argv) {
}
register_extensions();
+#ifdef __linux__
+ if (suid) {
+ // Drop every cap except CAP_SYS_PTRACE
+ cap_t caps = cap_init();
+ cap_value_t keep = CAP_SYS_PTRACE;
+ if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) ||
+ cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) ||
+ cap_set_proc(caps)) {
+ sway_log(L_ERROR, "Failed to drop extra capabilities");
+ exit(EXIT_FAILURE);
+ }
+ }
+#endif
// handle SIGTERM signals
signal(SIGTERM, sig_handler);