From d87ede0d695b0b891fda45e85df94cb5b1c3bf0e Mon Sep 17 00:00:00 2001 From: Ryan Farley Date: Tue, 13 Apr 2021 19:41:27 -0500 Subject: xwayland/sockets: ensure proper permissions Create a private UNIX socket directory (755), or use an existing one but ensure proper permissions are set to prevent meddling from other users. --- xwayland/sockets.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/xwayland/sockets.c b/xwayland/sockets.c index 6360745f..873fde8d 100644 --- a/xwayland/sockets.c +++ b/xwayland/sockets.c @@ -1,4 +1,4 @@ -#define _POSIX_C_SOURCE 200809L +#define _XOPEN_SOURCE 700 #include #include #include @@ -84,11 +84,46 @@ cleanup: return -1; } +static bool check_socket_dir(void) { + struct stat buf; + + if (lstat(socket_dir, &buf)) { + wlr_log_errno(WLR_ERROR, "Failed to stat %s", socket_dir); + return false; + } + if (!(buf.st_mode & S_IFDIR)) { + wlr_log(WLR_ERROR, "%s is not a directory", socket_dir); + return false; + } + if (!((buf.st_uid == 0) || (buf.st_uid == getuid()))) { + wlr_log(WLR_ERROR, "%s not owned by root or us", socket_dir); + return false; + } + if (!(buf.st_mode & S_ISVTX)) { + /* we can deal with no sticky bit... */ + if ((buf.st_mode & (S_IWGRP | S_IWOTH))) { + /* but not if other users can mess with our sockets */ + wlr_log(WLR_ERROR, "sticky bit not set on %s", socket_dir); + return false; + } + } + return true; +} + static bool open_sockets(int socks[2], int display) { struct sockaddr_un addr = { .sun_family = AF_UNIX }; size_t path_size; - mkdir(socket_dir, 0777); + if (mkdir(socket_dir, 0755) == 0) { + wlr_log(WLR_INFO, "Created %s ourselves -- other users will " + "be unable to create X11 UNIX sockets of their own", + socket_dir); + } else if (errno != EEXIST) { + wlr_log_errno(WLR_ERROR, "Unable to mkdir %s", socket_dir); + return false; + } else if (!check_socket_dir()) { + return false; + } #ifdef __linux__ addr.sun_path[0] = 0; -- cgit v1.2.3