aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kenny Levinsen <kl@kl.wtf>2022-06-01 20:01:19 +0200
committerLibravatar Simon Ser <contact@emersion.fr>2022-06-03 12:37:40 +0200
commite5728052b59fb5b476c78c9f18b812a85d7f4503 (patch)
treea456d2cbdc8aad99cc713682447b9e55379b6d18
parentipc: remove chatty debug log messages (diff)
downloadsway-e5728052b59fb5b476c78c9f18b812a85d7f4503.tar.gz
sway-e5728052b59fb5b476c78c9f18b812a85d7f4503.tar.zst
sway-e5728052b59fb5b476c78c9f18b812a85d7f4503.zip
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.
-rw-r--r--include/sway/server.h2
-rw-r--r--sway/main.c44
-rw-r--r--sway/server.c21
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 {
148 148
149extern struct sway_debug debug; 149extern struct sway_debug debug;
150 150
151/* Prepares an unprivileged server_init by performing all privileged operations in advance */
152bool server_privileged_prepare(struct sway_server *server);
153bool server_init(struct sway_server *server); 151bool server_init(struct sway_server *server);
154void server_fini(struct sway_server *server); 152void server_fini(struct sway_server *server);
155bool server_start(struct sway_server *server); 153bool 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) {
150 pclose(f); 150 pclose(f);
151} 151}
152 152
153 153static bool detect_suid(void) {
154static bool drop_permissions(void) { 154 if (geteuid() != 0 && getegid() != 0) {
155 if (getuid() != geteuid() || getgid() != getegid()) { 155 return false;
156 sway_log(SWAY_ERROR, "!!! DEPRECATION WARNING: "
157 "SUID privilege drop will be removed in a future release, please migrate to seatd-launch");
158
159 // Set the gid and uid in the correct order.
160 if (setgid(getgid()) != 0) {
161 sway_log(SWAY_ERROR, "Unable to drop root group, refusing to start");
162 return false;
163 }
164 if (setuid(getuid()) != 0) {
165 sway_log(SWAY_ERROR, "Unable to drop root user, refusing to start");
166 return false;
167 }
168 } 156 }
169 if (setgid(0) != -1 || setuid(0) != -1) { 157
170 sway_log(SWAY_ERROR, "Unable to drop root (we shouldn't be able to " 158 if (getuid() == geteuid() && getgid() == getegid()) {
171 "restore it after setuid), refusing to start");
172 return false; 159 return false;
173 } 160 }
161
162 sway_log(SWAY_ERROR, "SUID operation is no longer supported, refusing to start. "
163 "This check will be removed in a future release.");
174 return true; 164 return true;
175} 165}
176 166
@@ -319,6 +309,11 @@ int main(int argc, char **argv) {
319 } 309 }
320 } 310 }
321 311
312 // SUID operation is deprecated, so block it for now.
313 if (detect_suid()) {
314 exit(EXIT_FAILURE);
315 }
316
322 // Since wayland requires XDG_RUNTIME_DIR to be set, abort with just the 317 // Since wayland requires XDG_RUNTIME_DIR to be set, abort with just the
323 // clear error message (when not running as an IPC client). 318 // clear error message (when not running as an IPC client).
324 if (!getenv("XDG_RUNTIME_DIR") && optind == argc) { 319 if (!getenv("XDG_RUNTIME_DIR") && optind == argc) {
@@ -357,9 +352,6 @@ int main(int argc, char **argv) {
357 "`sway -d 2>sway.log`."); 352 "`sway -d 2>sway.log`.");
358 exit(EXIT_FAILURE); 353 exit(EXIT_FAILURE);
359 } 354 }
360 if (!drop_permissions()) {
361 exit(EXIT_FAILURE);
362 }
363 char *socket_path = getenv("SWAYSOCK"); 355 char *socket_path = getenv("SWAYSOCK");
364 if (!socket_path) { 356 if (!socket_path) {
365 sway_log(SWAY_ERROR, "Unable to retrieve socket path"); 357 sway_log(SWAY_ERROR, "Unable to retrieve socket path");
@@ -372,16 +364,6 @@ int main(int argc, char **argv) {
372 } 364 }
373 365
374 detect_proprietary(allow_unsupported_gpu); 366 detect_proprietary(allow_unsupported_gpu);
375
376 if (!server_privileged_prepare(&server)) {
377 return 1;
378 }
379
380 if (!drop_permissions()) {
381 server_fini(&server);
382 exit(EXIT_FAILURE);
383 }
384
385 increase_nofile_limit(); 367 increase_nofile_limit();
386 368
387 // handle SIGTERM signals 369 // 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 @@
47#include "sway/xwayland.h" 47#include "sway/xwayland.h"
48#endif 48#endif
49 49
50bool server_privileged_prepare(struct sway_server *server) {
51 sway_log(SWAY_DEBUG, "Preparing Wayland server initialization");
52 server->wl_display = wl_display_create();
53 server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
54 server->backend = wlr_backend_autocreate(server->wl_display);
55
56 if (!server->backend) {
57 sway_log(SWAY_ERROR, "Unable to create backend");
58 return false;
59 }
60 return true;
61}
62
63static void handle_drm_lease_request(struct wl_listener *listener, void *data) { 50static void handle_drm_lease_request(struct wl_listener *listener, void *data) {
64 /* We only offer non-desktop outputs, but in the future we might want to do 51 /* We only offer non-desktop outputs, but in the future we might want to do
65 * more logic here. */ 52 * more logic here. */
@@ -76,6 +63,14 @@ static void handle_drm_lease_request(struct wl_listener *listener, void *data) {
76 63
77bool server_init(struct sway_server *server) { 64bool server_init(struct sway_server *server) {
78 sway_log(SWAY_DEBUG, "Initializing Wayland server"); 65 sway_log(SWAY_DEBUG, "Initializing Wayland server");
66 server->wl_display = wl_display_create();
67 server->wl_event_loop = wl_display_get_event_loop(server->wl_display);
68 server->backend = wlr_backend_autocreate(server->wl_display);
69
70 if (!server->backend) {
71 sway_log(SWAY_ERROR, "Unable to create backend");
72 return false;
73 }
79 74
80 server->renderer = wlr_renderer_autocreate(server->backend); 75 server->renderer = wlr_renderer_autocreate(server->backend);
81 if (!server->renderer) { 76 if (!server->renderer) {