aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2017-05-11 12:48:30 -0400
committerLibravatar GitHub <noreply@github.com>2017-05-11 12:48:30 -0400
commit6df0f9a7e4d41cdc56206d178e57eb141a0e3d8f (patch)
treeee9a1ffafa93162484829ca42f6f61a997ca0f90
parentMention Patreon in README.md (diff)
parentReplace spaces with tabs in resolve_path (diff)
downloadsway-6df0f9a7e4d41cdc56206d178e57eb141a0e3d8f.tar.gz
sway-6df0f9a7e4d41cdc56206d178e57eb141a0e3d8f.tar.zst
sway-6df0f9a7e4d41cdc56206d178e57eb141a0e3d8f.zip
Merge pull request #1218 from Hummer12007/suicaps
Terminate when both suid bit and filecaps are set
-rw-r--r--common/util.c66
-rw-r--r--sway/main.c40
2 files changed, 65 insertions, 41 deletions
diff --git a/common/util.c b/common/util.c
index a9e6a9c2..34bb5ec1 100644
--- a/common/util.c
+++ b/common/util.c
@@ -124,38 +124,38 @@ uint32_t parse_color(const char *color) {
124} 124}
125 125
126char* resolve_path(const char* path) { 126char* resolve_path(const char* path) {
127 struct stat sb; 127 struct stat sb;
128 ssize_t r; 128 ssize_t r;
129 int i; 129 int i;
130 char *current = NULL; 130 char *current = NULL;
131 char *resolved = NULL; 131 char *resolved = NULL;
132 132
133 if(!(current = strdup(path))) { 133 if(!(current = strdup(path))) {
134 return NULL; 134 return NULL;
135 } 135 }
136 for (i = 0; i < 16; ++i) { 136 for (i = 0; i < 16; ++i) {
137 if (lstat(current, &sb) == -1) { 137 if (lstat(current, &sb) == -1) {
138 goto failed; 138 goto failed;
139 } 139 }
140 if((sb.st_mode & S_IFMT) != S_IFLNK) { 140 if((sb.st_mode & S_IFMT) != S_IFLNK) {
141 return current; 141 return current;
142 } 142 }
143 if (!(resolved = malloc(sb.st_size + 1))) { 143 if (!(resolved = malloc(sb.st_size + 1))) {
144 goto failed; 144 goto failed;
145 } 145 }
146 r = readlink(current, resolved, sb.st_size); 146 r = readlink(current, resolved, sb.st_size);
147 if (r == -1 || r > sb.st_size) { 147 if (r == -1 || r > sb.st_size) {
148 goto failed; 148 goto failed;
149 } 149 }
150 resolved[r] = '\0'; 150 resolved[r] = '\0';
151 free(current); 151 free(current);
152 current = strdup(resolved); 152 current = strdup(resolved);
153 free(resolved); 153 free(resolved);
154 resolved = NULL; 154 resolved = NULL;
155 } 155 }
156 156
157failed: 157failed:
158 free(resolved); 158 free(resolved);
159 free(current); 159 free(current);
160 return NULL; 160 return NULL;
161} \ No newline at end of file 161}
diff --git a/sway/main.c b/sway/main.c
index b9549b12..819788b1 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -27,6 +27,7 @@
27#include "stringop.h" 27#include "stringop.h"
28#include "sway.h" 28#include "sway.h"
29#include "log.h" 29#include "log.h"
30#include "util.h"
30 31
31static bool terminate_request = false; 32static bool terminate_request = false;
32static int exit_value = 0; 33static int exit_value = 0;
@@ -209,6 +210,27 @@ static void security_sanity_check() {
209#endif 210#endif
210} 211}
211 212
213static void executable_sanity_check() {
214#ifdef __linux__
215 struct stat sb;
216 char *exe = realpath("/proc/self/exe", NULL);
217 stat(exe, &sb);
218 // We assume that cap_get_file returning NULL implies ENODATA
219 if (sb.st_mode & (S_ISUID|S_ISGID) && cap_get_file(exe)) {
220 sway_log(L_ERROR,
221 "sway executable has both the s(g)uid bit AND file caps set.");
222 sway_log(L_ERROR,
223 "This is strongly discouraged (and completely broken).");
224 sway_log(L_ERROR,
225 "Please clear one of them (either the suid bit, or the file caps).");
226 sway_log(L_ERROR,
227 "If unsure, strip the file caps.");
228 exit(EXIT_FAILURE);
229 }
230 free(exe);
231#endif
232}
233
212int main(int argc, char **argv) { 234int main(int argc, char **argv) {
213 static int verbose = 0, debug = 0, validate = 0; 235 static int verbose = 0, debug = 0, validate = 0;
214 236
@@ -288,6 +310,15 @@ int main(int argc, char **argv) {
288 } 310 }
289 } 311 }
290 312
313 // we need to setup logging before wlc_init in case it fails.
314 if (debug) {
315 init_log(L_DEBUG);
316 } else if (verbose || validate) {
317 init_log(L_INFO);
318 } else {
319 init_log(L_ERROR);
320 }
321
291 if (optind < argc) { // Behave as IPC client 322 if (optind < argc) { // Behave as IPC client
292 if(optind != 1) { 323 if(optind != 1) {
293 sway_log(L_ERROR, "Don't use options with the IPC client"); 324 sway_log(L_ERROR, "Don't use options with the IPC client");
@@ -317,6 +348,7 @@ int main(int argc, char **argv) {
317 return 0; 348 return 0;
318 } 349 }
319 350
351 executable_sanity_check();
320#ifdef __linux__ 352#ifdef __linux__
321 bool suid = false; 353 bool suid = false;
322 if (getuid() != geteuid() || getgid() != getegid()) { 354 if (getuid() != geteuid() || getgid() != getegid()) {
@@ -329,14 +361,6 @@ int main(int argc, char **argv) {
329 } 361 }
330#endif 362#endif
331 363
332 // we need to setup logging before wlc_init in case it fails.
333 if (debug) {
334 init_log(L_DEBUG);
335 } else if (verbose || validate) {
336 init_log(L_INFO);
337 } else {
338 init_log(L_ERROR);
339 }
340 wlc_log_set_handler(wlc_log_handler); 364 wlc_log_set_handler(wlc_log_handler);
341 log_kernel(); 365 log_kernel();
342 log_distro(); 366 log_distro();