diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fcopy/main.c | 10 | ||||
-rw-r--r-- | src/firejail/fs_lib.c | 6 | ||||
-rw-r--r-- | src/firejail/macros.c | 43 | ||||
-rw-r--r-- | src/fnetfilter/main.c | 5 | ||||
-rw-r--r-- | src/include/common.h | 5 | ||||
-rw-r--r-- | src/lib/common.c | 60 |
6 files changed, 73 insertions, 56 deletions
diff --git a/src/fcopy/main.c b/src/fcopy/main.c index c64d20127..e56d853c8 100644 --- a/src/fcopy/main.c +++ b/src/fcopy/main.c | |||
@@ -472,18 +472,12 @@ int main(int argc, char **argv) { | |||
472 | size_t len = strlen(src); | 472 | size_t len = strlen(src); |
473 | while (len > 1 && src[len - 1] == '/') | 473 | while (len > 1 && src[len - 1] == '/') |
474 | src[--len] = '\0'; | 474 | src[--len] = '\0'; |
475 | if (strcspn(src, "\\*&!?\"'<>%^(){}[];,") != len) { | 475 | reject_meta_chars(src, 0); |
476 | fprintf(stderr, "Error fcopy: invalid source file name %s\n", src); | ||
477 | exit(1); | ||
478 | } | ||
479 | 476 | ||
480 | len = strlen(dest); | 477 | len = strlen(dest); |
481 | while (len > 1 && dest[len - 1] == '/') | 478 | while (len > 1 && dest[len - 1] == '/') |
482 | dest[--len] = '\0'; | 479 | dest[--len] = '\0'; |
483 | if (strcspn(dest, "\\*&!?\"'<>%^(){}[];,~") != len) { | 480 | reject_meta_chars(dest, 0); |
484 | fprintf(stderr, "Error fcopy: invalid dest file name %s\n", dest); | ||
485 | exit(1); | ||
486 | } | ||
487 | 481 | ||
488 | // the destination should be a directory; | 482 | // the destination should be a directory; |
489 | struct stat s; | 483 | struct stat s; |
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index 194a980f4..848691a56 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c | |||
@@ -276,9 +276,9 @@ static void install_list_entry(const char *lib) { | |||
276 | assert(lib); | 276 | assert(lib); |
277 | 277 | ||
278 | // filename check | 278 | // filename check |
279 | int len = strlen(lib); | 279 | reject_meta_chars(lib, 1); |
280 | if (strcspn(lib, "\\&!?\"'<>%^(){}[];,") != (size_t)len || | 280 | |
281 | strstr(lib, "..")) { | 281 | if (strstr(lib, "..")) { |
282 | fprintf(stderr, "Error: \"%s\" is an invalid library\n", lib); | 282 | fprintf(stderr, "Error: \"%s\" is an invalid library\n", lib); |
283 | exit(1); | 283 | exit(1); |
284 | } | 284 | } |
diff --git a/src/firejail/macros.c b/src/firejail/macros.c index 74d529504..3f9460041 100644 --- a/src/firejail/macros.c +++ b/src/firejail/macros.c | |||
@@ -265,28 +265,6 @@ char *expand_macros(const char *path) { | |||
265 | return rv; | 265 | return rv; |
266 | } | 266 | } |
267 | 267 | ||
268 | // replace control characters with a '?' | ||
269 | static char *fix_control_chars(const char *fname) { | ||
270 | assert(fname); | ||
271 | |||
272 | size_t len = strlen(fname); | ||
273 | char *rv = malloc(len + 1); | ||
274 | if (!rv) | ||
275 | errExit("malloc"); | ||
276 | |||
277 | size_t i = 0; | ||
278 | while (fname[i] != '\0') { | ||
279 | if (iscntrl((unsigned char) fname[i])) | ||
280 | rv[i] = '?'; | ||
281 | else | ||
282 | rv[i] = fname[i]; | ||
283 | i++; | ||
284 | } | ||
285 | rv[i] = '\0'; | ||
286 | |||
287 | return rv; | ||
288 | } | ||
289 | |||
290 | void invalid_filename(const char *fname, int globbing) { | 268 | void invalid_filename(const char *fname, int globbing) { |
291 | // EUID_ASSERT(); | 269 | // EUID_ASSERT(); |
292 | assert(fname); | 270 | assert(fname); |
@@ -304,24 +282,5 @@ void invalid_filename(const char *fname, int globbing) { | |||
304 | return; | 282 | return; |
305 | } | 283 | } |
306 | 284 | ||
307 | size_t i = 0; | 285 | reject_meta_chars(ptr, globbing); |
308 | while (ptr[i] != '\0') { | ||
309 | if (iscntrl((unsigned char) ptr[i])) { | ||
310 | char *new = fix_control_chars(fname); | ||
311 | fprintf(stderr, "Error: \"%s\" is an invalid filename: no control characters allowed\n", new); | ||
312 | exit(1); | ||
313 | } | ||
314 | i++; | ||
315 | } | ||
316 | |||
317 | char *reject; | ||
318 | if (globbing) | ||
319 | reject = "\\&!\"<>%^{};,"; // file globbing ('*?[]') is allowed | ||
320 | else | ||
321 | reject = "\\&!?\"<>%^{};,*[]"; | ||
322 | char *c = strpbrk(ptr, reject); | ||
323 | if (c) { | ||
324 | fprintf(stderr, "Error: \"%s\" is an invalid filename: rejected character: \"%c\"\n", fname, *c); | ||
325 | exit(1); | ||
326 | } | ||
327 | } | 286 | } |
diff --git a/src/fnetfilter/main.c b/src/fnetfilter/main.c index 081408ab3..a89e12933 100644 --- a/src/fnetfilter/main.c +++ b/src/fnetfilter/main.c | |||
@@ -187,10 +187,9 @@ printf("\n"); | |||
187 | char *command = (argc == 3)? argv[1]: NULL; | 187 | char *command = (argc == 3)? argv[1]: NULL; |
188 | //printf("command %s\n", command); | 188 | //printf("command %s\n", command); |
189 | //printf("destfile %s\n", destfile); | 189 | //printf("destfile %s\n", destfile); |
190 | |||
190 | // destfile is a real filename | 191 | // destfile is a real filename |
191 | int len = strlen(destfile); | 192 | reject_meta_chars(destfile, 0); |
192 | if (strcspn(destfile, "\\&!?\"'<>%^(){};,*[]") != (size_t)len) | ||
193 | err_exit_cannot_open_file(destfile); | ||
194 | 193 | ||
195 | // handle default config (command = NULL, destfile) | 194 | // handle default config (command = NULL, destfile) |
196 | if (command == NULL) { | 195 | if (command == NULL) { |
diff --git a/src/include/common.h b/src/include/common.h index f72ec9738..c9640435a 100644 --- a/src/include/common.h +++ b/src/include/common.h | |||
@@ -140,6 +140,11 @@ char *pid_proc_comm(const pid_t pid); | |||
140 | char *pid_proc_cmdline(const pid_t pid); | 140 | char *pid_proc_cmdline(const pid_t pid); |
141 | int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid); | 141 | int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid); |
142 | int pid_hidepid(void); | 142 | int pid_hidepid(void); |
143 | char *do_replace_cntrl_chars(char *str, char c); | ||
144 | char *replace_cntrl_chars(const char *str, char c); | ||
145 | int has_cntrl_chars(const char *str); | ||
146 | void reject_cntrl_chars(const char *fname); | ||
147 | void reject_meta_chars(const char *fname, int globbing); | ||
143 | void warn_dumpable(void); | 148 | void warn_dumpable(void); |
144 | const char *gnu_basename(const char *path); | 149 | const char *gnu_basename(const char *path); |
145 | int *str_to_int_array(const char *str, size_t *sz); | 150 | int *str_to_int_array(const char *str, size_t *sz); |
diff --git a/src/lib/common.c b/src/lib/common.c index 91d5125b1..8e84fab26 100644 --- a/src/lib/common.c +++ b/src/lib/common.c | |||
@@ -321,6 +321,66 @@ const char *gnu_basename(const char *path) { | |||
321 | return last_slash+1; | 321 | return last_slash+1; |
322 | } | 322 | } |
323 | 323 | ||
324 | char *do_replace_cntrl_chars(char *str, char c) { | ||
325 | if (str) { | ||
326 | size_t i; | ||
327 | for (i = 0; str[i]; i++) { | ||
328 | if (iscntrl((unsigned char) str[i])) | ||
329 | str[i] = c; | ||
330 | } | ||
331 | } | ||
332 | return str; | ||
333 | } | ||
334 | |||
335 | char *replace_cntrl_chars(const char *str, char c) { | ||
336 | assert(str); | ||
337 | |||
338 | char *rv = strdup(str); | ||
339 | if (!rv) | ||
340 | errExit("strdup"); | ||
341 | |||
342 | do_replace_cntrl_chars(rv, c); | ||
343 | return rv; | ||
344 | } | ||
345 | |||
346 | int has_cntrl_chars(const char *str) { | ||
347 | assert(str); | ||
348 | |||
349 | size_t i; | ||
350 | for (i = 0; str[i]; i++) { | ||
351 | if (iscntrl((unsigned char) str[i])) | ||
352 | return 1; | ||
353 | } | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | void reject_cntrl_chars(const char *fname) { | ||
358 | assert(fname); | ||
359 | |||
360 | if (has_cntrl_chars(fname)) { | ||
361 | char *fname_print = replace_cntrl_chars(fname, '?'); | ||
362 | |||
363 | fprintf(stderr, "Error: \"%s\" is an invalid filename: no control characters are allowed\n", fname_print); | ||
364 | exit(1); | ||
365 | } | ||
366 | } | ||
367 | |||
368 | void reject_meta_chars(const char *fname, int globbing) { | ||
369 | assert(fname); | ||
370 | |||
371 | reject_cntrl_chars(fname); | ||
372 | |||
373 | const char *reject = "\\&!?\"<>%^{};,*[]"; | ||
374 | if (globbing) | ||
375 | reject = "\\&!\"<>%^{};,"; // file globbing ('*?[]') is allowed | ||
376 | |||
377 | const char *c = strpbrk(fname, reject); | ||
378 | if (c) { | ||
379 | fprintf(stderr, "Error: \"%s\" is an invalid filename: rejected character: \"%c\"\n", fname, *c); | ||
380 | exit(1); | ||
381 | } | ||
382 | } | ||
383 | |||
324 | // takes string with comma separated int values, returns int array | 384 | // takes string with comma separated int values, returns int array |
325 | int *str_to_int_array(const char *str, size_t *sz) { | 385 | int *str_to_int_array(const char *str, size_t *sz) { |
326 | assert(str && sz); | 386 | assert(str && sz); |