diff options
-rw-r--r-- | sway/security.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/sway/security.c b/sway/security.c index 96af2b88..8eab6126 100644 --- a/sway/security.c +++ b/sway/security.c | |||
@@ -1,4 +1,6 @@ | |||
1 | #define _XOPEN_SOURCE 500 | 1 | #define _XOPEN_SOURCE 500 |
2 | #include <sys/types.h> | ||
3 | #include <sys/stat.h> | ||
2 | #include <string.h> | 4 | #include <string.h> |
3 | #include <unistd.h> | 5 | #include <unistd.h> |
4 | #include <stdio.h> | 6 | #include <stdio.h> |
@@ -6,8 +8,46 @@ | |||
6 | #include "sway/security.h" | 8 | #include "sway/security.h" |
7 | #include "log.h" | 9 | #include "log.h" |
8 | 10 | ||
11 | static bool validate_ipc_target(const char *program) { | ||
12 | struct stat sb; | ||
13 | |||
14 | sway_log(L_DEBUG, "Validating IPC target '%s'", program); | ||
15 | |||
16 | if (!strcmp(program, "*")) { | ||
17 | return true; | ||
18 | } | ||
19 | if (lstat(program, &sb) == -1) { | ||
20 | return false; | ||
21 | } | ||
22 | if (!S_ISREG(sb.st_mode)) { | ||
23 | sway_log(L_ERROR, | ||
24 | "IPC target '%s' MUST be/point at an existing regular file", | ||
25 | program); | ||
26 | return false; | ||
27 | } | ||
28 | if (sb.st_uid != 0) { | ||
29 | #ifdef NDEBUG | ||
30 | sway_log(L_ERROR, "IPC target '%s' MUST be owned by root", program); | ||
31 | return false; | ||
32 | #else | ||
33 | sway_log(L_INFO, "IPC target '%s' MUST be owned by root (waived for debug build)", program); | ||
34 | return true; | ||
35 | #endif | ||
36 | } | ||
37 | if (sb.st_mode & S_IWOTH) { | ||
38 | sway_log(L_ERROR, "IPC target '%s' MUST NOT be world writable", program); | ||
39 | return false; | ||
40 | } | ||
41 | |||
42 | return true; | ||
43 | } | ||
44 | |||
9 | struct feature_policy *alloc_feature_policy(const char *program) { | 45 | struct feature_policy *alloc_feature_policy(const char *program) { |
10 | uint32_t default_policy = 0; | 46 | uint32_t default_policy = 0; |
47 | |||
48 | if (!validate_ipc_target(program)) { | ||
49 | return NULL; | ||
50 | } | ||
11 | for (int i = 0; i < config->feature_policies->length; ++i) { | 51 | for (int i = 0; i < config->feature_policies->length; ++i) { |
12 | struct feature_policy *policy = config->feature_policies->items[i]; | 52 | struct feature_policy *policy = config->feature_policies->items[i]; |
13 | if (strcmp(policy->program, "*") == 0) { | 53 | if (strcmp(policy->program, "*") == 0) { |
@@ -26,11 +66,16 @@ struct feature_policy *alloc_feature_policy(const char *program) { | |||
26 | return NULL; | 66 | return NULL; |
27 | } | 67 | } |
28 | policy->features = default_policy; | 68 | policy->features = default_policy; |
69 | |||
29 | return policy; | 70 | return policy; |
30 | } | 71 | } |
31 | 72 | ||
32 | struct ipc_policy *alloc_ipc_policy(const char *program) { | 73 | struct ipc_policy *alloc_ipc_policy(const char *program) { |
33 | uint32_t default_policy = 0; | 74 | uint32_t default_policy = 0; |
75 | |||
76 | if (!validate_ipc_target(program)) { | ||
77 | return NULL; | ||
78 | } | ||
34 | for (int i = 0; i < config->ipc_policies->length; ++i) { | 79 | for (int i = 0; i < config->ipc_policies->length; ++i) { |
35 | struct ipc_policy *policy = config->ipc_policies->items[i]; | 80 | struct ipc_policy *policy = config->ipc_policies->items[i]; |
36 | if (strcmp(policy->program, "*") == 0) { | 81 | if (strcmp(policy->program, "*") == 0) { |
@@ -49,6 +94,7 @@ struct ipc_policy *alloc_ipc_policy(const char *program) { | |||
49 | return NULL; | 94 | return NULL; |
50 | } | 95 | } |
51 | policy->features = default_policy; | 96 | policy->features = default_policy; |
97 | |||
52 | return policy; | 98 | return policy; |
53 | } | 99 | } |
54 | 100 | ||