diff options
-rw-r--r-- | sway/main.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/sway/main.c b/sway/main.c index e8a02e7a..7bf71b53 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -10,6 +10,9 @@ | |||
10 | #include <unistd.h> | 10 | #include <unistd.h> |
11 | #include <getopt.h> | 11 | #include <getopt.h> |
12 | #include <sys/capability.h> | 12 | #include <sys/capability.h> |
13 | #ifdef __linux__ | ||
14 | #include <sys/prctl.h> | ||
15 | #endif | ||
13 | #include "sway/extensions.h" | 16 | #include "sway/extensions.h" |
14 | #include "sway/layout.h" | 17 | #include "sway/layout.h" |
15 | #include "sway/config.h" | 18 | #include "sway/config.h" |
@@ -289,6 +292,18 @@ int main(int argc, char **argv) { | |||
289 | return 0; | 292 | return 0; |
290 | } | 293 | } |
291 | 294 | ||
295 | #ifdef __linux__ | ||
296 | bool suid = false; | ||
297 | if (getuid() != geteuid() || getgid() != getegid()) { | ||
298 | // Retain capabilities after setuid() | ||
299 | if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { | ||
300 | sway_log(L_ERROR, "Cannot keep caps after setuid()"); | ||
301 | exit(EXIT_FAILURE); | ||
302 | } | ||
303 | suid = true; | ||
304 | } | ||
305 | #endif | ||
306 | |||
292 | // we need to setup logging before wlc_init in case it fails. | 307 | // we need to setup logging before wlc_init in case it fails. |
293 | if (debug) { | 308 | if (debug) { |
294 | init_log(L_DEBUG); | 309 | init_log(L_DEBUG); |
@@ -311,6 +326,20 @@ int main(int argc, char **argv) { | |||
311 | } | 326 | } |
312 | register_extensions(); | 327 | register_extensions(); |
313 | 328 | ||
329 | #ifdef __linux__ | ||
330 | if (suid) { | ||
331 | // Drop every cap except CAP_SYS_PTRACE | ||
332 | cap_t caps = cap_init(); | ||
333 | cap_value_t keep = CAP_SYS_PTRACE; | ||
334 | sway_log(L_INFO, "Dropping extra capabilities"); | ||
335 | if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || | ||
336 | cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || | ||
337 | cap_set_proc(caps)) { | ||
338 | sway_log(L_ERROR, "Failed to drop extra capabilities"); | ||
339 | exit(EXIT_FAILURE); | ||
340 | } | ||
341 | } | ||
342 | #endif | ||
314 | // handle SIGTERM signals | 343 | // handle SIGTERM signals |
315 | signal(SIGTERM, sig_handler); | 344 | signal(SIGTERM, sig_handler); |
316 | 345 | ||