Skip to content

Commit

Permalink
Refuse to start when SUID is detected
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kennylevinsen authored and emersion committed Jun 3, 2022
1 parent 251a648 commit e572805
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 46 deletions.
2 changes: 0 additions & 2 deletions include/sway/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
44 changes: 13 additions & 31 deletions sway/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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");
Expand All @@ -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
Expand Down
21 changes: 8 additions & 13 deletions sway/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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) {
Expand Down

0 comments on commit e572805

Please sign in to comment.