aboutsummaryrefslogtreecommitdiff
path: root/sway/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/main.c')
-rw-r--r--sway/main.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/sway/main.c b/sway/main.c
index a040cec9..73c4b5f2 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -4,13 +4,16 @@
#include <wlc/wlc.h>
#include <sys/wait.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/un.h>
#include <signal.h>
#include <unistd.h>
#include <getopt.h>
+#include <sys/capability.h>
#include "sway/extensions.h"
#include "sway/layout.h"
#include "sway/config.h"
+#include "sway/security.h"
#include "sway/handlers.h"
#include "sway/input.h"
#include "sway/ipc-server.h"
@@ -142,6 +145,63 @@ static void log_kernel() {
fclose(f);
}
+static void security_sanity_check() {
+ // TODO: Notify users visually if this has issues
+ struct stat s;
+ if (stat("/proc", &s)) {
+ sway_log(L_ERROR,
+ "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!");
+ }
+ cap_flag_value_t v;
+ cap_t cap = cap_get_proc();
+ if (!cap || cap_get_flag(cap, CAP_SYS_PTRACE, CAP_PERMITTED, &v) != 0 || v != CAP_SET) {
+ sway_log(L_ERROR,
+ "!! DANGER !! Sway does not have CAP_SYS_PTRACE and cannot enforce security rules for processes running as other users.");
+ }
+ if (cap) {
+ cap_free(cap);
+ }
+ if (!stat(SYSCONFDIR "/sway", &s)) {
+ if (s.st_uid != 0 || s.st_gid != 0
+ || (s.st_mode & S_IWGRP) || (s.st_mode & S_IWOTH)) {
+ sway_log(L_ERROR,
+ "!! DANGER !! " SYSCONFDIR "/sway is not secure! It should be owned by root and set to 0755 at the minimum");
+ }
+ }
+ struct {
+ char *command;
+ enum command_context context;
+ bool checked;
+ } expected[] = {
+ { "reload", CONTEXT_BINDING, false },
+ { "restart", CONTEXT_BINDING, false },
+ { "permit", CONTEXT_CONFIG, false },
+ { "reject", CONTEXT_CONFIG, false },
+ { "ipc", CONTEXT_CONFIG, false },
+ };
+ int expected_len = 5;
+ for (int i = 0; i < config->command_policies->length; ++i) {
+ struct command_policy *policy = config->command_policies->items[i];
+ for (int j = 0; j < expected_len; ++j) {
+ if (strcmp(expected[j].command, policy->command) == 0) {
+ expected[j].checked = true;
+ if (expected[j].context != policy->context) {
+ sway_log(L_ERROR,
+ "!! DANGER !! Command security policy for %s should be set to %s",
+ expected[j].command, command_policy_str(expected[j].context));
+ }
+ }
+ }
+ }
+ for (int j = 0; j < expected_len; ++j) {
+ if (!expected[j].checked) {
+ sway_log(L_ERROR,
+ "!! DANGER !! Command security policy for %s should be set to %s",
+ expected[j].command, command_policy_str(expected[j].context));
+ }
+ }
+}
+
int main(int argc, char **argv) {
static int verbose = 0, debug = 0, validate = 0;
@@ -170,6 +230,10 @@ int main(int argc, char **argv) {
" --get-socketpath Gets the IPC socket path and prints it, then exits.\n"
"\n";
+ // Security:
+ unsetenv("LD_PRELOAD");
+ setenv("LD_LIBRARY_PATH", _LD_LIBRARY_PATH, 1);
+
int c;
while (1) {
int option_index = 0;
@@ -298,6 +362,8 @@ int main(int argc, char **argv) {
free(config_path);
}
+ security_sanity_check();
+
if (!terminate_request) {
wlc_run();
}