summaryrefslogtreecommitdiffstats
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 @@
4#include <wlc/wlc.h> 4#include <wlc/wlc.h>
5#include <sys/wait.h> 5#include <sys/wait.h>
6#include <sys/types.h> 6#include <sys/types.h>
7#include <sys/stat.h>
7#include <sys/un.h> 8#include <sys/un.h>
8#include <signal.h> 9#include <signal.h>
9#include <unistd.h> 10#include <unistd.h>
10#include <getopt.h> 11#include <getopt.h>
12#include <sys/capability.h>
11#include "sway/extensions.h" 13#include "sway/extensions.h"
12#include "sway/layout.h" 14#include "sway/layout.h"
13#include "sway/config.h" 15#include "sway/config.h"
16#include "sway/security.h"
14#include "sway/handlers.h" 17#include "sway/handlers.h"
15#include "sway/input.h" 18#include "sway/input.h"
16#include "sway/ipc-server.h" 19#include "sway/ipc-server.h"
@@ -142,6 +145,63 @@ static void log_kernel() {
142 fclose(f); 145 fclose(f);
143} 146}
144 147
148static void security_sanity_check() {
149 // TODO: Notify users visually if this has issues
150 struct stat s;
151 if (stat("/proc", &s)) {
152 sway_log(L_ERROR,
153 "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!");
154 }
155 cap_flag_value_t v;
156 cap_t cap = cap_get_proc();
157 if (!cap || cap_get_flag(cap, CAP_SYS_PTRACE, CAP_PERMITTED, &v) != 0 || v != CAP_SET) {
158 sway_log(L_ERROR,
159 "!! DANGER !! Sway does not have CAP_SYS_PTRACE and cannot enforce security rules for processes running as other users.");
160 }
161 if (cap) {
162 cap_free(cap);
163 }
164 if (!stat(SYSCONFDIR "/sway", &s)) {
165 if (s.st_uid != 0 || s.st_gid != 0
166 || (s.st_mode & S_IWGRP) || (s.st_mode & S_IWOTH)) {
167 sway_log(L_ERROR,
168 "!! DANGER !! " SYSCONFDIR "/sway is not secure! It should be owned by root and set to 0755 at the minimum");
169 }
170 }
171 struct {
172 char *command;
173 enum command_context context;
174 bool checked;
175 } expected[] = {
176 { "reload", CONTEXT_BINDING, false },
177 { "restart", CONTEXT_BINDING, false },
178 { "permit", CONTEXT_CONFIG, false },
179 { "reject", CONTEXT_CONFIG, false },
180 { "ipc", CONTEXT_CONFIG, false },
181 };
182 int expected_len = 5;
183 for (int i = 0; i < config->command_policies->length; ++i) {
184 struct command_policy *policy = config->command_policies->items[i];
185 for (int j = 0; j < expected_len; ++j) {
186 if (strcmp(expected[j].command, policy->command) == 0) {
187 expected[j].checked = true;
188 if (expected[j].context != policy->context) {
189 sway_log(L_ERROR,
190 "!! DANGER !! Command security policy for %s should be set to %s",
191 expected[j].command, command_policy_str(expected[j].context));
192 }
193 }
194 }
195 }
196 for (int j = 0; j < expected_len; ++j) {
197 if (!expected[j].checked) {
198 sway_log(L_ERROR,
199 "!! DANGER !! Command security policy for %s should be set to %s",
200 expected[j].command, command_policy_str(expected[j].context));
201 }
202 }
203}
204
145int main(int argc, char **argv) { 205int main(int argc, char **argv) {
146 static int verbose = 0, debug = 0, validate = 0; 206 static int verbose = 0, debug = 0, validate = 0;
147 207
@@ -170,6 +230,10 @@ int main(int argc, char **argv) {
170 " --get-socketpath Gets the IPC socket path and prints it, then exits.\n" 230 " --get-socketpath Gets the IPC socket path and prints it, then exits.\n"
171 "\n"; 231 "\n";
172 232
233 // Security:
234 unsetenv("LD_PRELOAD");
235 setenv("LD_LIBRARY_PATH", _LD_LIBRARY_PATH, 1);
236
173 int c; 237 int c;
174 while (1) { 238 while (1) {
175 int option_index = 0; 239 int option_index = 0;
@@ -298,6 +362,8 @@ int main(int argc, char **argv) {
298 free(config_path); 362 free(config_path);
299 } 363 }
300 364
365 security_sanity_check();
366
301 if (!terminate_request) { 367 if (!terminate_request) {
302 wlc_run(); 368 wlc_run();
303 } 369 }