diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-10-22 10:37:30 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2017-11-11 09:08:50 -0500 |
commit | 7c448b408126aef0561be0761871f968921d7db0 (patch) | |
tree | 055716519b975eca17b2e27254217acd1b801c20 /sway/main.c | |
parent | Find and link to wlroots (diff) | |
download | sway-7c448b408126aef0561be0761871f968921d7db0.tar.gz sway-7c448b408126aef0561be0761871f968921d7db0.tar.zst sway-7c448b408126aef0561be0761871f968921d7db0.zip |
Fire up the wlroots backend and run the event loop
Diffstat (limited to 'sway/main.c')
-rw-r--r-- | sway/main.c | 113 |
1 files changed, 44 insertions, 69 deletions
diff --git a/sway/main.c b/sway/main.c index cc9147b8..efca96d5 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -3,7 +3,6 @@ | |||
3 | #include <stdio.h> | 3 | #include <stdio.h> |
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | #include <wlc/wlc.h> | ||
7 | #include <sys/wait.h> | 6 | #include <sys/wait.h> |
8 | #include <sys/types.h> | 7 | #include <sys/types.h> |
9 | #include <sys/stat.h> | 8 | #include <sys/stat.h> |
@@ -15,13 +14,13 @@ | |||
15 | #include <sys/capability.h> | 14 | #include <sys/capability.h> |
16 | #include <sys/prctl.h> | 15 | #include <sys/prctl.h> |
17 | #endif | 16 | #endif |
18 | #include "sway/extensions.h" | ||
19 | #include "sway/layout.h" | 17 | #include "sway/layout.h" |
20 | #include "sway/config.h" | 18 | #include "sway/config.h" |
21 | #include "sway/security.h" | 19 | #include "sway/security.h" |
22 | #include "sway/handlers.h" | 20 | #include "sway/handlers.h" |
23 | #include "sway/input.h" | 21 | #include "sway/input.h" |
24 | #include "sway/ipc-server.h" | 22 | #include "sway/ipc-server.h" |
23 | #include "sway/server.h" | ||
25 | #include "ipc-client.h" | 24 | #include "ipc-client.h" |
26 | #include "readline.h" | 25 | #include "readline.h" |
27 | #include "stringop.h" | 26 | #include "stringop.h" |
@@ -31,11 +30,12 @@ | |||
31 | 30 | ||
32 | static bool terminate_request = false; | 31 | static bool terminate_request = false; |
33 | static int exit_value = 0; | 32 | static int exit_value = 0; |
33 | struct sway_server server; | ||
34 | 34 | ||
35 | void sway_terminate(int exit_code) { | 35 | void sway_terminate(int exit_code) { |
36 | terminate_request = true; | 36 | terminate_request = true; |
37 | exit_value = exit_code; | 37 | exit_value = exit_code; |
38 | wlc_terminate(); | 38 | wl_display_terminate(server.wl_display); |
39 | } | 39 | } |
40 | 40 | ||
41 | void sig_handler(int signal) { | 41 | void sig_handler(int signal) { |
@@ -43,16 +43,6 @@ void sig_handler(int signal) { | |||
43 | sway_terminate(EXIT_SUCCESS); | 43 | sway_terminate(EXIT_SUCCESS); |
44 | } | 44 | } |
45 | 45 | ||
46 | static void wlc_log_handler(enum wlc_log_type type, const char *str) { | ||
47 | if (type == WLC_LOG_ERROR) { | ||
48 | sway_log(L_ERROR, "[wlc] %s", str); | ||
49 | } else if (type == WLC_LOG_WARN) { | ||
50 | sway_log(L_INFO, "[wlc] %s", str); | ||
51 | } else { | ||
52 | sway_log(L_DEBUG, "[wlc] %s", str); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | void detect_raspi() { | 46 | void detect_raspi() { |
57 | bool raspi = false; | 47 | bool raspi = false; |
58 | FILE *f = fopen("/sys/firmware/devicetree/base/model", "r"); | 48 | FILE *f = fopen("/sys/firmware/devicetree/base/model", "r"); |
@@ -189,19 +179,7 @@ static void log_env() { | |||
189 | "LD_LIBRARY_PATH", | 179 | "LD_LIBRARY_PATH", |
190 | "SWAY_CURSOR_THEME", | 180 | "SWAY_CURSOR_THEME", |
191 | "SWAY_CURSOR_SIZE", | 181 | "SWAY_CURSOR_SIZE", |
192 | "SWAYSOCK", | 182 | "SWAYSOCK" |
193 | "WLC_DRM_DEVICE", | ||
194 | "WLC_SHM", | ||
195 | "WLC_OUTPUTS", | ||
196 | "WLC_XWAYLAND", | ||
197 | "WLC_LIBINPUT", | ||
198 | "WLC_REPEAT_DELAY", | ||
199 | "WLC_REPEAT_RATE", | ||
200 | "XKB_DEFAULT_RULES", | ||
201 | "XKB_DEFAULT_MODEL", | ||
202 | "XKB_DEFAULT_LAYOUT", | ||
203 | "XKB_DEFAULT_VARIANT", | ||
204 | "XKB_DEFAULT_OPTIONS", | ||
205 | }; | 183 | }; |
206 | for (size_t i = 0; i < sizeof(log_vars) / sizeof(char *); ++i) { | 184 | for (size_t i = 0; i < sizeof(log_vars) / sizeof(char *); ++i) { |
207 | sway_log(L_INFO, "%s=%s", log_vars[i], getenv(log_vars[i])); | 185 | sway_log(L_INFO, "%s=%s", log_vars[i], getenv(log_vars[i])); |
@@ -295,6 +273,37 @@ static void executable_sanity_check() { | |||
295 | #endif | 273 | #endif |
296 | } | 274 | } |
297 | 275 | ||
276 | static void drop_permissions(bool keep_caps) { | ||
277 | if (getuid() != geteuid() || getgid() != getegid()) { | ||
278 | if (setgid(getgid()) != 0) { | ||
279 | sway_log(L_ERROR, "Unable to drop root"); | ||
280 | exit(EXIT_FAILURE); | ||
281 | } | ||
282 | if (setuid(getuid()) != 0) { | ||
283 | sway_log(L_ERROR, "Unable to drop root"); | ||
284 | exit(EXIT_FAILURE); | ||
285 | } | ||
286 | } | ||
287 | if (setuid(0) != -1) { | ||
288 | sway_log(L_ERROR, "Root privileges can be restored."); | ||
289 | exit(EXIT_FAILURE); | ||
290 | } | ||
291 | #ifdef __linux__ | ||
292 | if (keep_caps) { | ||
293 | // Drop every cap except CAP_SYS_PTRACE | ||
294 | cap_t caps = cap_init(); | ||
295 | cap_value_t keep = CAP_SYS_PTRACE; | ||
296 | sway_log(L_INFO, "Dropping extra capabilities"); | ||
297 | if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || | ||
298 | cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || | ||
299 | cap_set_proc(caps)) { | ||
300 | sway_log(L_ERROR, "Failed to drop extra capabilities"); | ||
301 | exit(EXIT_FAILURE); | ||
302 | } | ||
303 | } | ||
304 | #endif | ||
305 | } | ||
306 | |||
298 | int main(int argc, char **argv) { | 307 | int main(int argc, char **argv) { |
299 | static int verbose = 0, debug = 0, validate = 0; | 308 | static int verbose = 0, debug = 0, validate = 0; |
300 | 309 | ||
@@ -374,7 +383,7 @@ int main(int argc, char **argv) { | |||
374 | } | 383 | } |
375 | } | 384 | } |
376 | 385 | ||
377 | // we need to setup logging before wlc_init in case it fails. | 386 | // TODO: switch logging over to wlroots? |
378 | if (debug) { | 387 | if (debug) { |
379 | init_log(L_DEBUG); | 388 | init_log(L_DEBUG); |
380 | } else if (verbose || validate) { | 389 | } else if (verbose || validate) { |
@@ -388,20 +397,7 @@ int main(int argc, char **argv) { | |||
388 | sway_log(L_ERROR, "Don't use options with the IPC client"); | 397 | sway_log(L_ERROR, "Don't use options with the IPC client"); |
389 | exit(EXIT_FAILURE); | 398 | exit(EXIT_FAILURE); |
390 | } | 399 | } |
391 | if (getuid() != geteuid() || getgid() != getegid()) { | 400 | drop_permissions(false); |
392 | if (setgid(getgid()) != 0) { | ||
393 | sway_log(L_ERROR, "Unable to drop root"); | ||
394 | exit(EXIT_FAILURE); | ||
395 | } | ||
396 | if (setuid(getuid()) != 0) { | ||
397 | sway_log(L_ERROR, "Unable to drop root"); | ||
398 | exit(EXIT_FAILURE); | ||
399 | } | ||
400 | } | ||
401 | if (setuid(0) != -1) { | ||
402 | sway_log(L_ERROR, "Root privileges can be restored."); | ||
403 | exit(EXIT_FAILURE); | ||
404 | } | ||
405 | char *socket_path = getenv("SWAYSOCK"); | 401 | char *socket_path = getenv("SWAYSOCK"); |
406 | if (!socket_path) { | 402 | if (!socket_path) { |
407 | sway_log(L_ERROR, "Unable to retrieve socket path"); | 403 | sway_log(L_ERROR, "Unable to retrieve socket path"); |
@@ -413,8 +409,8 @@ int main(int argc, char **argv) { | |||
413 | } | 409 | } |
414 | 410 | ||
415 | executable_sanity_check(); | 411 | executable_sanity_check(); |
416 | #ifdef __linux__ | ||
417 | bool suid = false; | 412 | bool suid = false; |
413 | #ifdef __linux__ | ||
418 | if (getuid() != geteuid() || getgid() != getegid()) { | 414 | if (getuid() != geteuid() || getgid() != getegid()) { |
419 | // Retain capabilities after setuid() | 415 | // Retain capabilities after setuid() |
420 | if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { | 416 | if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { |
@@ -425,37 +421,14 @@ int main(int argc, char **argv) { | |||
425 | } | 421 | } |
426 | #endif | 422 | #endif |
427 | 423 | ||
428 | wlc_log_set_handler(wlc_log_handler); | ||
429 | log_kernel(); | 424 | log_kernel(); |
430 | log_distro(); | 425 | log_distro(); |
431 | log_env(); | 426 | log_env(); |
432 | detect_proprietary(); | 427 | detect_proprietary(); |
433 | detect_raspi(); | 428 | detect_raspi(); |
434 | 429 | ||
435 | input_devices = create_list(); | ||
436 | |||
437 | /* Changing code earlier than this point requires detailed review */ | ||
438 | /* (That code runs as root on systems without logind, and wlc_init drops to | ||
439 | * another user.) */ | ||
440 | register_wlc_handlers(); | ||
441 | if (!wlc_init()) { | ||
442 | return 1; | ||
443 | } | ||
444 | register_extensions(); | ||
445 | |||
446 | #ifdef __linux__ | 430 | #ifdef __linux__ |
447 | if (suid) { | 431 | drop_permissions(suid); |
448 | // Drop every cap except CAP_SYS_PTRACE | ||
449 | cap_t caps = cap_init(); | ||
450 | cap_value_t keep = CAP_SYS_PTRACE; | ||
451 | sway_log(L_INFO, "Dropping extra capabilities"); | ||
452 | if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || | ||
453 | cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || | ||
454 | cap_set_proc(caps)) { | ||
455 | sway_log(L_ERROR, "Failed to drop extra capabilities"); | ||
456 | exit(EXIT_FAILURE); | ||
457 | } | ||
458 | } | ||
459 | #endif | 432 | #endif |
460 | // handle SIGTERM signals | 433 | // handle SIGTERM signals |
461 | signal(SIGTERM, sig_handler); | 434 | signal(SIGTERM, sig_handler); |
@@ -465,8 +438,10 @@ int main(int argc, char **argv) { | |||
465 | 438 | ||
466 | sway_log(L_INFO, "Starting sway version " SWAY_VERSION "\n"); | 439 | sway_log(L_INFO, "Starting sway version " SWAY_VERSION "\n"); |
467 | 440 | ||
441 | if (!server_init(&server)) { | ||
442 | return 1; | ||
443 | } | ||
468 | init_layout(); | 444 | init_layout(); |
469 | |||
470 | ipc_init(); | 445 | ipc_init(); |
471 | 446 | ||
472 | if (validate) { | 447 | if (validate) { |
@@ -485,10 +460,10 @@ int main(int argc, char **argv) { | |||
485 | security_sanity_check(); | 460 | security_sanity_check(); |
486 | 461 | ||
487 | if (!terminate_request) { | 462 | if (!terminate_request) { |
488 | wlc_run(); | 463 | wl_display_run(server.wl_display); |
489 | } | 464 | } |
490 | 465 | ||
491 | list_free(input_devices); | 466 | server_fini(&server); |
492 | 467 | ||
493 | ipc_terminate(); | 468 | ipc_terminate(); |
494 | 469 | ||