diff options
author | Aleksey Manevich <manevich.aleksey@gmail.com> | 2016-02-10 13:40:30 +0200 |
---|---|---|
committer | Aleksey Manevich <manevich.aleksey@gmail.com> | 2016-02-10 13:40:30 +0200 |
commit | d4e6b2e16866fa74acc5ba491e3b862e8a634dd4 (patch) | |
tree | 82c9bfb67bbf45d83fd243c7fe67cdef2818b56e /src/libtracelog/libtracelog.c | |
parent | whitelisting ~/.pki in Firefox, Crome/Cromium, Opera (diff) | |
download | firejail-d4e6b2e16866fa74acc5ba491e3b862e8a634dd4.tar.gz firejail-d4e6b2e16866fa74acc5ba491e3b862e8a634dd4.tar.zst firejail-d4e6b2e16866fa74acc5ba491e3b862e8a634dd4.zip |
Fix problem with relative path in storage_find function
storage_find function fails on relative path, so nothing reported to log when blacklisted file accessed by relative path.
This is because CWD is NULL when realpath function called.
How to reproduce:
touch /home/user/somefile
firejail --blacklist=somefile --tracelog cat somefile
Solution: keep CWD value and set it before calling realpath. In order to do this:
* new wrapper for chdir call, and variable to keep CWD added.
* storage_find modified to chdir before calling realpath function.
* order of storage_find and orig_* calls in syscall wrappers changed,
to prevent error set by calls in storage_find leak outside.
* condition for calling realpath changed to include double-slash
and path without initial slash.
Diffstat (limited to 'src/libtracelog/libtracelog.c')
-rw-r--r-- | src/libtracelog/libtracelog.c | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/src/libtracelog/libtracelog.c b/src/libtracelog/libtracelog.c index 3ba47afdb..c3fd40a67 100644 --- a/src/libtracelog/libtracelog.c +++ b/src/libtracelog/libtracelog.c | |||
@@ -91,6 +91,9 @@ static void storage_add(const char *str) { | |||
91 | storage[h] = ptr; | 91 | storage[h] = ptr; |
92 | } | 92 | } |
93 | 93 | ||
94 | char* cwd = NULL; // global variable for keeping current working directory | ||
95 | typedef int (*orig_chdir_t)(const char *pathname); | ||
96 | static orig_chdir_t orig_chdir = NULL; | ||
94 | static char *storage_find(const char *str) { | 97 | static char *storage_find(const char *str) { |
95 | #ifdef DEBUG | 98 | #ifdef DEBUG |
96 | printf("storage find %s\n", str); | 99 | printf("storage find %s\n", str); |
@@ -98,18 +101,27 @@ static char *storage_find(const char *str) { | |||
98 | if (!str) { | 101 | if (!str) { |
99 | #ifdef DEBUG | 102 | #ifdef DEBUG |
100 | printf("null pointer passed to storage_find\n"); | 103 | printf("null pointer passed to storage_find\n"); |
101 | #endif | 104 | #endif |
102 | return NULL; | 105 | return NULL; |
103 | } | 106 | } |
104 | const char *tofind = str; | 107 | const char *tofind = str; |
105 | int allocated = 0; | 108 | int allocated = 0; |
106 | 109 | ||
107 | if (strstr(str, "..") || strstr(str, "/./")) { | 110 | if (strstr(str, "..") || strstr(str, "/./") || strstr(str, "//") || str[0]!='/') { |
111 | if (!orig_chdir) | ||
112 | orig_chdir = (orig_chdir_t)dlsym(RTLD_NEXT, "chdir"); | ||
113 | if (!orig_chdir(cwd)) { | ||
114 | #ifdef DEBUG | ||
115 | printf("chdir failed\n"); | ||
116 | #endif | ||
117 | return NULL; | ||
118 | } | ||
119 | |||
108 | tofind = realpath(str, NULL); | 120 | tofind = realpath(str, NULL); |
109 | if (!tofind) { | 121 | if (!tofind) { |
110 | #ifdef DEBUG | 122 | #ifdef DEBUG |
111 | printf("realpath failed\n"); | 123 | printf("realpath failed\n"); |
112 | #endif | 124 | #endif |
113 | return NULL; | 125 | return NULL; |
114 | } | 126 | } |
115 | allocated = 1; | 127 | allocated = 1; |
@@ -296,9 +308,9 @@ int open(const char *pathname, int flags, mode_t mode) { | |||
296 | if (!blacklist_loaded) | 308 | if (!blacklist_loaded) |
297 | load_blacklist(); | 309 | load_blacklist(); |
298 | 310 | ||
299 | int rv = orig_open(pathname, flags, mode); | ||
300 | if (storage_find(pathname)) | 311 | if (storage_find(pathname)) |
301 | sendlog(name(), __FUNCTION__, pathname); | 312 | sendlog(name(), __FUNCTION__, pathname); |
313 | int rv = orig_open(pathname, flags, mode); | ||
302 | return rv; | 314 | return rv; |
303 | } | 315 | } |
304 | 316 | ||
@@ -317,9 +329,9 @@ int open64(const char *pathname, int flags, mode_t mode) { | |||
317 | if (!blacklist_loaded) | 329 | if (!blacklist_loaded) |
318 | load_blacklist(); | 330 | load_blacklist(); |
319 | 331 | ||
320 | int rv = orig_open64(pathname, flags, mode); | ||
321 | if (storage_find(pathname)) | 332 | if (storage_find(pathname)) |
322 | sendlog(name(), __FUNCTION__, pathname); | 333 | sendlog(name(), __FUNCTION__, pathname); |
334 | int rv = orig_open64(pathname, flags, mode); | ||
323 | return rv; | 335 | return rv; |
324 | } | 336 | } |
325 | //#endif | 337 | //#endif |
@@ -337,9 +349,9 @@ int openat(int dirfd, const char *pathname, int flags, mode_t mode) { | |||
337 | if (!blacklist_loaded) | 349 | if (!blacklist_loaded) |
338 | load_blacklist(); | 350 | load_blacklist(); |
339 | 351 | ||
340 | int rv = orig_openat(dirfd, pathname, flags, mode); | ||
341 | if (storage_find(pathname)) | 352 | if (storage_find(pathname)) |
342 | sendlog(name(), __FUNCTION__, pathname); | 353 | sendlog(name(), __FUNCTION__, pathname); |
354 | int rv = orig_openat(dirfd, pathname, flags, mode); | ||
343 | return rv; | 355 | return rv; |
344 | } | 356 | } |
345 | 357 | ||
@@ -354,9 +366,9 @@ int openat64(int dirfd, const char *pathname, int flags, mode_t mode) { | |||
354 | if (!blacklist_loaded) | 366 | if (!blacklist_loaded) |
355 | load_blacklist(); | 367 | load_blacklist(); |
356 | 368 | ||
357 | int rv = orig_openat64(dirfd, pathname, flags, mode); | ||
358 | if (storage_find(pathname)) | 369 | if (storage_find(pathname)) |
359 | sendlog(name(), __FUNCTION__, pathname); | 370 | sendlog(name(), __FUNCTION__, pathname); |
371 | int rv = orig_openat64(dirfd, pathname, flags, mode); | ||
360 | return rv; | 372 | return rv; |
361 | } | 373 | } |
362 | 374 | ||
@@ -371,9 +383,9 @@ FILE *fopen(const char *pathname, const char *mode) { | |||
371 | if (!blacklist_loaded) | 383 | if (!blacklist_loaded) |
372 | load_blacklist(); | 384 | load_blacklist(); |
373 | 385 | ||
374 | FILE *rv = orig_fopen(pathname, mode); | ||
375 | if (storage_find(pathname)) | 386 | if (storage_find(pathname)) |
376 | sendlog(name(), __FUNCTION__, pathname); | 387 | sendlog(name(), __FUNCTION__, pathname); |
388 | FILE *rv = orig_fopen(pathname, mode); | ||
377 | return rv; | 389 | return rv; |
378 | } | 390 | } |
379 | 391 | ||
@@ -387,9 +399,9 @@ FILE *fopen64(const char *pathname, const char *mode) { | |||
387 | if (!blacklist_loaded) | 399 | if (!blacklist_loaded) |
388 | load_blacklist(); | 400 | load_blacklist(); |
389 | 401 | ||
390 | FILE *rv = orig_fopen64(pathname, mode); | ||
391 | if (storage_find(pathname)) | 402 | if (storage_find(pathname)) |
392 | sendlog(name(), __FUNCTION__, pathname); | 403 | sendlog(name(), __FUNCTION__, pathname); |
404 | FILE *rv = orig_fopen64(pathname, mode); | ||
393 | return rv; | 405 | return rv; |
394 | } | 406 | } |
395 | #endif /* __GLIBC__ */ | 407 | #endif /* __GLIBC__ */ |
@@ -407,9 +419,9 @@ FILE *freopen(const char *pathname, const char *mode, FILE *stream) { | |||
407 | if (!blacklist_loaded) | 419 | if (!blacklist_loaded) |
408 | load_blacklist(); | 420 | load_blacklist(); |
409 | 421 | ||
410 | FILE *rv = orig_freopen(pathname, mode, stream); | ||
411 | if (storage_find(pathname)) | 422 | if (storage_find(pathname)) |
412 | sendlog(name(), __FUNCTION__, pathname); | 423 | sendlog(name(), __FUNCTION__, pathname); |
424 | FILE *rv = orig_freopen(pathname, mode, stream); | ||
413 | return rv; | 425 | return rv; |
414 | } | 426 | } |
415 | 427 | ||
@@ -425,9 +437,9 @@ FILE *freopen64(const char *pathname, const char *mode, FILE *stream) { | |||
425 | if (!blacklist_loaded) | 437 | if (!blacklist_loaded) |
426 | load_blacklist(); | 438 | load_blacklist(); |
427 | 439 | ||
428 | FILE *rv = orig_freopen64(pathname, mode, stream); | ||
429 | if (storage_find(pathname)) | 440 | if (storage_find(pathname)) |
430 | sendlog(name(), __FUNCTION__, pathname); | 441 | sendlog(name(), __FUNCTION__, pathname); |
442 | FILE *rv = orig_freopen64(pathname, mode, stream); | ||
431 | return rv; | 443 | return rv; |
432 | } | 444 | } |
433 | #endif /* __GLIBC__ */ | 445 | #endif /* __GLIBC__ */ |
@@ -444,9 +456,9 @@ int unlink(const char *pathname) { | |||
444 | if (!blacklist_loaded) | 456 | if (!blacklist_loaded) |
445 | load_blacklist(); | 457 | load_blacklist(); |
446 | 458 | ||
447 | int rv = orig_unlink(pathname); | ||
448 | if (storage_find(pathname)) | 459 | if (storage_find(pathname)) |
449 | sendlog(name(), __FUNCTION__, pathname); | 460 | sendlog(name(), __FUNCTION__, pathname); |
461 | int rv = orig_unlink(pathname); | ||
450 | return rv; | 462 | return rv; |
451 | } | 463 | } |
452 | 464 | ||
@@ -461,9 +473,9 @@ int unlinkat(int dirfd, const char *pathname, int flags) { | |||
461 | if (!blacklist_loaded) | 473 | if (!blacklist_loaded) |
462 | load_blacklist(); | 474 | load_blacklist(); |
463 | 475 | ||
464 | int rv = orig_unlinkat(dirfd, pathname, flags); | ||
465 | if (storage_find(pathname)) | 476 | if (storage_find(pathname)) |
466 | sendlog(name(), __FUNCTION__, pathname); | 477 | sendlog(name(), __FUNCTION__, pathname); |
478 | int rv = orig_unlinkat(dirfd, pathname, flags); | ||
467 | return rv; | 479 | return rv; |
468 | } | 480 | } |
469 | 481 | ||
@@ -479,9 +491,9 @@ int mkdir(const char *pathname, mode_t mode) { | |||
479 | if (!blacklist_loaded) | 491 | if (!blacklist_loaded) |
480 | load_blacklist(); | 492 | load_blacklist(); |
481 | 493 | ||
482 | int rv = orig_mkdir(pathname, mode); | ||
483 | if (storage_find(pathname)) | 494 | if (storage_find(pathname)) |
484 | sendlog(name(), __FUNCTION__, pathname); | 495 | sendlog(name(), __FUNCTION__, pathname); |
496 | int rv = orig_mkdir(pathname, mode); | ||
485 | return rv; | 497 | return rv; |
486 | } | 498 | } |
487 | 499 | ||
@@ -496,9 +508,9 @@ int mkdirat(int dirfd, const char *pathname, mode_t mode) { | |||
496 | if (!blacklist_loaded) | 508 | if (!blacklist_loaded) |
497 | load_blacklist(); | 509 | load_blacklist(); |
498 | 510 | ||
499 | int rv = orig_mkdirat(dirfd, pathname, mode); | ||
500 | if (storage_find(pathname)) | 511 | if (storage_find(pathname)) |
501 | sendlog(name(), __FUNCTION__, pathname); | 512 | sendlog(name(), __FUNCTION__, pathname); |
513 | int rv = orig_mkdirat(dirfd, pathname, mode); | ||
502 | return rv; | 514 | return rv; |
503 | } | 515 | } |
504 | 516 | ||
@@ -513,9 +525,9 @@ int rmdir(const char *pathname) { | |||
513 | if (!blacklist_loaded) | 525 | if (!blacklist_loaded) |
514 | load_blacklist(); | 526 | load_blacklist(); |
515 | 527 | ||
516 | int rv = orig_rmdir(pathname); | ||
517 | if (storage_find(pathname)) | 528 | if (storage_find(pathname)) |
518 | sendlog(name(), __FUNCTION__, pathname); | 529 | sendlog(name(), __FUNCTION__, pathname); |
530 | int rv = orig_rmdir(pathname); | ||
519 | return rv; | 531 | return rv; |
520 | } | 532 | } |
521 | 533 | ||
@@ -531,9 +543,9 @@ int stat(const char *pathname, struct stat *buf) { | |||
531 | if (!blacklist_loaded) | 543 | if (!blacklist_loaded) |
532 | load_blacklist(); | 544 | load_blacklist(); |
533 | 545 | ||
534 | int rv = orig_stat(pathname, buf); | ||
535 | if (storage_find(pathname)) | 546 | if (storage_find(pathname)) |
536 | sendlog(name(), __FUNCTION__, pathname); | 547 | sendlog(name(), __FUNCTION__, pathname); |
548 | int rv = orig_stat(pathname, buf); | ||
537 | return rv; | 549 | return rv; |
538 | } | 550 | } |
539 | 551 | ||
@@ -549,9 +561,9 @@ int stat64(const char *pathname, struct stat64 *buf) { | |||
549 | if (!blacklist_loaded) | 561 | if (!blacklist_loaded) |
550 | load_blacklist(); | 562 | load_blacklist(); |
551 | 563 | ||
552 | int rv = orig_stat64(pathname, buf); | ||
553 | if (storage_find(pathname)) | 564 | if (storage_find(pathname)) |
554 | sendlog(name(), __FUNCTION__, pathname); | 565 | sendlog(name(), __FUNCTION__, pathname); |
566 | int rv = orig_stat64(pathname, buf); | ||
555 | return rv; | 567 | return rv; |
556 | } | 568 | } |
557 | #endif /* __GLIBC__ */ | 569 | #endif /* __GLIBC__ */ |
@@ -567,9 +579,9 @@ int lstat(const char *pathname, struct stat *buf) { | |||
567 | if (!blacklist_loaded) | 579 | if (!blacklist_loaded) |
568 | load_blacklist(); | 580 | load_blacklist(); |
569 | 581 | ||
570 | int rv = orig_lstat(pathname, buf); | ||
571 | if (storage_find(pathname)) | 582 | if (storage_find(pathname)) |
572 | sendlog(name(), __FUNCTION__, pathname); | 583 | sendlog(name(), __FUNCTION__, pathname); |
584 | int rv = orig_lstat(pathname, buf); | ||
573 | return rv; | 585 | return rv; |
574 | } | 586 | } |
575 | 587 | ||
@@ -585,9 +597,9 @@ int lstat64(const char *pathname, struct stat64 *buf) { | |||
585 | if (!blacklist_loaded) | 597 | if (!blacklist_loaded) |
586 | load_blacklist(); | 598 | load_blacklist(); |
587 | 599 | ||
588 | int rv = orig_lstat64(pathname, buf); | ||
589 | if (storage_find(pathname)) | 600 | if (storage_find(pathname)) |
590 | sendlog(name(), __FUNCTION__, pathname); | 601 | sendlog(name(), __FUNCTION__, pathname); |
602 | int rv = orig_lstat64(pathname, buf); | ||
591 | return rv; | 603 | return rv; |
592 | } | 604 | } |
593 | #endif /* __GLIBC__ */ | 605 | #endif /* __GLIBC__ */ |
@@ -604,9 +616,9 @@ int access(const char *pathname, int mode) { | |||
604 | if (!blacklist_loaded) | 616 | if (!blacklist_loaded) |
605 | load_blacklist(); | 617 | load_blacklist(); |
606 | 618 | ||
607 | int rv = orig_access(pathname, mode); | ||
608 | if (storage_find(pathname)) | 619 | if (storage_find(pathname)) |
609 | sendlog(name(), __FUNCTION__, pathname); | 620 | sendlog(name(), __FUNCTION__, pathname); |
621 | int rv = orig_access(pathname, mode); | ||
610 | return rv; | 622 | return rv; |
611 | } | 623 | } |
612 | 624 | ||
@@ -622,10 +634,31 @@ DIR *opendir(const char *pathname) { | |||
622 | if (!blacklist_loaded) | 634 | if (!blacklist_loaded) |
623 | load_blacklist(); | 635 | load_blacklist(); |
624 | 636 | ||
625 | DIR *rv = orig_opendir(pathname); | ||
626 | if (storage_find(pathname)) | 637 | if (storage_find(pathname)) |
627 | sendlog(name(), __FUNCTION__, pathname); | 638 | sendlog(name(), __FUNCTION__, pathname); |
639 | DIR *rv = orig_opendir(pathname); | ||
628 | return rv; | 640 | return rv; |
629 | } | 641 | } |
630 | 642 | ||
643 | // chdir | ||
644 | // definition of orig_chdir placed before storage_find function | ||
645 | //typedef int (*orig_chdir_t)(const char *pathname); | ||
646 | //static orig_chdir_t orig_chdir = NULL; | ||
647 | int chdir(const char *pathname) { | ||
648 | #ifdef DEBUG | ||
649 | printf("%s %s\n", __FUNCTION__, pathname); | ||
650 | #endif | ||
651 | if (!orig_chdir) | ||
652 | orig_chdir = (orig_chdir_t)dlsym(RTLD_NEXT, "chdir"); | ||
653 | if (!blacklist_loaded) | ||
654 | load_blacklist(); | ||
655 | |||
656 | if (storage_find(pathname)) | ||
657 | sendlog(name(), __FUNCTION__, pathname); | ||
631 | 658 | ||
659 | free(cwd); | ||
660 | cwd = strdup(pathname); | ||
661 | |||
662 | int rv = orig_chdir(pathname); | ||
663 | return rv; | ||
664 | } | ||