From 5831f7ab68a7166a492812d6301868541fdc9ae3 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 1 Dec 2016 19:27:35 -0500 Subject: Write example security config, start on code --- sway/main.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'sway/main.c') diff --git a/sway/main.c b/sway/main.c index a040cec9..4704f900 100644 --- a/sway/main.c +++ b/sway/main.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -142,6 +143,27 @@ static void log_kernel() { fclose(f); } +static void security_sanity_check() { + // TODO: Notify users visually if this has issues + struct stat s = {0}; + if (stat("/proc", &s)) { + sway_log(L_ERROR, + "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!"); + } + if (!stat(SYSCONFDIR "/sway", &s)) { + if (s.st_uid != 0 || s.st_gid != 0 || s.st_mode != 00755) { + sway_log(L_ERROR, + "!! DANGER !! " SYSCONFDIR "/sway is not secure! It should be owned by root and set to 0755"); + } + } + // TODO: check that these command policies are set + // reload bindsym + // restart bindsym + // permit config + // reject config + // ipc config +} + int main(int argc, char **argv) { static int verbose = 0, debug = 0, validate = 0; @@ -256,6 +278,7 @@ int main(int argc, char **argv) { } wlc_log_set_handler(wlc_log_handler); detect_proprietary(); + security_sanity_check(); input_devices = create_list(); -- cgit v1.2.3 From dc4b57c868662e76dc4363eca6ddd0d73284eb72 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 1 Dec 2016 21:58:38 -0500 Subject: Shut Clang up --- sway/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/main.c') diff --git a/sway/main.c b/sway/main.c index 4704f900..a6721fba 100644 --- a/sway/main.c +++ b/sway/main.c @@ -145,7 +145,7 @@ static void log_kernel() { static void security_sanity_check() { // TODO: Notify users visually if this has issues - struct stat s = {0}; + struct stat s; if (stat("/proc", &s)) { sway_log(L_ERROR, "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!"); -- cgit v1.2.3 From 04fc10feeb4bd3a736b071ef1fa89c5685118707 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 2 Dec 2016 08:42:26 -0500 Subject: Flesh out security_sanity_check --- sway/main.c | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'sway/main.c') diff --git a/sway/main.c b/sway/main.c index a6721fba..d396089c 100644 --- a/sway/main.c +++ b/sway/main.c @@ -12,6 +12,7 @@ #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" @@ -151,17 +152,44 @@ static void security_sanity_check() { "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!"); } if (!stat(SYSCONFDIR "/sway", &s)) { - if (s.st_uid != 0 || s.st_gid != 0 || s.st_mode != 00755) { + 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"); + "!! 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)); } } - // TODO: check that these command policies are set - // reload bindsym - // restart bindsym - // permit config - // reject config - // ipc config } int main(int argc, char **argv) { @@ -278,7 +306,6 @@ int main(int argc, char **argv) { } wlc_log_set_handler(wlc_log_handler); detect_proprietary(); - security_sanity_check(); input_devices = create_list(); @@ -321,6 +348,8 @@ int main(int argc, char **argv) { free(config_path); } + security_sanity_check(); + if (!terminate_request) { wlc_run(); } -- cgit v1.2.3 From 10c21250402aa8127a6700bc0330f47c7439f5bb Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 2 Dec 2016 08:47:03 -0500 Subject: Unset LD_PRELOAD on startup (before dropping root) LD_PRELOAD enables keyloggers to easily be made. This solution isn't perfect - really a secure system wouldn't have LD_PRELOAD at all. It was a stupid idea in the first place. --- sway/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sway/main.c') diff --git a/sway/main.c b/sway/main.c index d396089c..1db88da2 100644 --- a/sway/main.c +++ b/sway/main.c @@ -220,6 +220,8 @@ int main(int argc, char **argv) { " --get-socketpath Gets the IPC socket path and prints it, then exits.\n" "\n"; + unsetenv("LD_PRELOAD"); // Security + int c; while (1) { int option_index = 0; -- cgit v1.2.3 From a4e92ad2723a9c33c029f90f8a2af054bf74e1ce Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 2 Dec 2016 10:23:30 -0500 Subject: Deal with LD_LIBRARY_PATH --- sway/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sway/main.c') diff --git a/sway/main.c b/sway/main.c index 1db88da2..9746cfb2 100644 --- a/sway/main.c +++ b/sway/main.c @@ -220,7 +220,9 @@ int main(int argc, char **argv) { " --get-socketpath Gets the IPC socket path and prints it, then exits.\n" "\n"; - unsetenv("LD_PRELOAD"); // Security + // Security: + unsetenv("LD_PRELOAD"); + setenv("LD_LIBRARY_PATH", _LD_LIBRARY_PATH, 1); int c; while (1) { -- cgit v1.2.3 From 8577095db77eef62af05fd2acbd9bd2c28b901f6 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 2 Dec 2016 18:37:01 -0500 Subject: Check for CAP_SYS_PTRACE --- sway/main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sway/main.c') diff --git a/sway/main.c b/sway/main.c index 9746cfb2..73c4b5f2 100644 --- a/sway/main.c +++ b/sway/main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "sway/extensions.h" #include "sway/layout.h" #include "sway/config.h" @@ -151,6 +152,15 @@ static void security_sanity_check() { 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)) { -- cgit v1.2.3