From 26752932003145c89a0cd8d39c9944d6f5917837 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 1 Dec 2016 19:58:11 -0500 Subject: Implement policy lookups --- sway/security.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 sway/security.c (limited to 'sway/security.c') diff --git a/sway/security.c b/sway/security.c new file mode 100644 index 00000000..c72d54f6 --- /dev/null +++ b/sway/security.c @@ -0,0 +1,54 @@ +#include +#include +#include "sway/config.h" +#include "sway/security.h" +#include "log.h" + +enum secure_feature get_feature_policy(pid_t pid) { + const char *fmt = "/proc/%d/exe"; + int pathlen = snprintf(NULL, 0, fmt, pid); + char *path = malloc(pathlen + 1); + snprintf(path, pathlen + 1, fmt, pid); + static char link[2048]; + + enum secure_feature default_policy = + FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE; + + ssize_t len = readlink(path, link, sizeof(link)); + if (len < 0) { + sway_log(L_INFO, + "WARNING: unable to read %s for security check. Using default policy.", + path); + strcpy(link, "*"); + } else { + link[len] = '\0'; + } + + for (int i = 0; i < config->feature_policies->length; ++i) { + struct feature_policy *policy = config->feature_policies->items[i]; + if (strcmp(policy->program, "*")) { + default_policy = policy->features; + } + if (strcmp(policy->program, link) == 0) { + return policy->features; + } + } + + return default_policy; +} + +enum command_context get_command_policy(const char *cmd) { + enum command_context default_policy = CONTEXT_ALL; + + for (int i = 0; i < config->command_policies->length; ++i) { + struct command_policy *policy = config->command_policies->items[i]; + if (strcmp(policy->command, "*")) { + default_policy = policy->context; + } + if (strcmp(policy->command, cmd) == 0) { + return policy->context; + } + } + + return default_policy; +} -- cgit v1.2.3 From 1a8a42f372e1bed146623e3357dbb12d8947e654 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 1 Dec 2016 20:39:35 -0500 Subject: Memory leak --- sway/security.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sway/security.c') diff --git a/sway/security.c b/sway/security.c index c72d54f6..00e5e8d7 100644 --- a/sway/security.c +++ b/sway/security.c @@ -15,6 +15,7 @@ enum secure_feature get_feature_policy(pid_t pid) { FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE; ssize_t len = readlink(path, link, sizeof(link)); + free(path); if (len < 0) { sway_log(L_INFO, "WARNING: unable to read %s for security check. Using default policy.", -- cgit v1.2.3 From 76cab04b4d7828f3c4f607c49e1e6ad78aa6e3da Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 1 Dec 2016 21:36:43 -0500 Subject: Implement permit and reject commands --- sway/security.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sway/security.c') diff --git a/sway/security.c b/sway/security.c index 00e5e8d7..776bd527 100644 --- a/sway/security.c +++ b/sway/security.c @@ -4,6 +4,13 @@ #include "sway/security.h" #include "log.h" +struct feature_policy *alloc_feature_policy(const char *program) { + struct feature_policy *policy = malloc(sizeof(struct feature_policy)); + policy->program = strdup(program); + policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE; + return policy; +} + enum secure_feature get_feature_policy(pid_t pid) { const char *fmt = "/proc/%d/exe"; int pathlen = snprintf(NULL, 0, fmt, pid); -- cgit v1.2.3 From 21e1b2bef3d3cda3d10d4dc2aafe5fcac583c2a5 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 1 Dec 2016 21:51:07 -0500 Subject: Add security checks for background, panel, lock --- sway/security.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sway/security.c') diff --git a/sway/security.c b/sway/security.c index 776bd527..a4cecf16 100644 --- a/sway/security.c +++ b/sway/security.c @@ -34,7 +34,7 @@ enum secure_feature get_feature_policy(pid_t pid) { for (int i = 0; i < config->feature_policies->length; ++i) { struct feature_policy *policy = config->feature_policies->items[i]; - if (strcmp(policy->program, "*")) { + if (strcmp(policy->program, "*") == 0) { default_policy = policy->features; } if (strcmp(policy->program, link) == 0) { @@ -50,7 +50,7 @@ enum command_context get_command_policy(const char *cmd) { for (int i = 0; i < config->command_policies->length; ++i) { struct command_policy *policy = config->command_policies->items[i]; - if (strcmp(policy->command, "*")) { + if (strcmp(policy->command, "*") == 0) { default_policy = policy->context; } if (strcmp(policy->command, cmd) == 0) { -- cgit v1.2.3 From f23880b1fdd70a21b04317c18208a1f3ce356839 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 2 Dec 2016 08:10:03 -0500 Subject: Add support for command policies in config file --- sway/security.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sway/security.c') diff --git a/sway/security.c b/sway/security.c index a4cecf16..670cae56 100644 --- a/sway/security.c +++ b/sway/security.c @@ -11,6 +11,13 @@ struct feature_policy *alloc_feature_policy(const char *program) { return policy; } +struct command_policy *alloc_command_policy(const char *command) { + struct command_policy *policy = malloc(sizeof(struct command_policy)); + policy->command = strdup(command); + policy->context = CONTEXT_ALL; + return policy; +} + enum secure_feature get_feature_policy(pid_t pid) { const char *fmt = "/proc/%d/exe"; int pathlen = snprintf(NULL, 0, fmt, pid); @@ -50,9 +57,6 @@ enum command_context get_command_policy(const char *cmd) { for (int i = 0; i < config->command_policies->length; ++i) { struct command_policy *policy = config->command_policies->items[i]; - if (strcmp(policy->command, "*") == 0) { - default_policy = policy->context; - } if (strcmp(policy->command, cmd) == 0) { return policy->context; } -- cgit v1.2.3 From 39cf9a82f7c1f7e5d7b4952cabf215c8459a99e2 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 2 Dec 2016 08:17:45 -0500 Subject: Enforce command policies --- sway/security.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'sway/security.c') diff --git a/sway/security.c b/sway/security.c index 670cae56..2ccc30fd 100644 --- a/sway/security.c +++ b/sway/security.c @@ -64,3 +64,20 @@ enum command_context get_command_policy(const char *cmd) { return default_policy; } + +const char *command_policy_str(enum command_context context) { + switch (context) { + case CONTEXT_ALL: + return "all"; + case CONTEXT_CONFIG: + return "config"; + case CONTEXT_BINDING: + return "binding"; + case CONTEXT_IPC: + return "IPC"; + case CONTEXT_CRITERIA: + return "criteria"; + default: + return "unknown"; + } +} -- cgit v1.2.3 From d353da248b4653d7bc027ff0dceca946cdd0b22f Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 2 Dec 2016 18:08:15 -0500 Subject: Add ipc connection feature policy controls --- sway/security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/security.c') diff --git a/sway/security.c b/sway/security.c index 2ccc30fd..0d510253 100644 --- a/sway/security.c +++ b/sway/security.c @@ -7,7 +7,7 @@ struct feature_policy *alloc_feature_policy(const char *program) { struct feature_policy *policy = malloc(sizeof(struct feature_policy)); policy->program = strdup(program); - policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE; + policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE | FEATURE_IPC; return policy; } -- cgit v1.2.3 From 93d99f37126b93176677fb22cf7500d10f3db6e4 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 2 Dec 2016 18:57:10 -0500 Subject: Fix use-after-free --- sway/security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/security.c') diff --git a/sway/security.c b/sway/security.c index 0d510253..1d236b1d 100644 --- a/sway/security.c +++ b/sway/security.c @@ -29,7 +29,6 @@ enum secure_feature get_feature_policy(pid_t pid) { FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE; ssize_t len = readlink(path, link, sizeof(link)); - free(path); if (len < 0) { sway_log(L_INFO, "WARNING: unable to read %s for security check. Using default policy.", @@ -38,6 +37,7 @@ enum secure_feature get_feature_policy(pid_t pid) { } else { link[len] = '\0'; } + free(path); for (int i = 0; i < config->feature_policies->length; ++i) { struct feature_policy *policy = config->feature_policies->items[i]; -- cgit v1.2.3 From e7a764fdf450a8259ddbc17446dd720fa1157b44 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 3 Dec 2016 12:38:42 -0500 Subject: Disallow everything by default And update config.d/security to configure sane defaults --- sway/security.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'sway/security.c') diff --git a/sway/security.c b/sway/security.c index 1d236b1d..f16fdd1f 100644 --- a/sway/security.c +++ b/sway/security.c @@ -5,16 +5,25 @@ #include "log.h" struct feature_policy *alloc_feature_policy(const char *program) { + uint32_t default_policy = 0; + for (int i = 0; i < config->feature_policies->length; ++i) { + struct feature_policy *policy = config->feature_policies->items[i]; + if (strcmp(policy->program, "*") == 0) { + default_policy = policy->features; + break; + } + } + struct feature_policy *policy = malloc(sizeof(struct feature_policy)); policy->program = strdup(program); - policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE | FEATURE_IPC; + policy->features = default_policy; return policy; } struct command_policy *alloc_command_policy(const char *command) { struct command_policy *policy = malloc(sizeof(struct command_policy)); policy->command = strdup(command); - policy->context = CONTEXT_ALL; + policy->context = 0; return policy; } @@ -25,8 +34,7 @@ enum secure_feature get_feature_policy(pid_t pid) { snprintf(path, pathlen + 1, fmt, pid); static char link[2048]; - enum secure_feature default_policy = - FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE; + uint32_t default_policy = 0; ssize_t len = readlink(path, link, sizeof(link)); if (len < 0) { @@ -53,10 +61,13 @@ enum secure_feature get_feature_policy(pid_t pid) { } enum command_context get_command_policy(const char *cmd) { - enum command_context default_policy = CONTEXT_ALL; + uint32_t default_policy = 0; for (int i = 0; i < config->command_policies->length; ++i) { struct command_policy *policy = config->command_policies->items[i]; + if (strcmp(policy->command, "*") == 0) { + default_policy = policy->context; + } if (strcmp(policy->command, cmd) == 0) { return policy->context; } -- cgit v1.2.3