diff options
author | 2017-01-12 04:25:03 +0200 | |
---|---|---|
committer | 2017-01-12 04:25:27 +0200 | |
commit | ea1313d80d5ee1623b00c8cdf6e7ff8a7e14c2ae (patch) | |
tree | eb404bad9c33885a101ff9af396c425bff4d2700 /sway | |
parent | Fix #1008 (diff) | |
download | sway-ea1313d80d5ee1623b00c8cdf6e7ff8a7e14c2ae.tar.gz sway-ea1313d80d5ee1623b00c8cdf6e7ff8a7e14c2ae.tar.zst sway-ea1313d80d5ee1623b00c8cdf6e7ff8a7e14c2ae.zip |
Keep CAP_SYS_PTRACE with suid binary
Diffstat (limited to 'sway')
-rw-r--r-- | sway/main.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sway/main.c b/sway/main.c index e8a02e7a..6c74aab2 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,19 @@ 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 | if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || | ||
335 | cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || | ||
336 | cap_set_proc(caps)) { | ||
337 | sway_log(L_ERROR, "Failed to drop extra capabilities"); | ||
338 | exit(EXIT_FAILURE); | ||
339 | } | ||
340 | } | ||
341 | #endif | ||
314 | // handle SIGTERM signals | 342 | // handle SIGTERM signals |
315 | signal(SIGTERM, sig_handler); | 343 | signal(SIGTERM, sig_handler); |
316 | 344 | ||