From e5728052b59fb5b476c78c9f18b812a85d7f4503 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Wed, 1 Jun 2022 20:01:19 +0200 Subject: [PATCH] Refuse to start when SUID is detected This ensures that those surprised by the deprecation of SUID operation receive an error rather than accidentally having sway run as root. This detection will be removed in a future release. --- include/sway/server.h | 2 -- sway/main.c | 44 +++++++++++++------------------------------ sway/server.c | 21 ++++++++------------- 3 files changed, 21 insertions(+), 46 deletions(-) diff --git a/include/sway/server.h b/include/sway/server.h index 3d59ca56..4cce17cc 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -148,8 +148,6 @@ struct sway_debug { extern struct sway_debug debug; -/* Prepares an unprivileged server_init by performing all privileged operations in advance */ -bool server_privileged_prepare(struct sway_server *server); bool server_init(struct sway_server *server); void server_fini(struct sway_server *server); bool server_start(struct sway_server *server); diff --git a/sway/main.c b/sway/main.c index a0033c45..a46e5231 100644 --- a/sway/main.c +++ b/sway/main.c @@ -150,27 +150,17 @@ static void log_kernel(void) { pclose(f); } - -static bool drop_permissions(void) { - if (getuid() != geteuid() || getgid() != getegid()) { - sway_log(SWAY_ERROR, "!!! DEPRECATION WARNING: " - "SUID privilege drop will be removed in a future release, please migrate to seatd-launch"); - - // Set the gid and uid in the correct order. - if (setgid(getgid()) != 0) { - sway_log(SWAY_ERROR, "Unable to drop root group, refusing to start"); - return false; - } - if (setuid(getuid()) != 0) { - sway_log(SWAY_ERROR, "Unable to drop root user, refusing to start"); - return false; - } +static bool detect_suid(void) { + if (geteuid() != 0 && getegid() != 0) { + return false; } - if (setgid(0) != -1 || setuid(0) != -1) { - sway_log(SWAY_ERROR, "Unable to drop root (we shouldn't be able to " - "restore it after setuid), refusing to start"); + + if (getuid() == geteuid() && getgid() == getegid()) { return false; } + + sway_log(SWAY_ERROR, "SUID operation is no longer supported, refusing to start. " + "This check will be removed in a future release."); return true; } @@ -319,6 +309,11 @@ int main(int argc, char **argv) { } } + // SUID operation is deprecated, so block it for now. + if (detect_suid()) { + exit(EXIT_FAILURE); + } + // Since wayland requires XDG_RUNTIME_DIR to be set, abort with just the // clear error message (when not running as an IPC client). if (!getenv("XDG_RUNTIME_DIR") && optind == argc) { @@ -357,9 +352,6 @@ int main(int argc, char **argv) { "`sway -d 2>sway.log`."); exit(EXIT_FAILURE); } - if (!drop_permissions()) { - exit(EXIT_FAILURE); - } char *socket_path = getenv("SWAYSOCK"); if (!socket_path) { sway_log(SWAY_ERROR, "Unable to retrieve socket path"); @@ -372,16 +364,6 @@ int main(int argc, char **argv) { } detect_proprietary(allow_unsupported_gpu); - - if (!server_privileged_prepare(&server)) { - return 1; - } - - if (!drop_permissions()) { - server_fini(&server); - exit(EXIT_FAILURE); - } - increase_nofile_limit(); // handle SIGTERM signals diff --git a/sway/server.c b/sway/server.c index 627d80d6..be74b3b3 100644 --- a/sway/server.c +++ b/sway/server.c @@ -47,19 +47,6 @@ #include "sway/xwayland.h" #endif -bool server_privileged_prepare(struct sway_server *server) { - sway_log(SWAY_DEBUG, "Preparing Wayland server initialization"); - server->wl_display = wl_display_create(); - server->wl_event_loop = wl_display_get_event_loop(server->wl_display); - server->backend = wlr_backend_autocreate(server->wl_display); - - if (!server->backend) { - sway_log(SWAY_ERROR, "Unable to create backend"); - return false; - } - return true; -} - static void handle_drm_lease_request(struct wl_listener *listener, void *data) { /* We only offer non-desktop outputs, but in the future we might want to do * more logic here. */ @@ -76,6 +63,14 @@ static void handle_drm_lease_request(struct wl_listener *listener, void *data) { bool server_init(struct sway_server *server) { sway_log(SWAY_DEBUG, "Initializing Wayland server"); + server->wl_display = wl_display_create(); + server->wl_event_loop = wl_display_get_event_loop(server->wl_display); + server->backend = wlr_backend_autocreate(server->wl_display); + + if (!server->backend) { + sway_log(SWAY_ERROR, "Unable to create backend"); + return false; + } server->renderer = wlr_renderer_autocreate(server->backend); if (!server->renderer) {