aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar ಚಿರಾಗ್ ನಟರಾಜ್ <chiraag.nataraj@gmail.com>2018-07-23 19:16:23 -0400
committerLibravatar ಚಿರಾಗ್ ನಟರಾಜ್ <chiraag.nataraj@gmail.com>2018-07-23 19:16:23 -0400
commitfff306c991ff1f33ccb56313e4c166a169555656 (patch)
treeaca84d4befea348bb7fd50c8c7639ace8157f39f /src
parentFix #1638 (diff)
downloadfirejail-fff306c991ff1f33ccb56313e4c166a169555656.tar.gz
firejail-fff306c991ff1f33ccb56313e4c166a169555656.tar.zst
firejail-fff306c991ff1f33ccb56313e4c166a169555656.zip
Add ${MUSIC}, ${VIDEOS}, ${PICTURES}, ${DOCUMENTS}, and ${DESKTOP} (Fixes #259)
Diffstat (limited to 'src')
-rw-r--r--src/firejail/fs_whitelist.c371
-rw-r--r--src/firejail/util.c10
2 files changed, 282 insertions, 99 deletions
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index cddfaa017..bf839b524 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -34,115 +34,158 @@
34//#define TEST_MOUNTINFO 34//#define TEST_MOUNTINFO
35 35
36static char *dentry[] = { 36static char *dentry[] = {
37 "Downloads", 37 "Downloads",
38 "Загрузки", 38 "Загрузки",
39 "Téléchargement", 39 "Téléchargement",
40 NULL 40 NULL
41}; 41};
42 42
43#define EMPTY_STRING ("") 43static char *mentry[] = {
44#define MAXBUF 4098 44 "Music",
45static char *resolve_downloads(int nowhitelist_flag) { 45 "Музыка",
46 EUID_ASSERT(); 46 "Musique",
47 char *fname; 47 NULL
48 struct stat s; 48};
49
50 // try a name from ~/.config/user-dirs.dirs
51 if (asprintf(&fname, "%s/.config/user-dirs.dirs", cfg.homedir) == -1)
52 errExit("asprintf");
53 FILE *fp = fopen(fname, "r");
54 if (!fp) {
55 free(fname);
56 return NULL;
57 }
58 free(fname);
59
60 // extract downloads directory
61 char buf[MAXBUF];
62 while (fgets(buf, MAXBUF, fp)) {
63 char *ptr = buf;
64 49
65 // skip blanks 50static char *ventry[] = {
66 while (*ptr == ' ' || *ptr == '\t') 51 "Videos",
67 ptr++; 52 "Видео",
68 if (*ptr == '\0' || *ptr == '\n' || *ptr == '#') 53 "Vidéos",
69 continue; 54 NULL
55};
70 56
71 if (strncmp(ptr, "XDG_DOWNLOAD_DIR=\"$HOME/", 24) == 0) { 57static char *pentry[] = {
72 char *ptr1 = ptr + 24; 58 "Pictures",
73 char *ptr2 = strchr(ptr1, '"'); 59 "Изображения",
74 if (ptr2) { 60 "Photos",
75 fclose(fp); 61 NULL
76 *ptr2 = '\0'; 62};
77 if (arg_debug || arg_debug_whitelists)
78 printf("extracted %s from ~/.config/user-dirs.dirs\n", ptr1);
79 if (strlen(ptr1) != 0) {
80 if (arg_debug || arg_debug_whitelists)
81 printf("Downloads directory resolved as \"%s\"\n", ptr1);
82
83 if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1)
84 errExit("asprintf");
85
86 if (stat(fname, &s) == -1) {
87 free(fname);
88 goto errout;
89 }
90
91 char *rv;
92 if (nowhitelist_flag) {
93 if (asprintf(&rv, "nowhitelist ~/%s", ptr + 24) == -1)
94 errExit("asprintf");
95 }
96 else {
97 if (asprintf(&rv, "whitelist ~/%s", ptr + 24) == -1)
98 errExit("asprintf");
99 }
100 return rv;
101 }
102 else
103 goto errout;
104 }
105 }
106 }
107 63
108 // try a well known download directory name 64static char *deentry[] = {
109 int i = 0; 65 "Desktop",
110 while (dentry[i] != NULL) { 66 "Рабочий стол",
111 if (asprintf(&fname, "%s/%s", cfg.homedir, dentry[i]) == -1) 67 "Bureau",
112 errExit("asprintf"); 68 NULL
69};
113 70
114 if (stat(fname, &s) == 0) { 71static char *doentry[] = {
115 if (arg_debug || arg_debug_whitelists) 72 "Documents",
116 printf("Downloads directory resolved as \"%s\"\n", fname); 73 "Документы",
74 "Documents",
75 NULL
76};
117 77
118 char *rv; 78#define EMPTY_STRING ("")
119 if (nowhitelist_flag) { 79#define MAXBUF 4098
120 if (asprintf(&rv, "nowhitelist ~/%s", dentry[i]) == -1)
121 errExit("asprintf");
122 }
123 else {
124 if (asprintf(&rv, "whitelist ~/%s", dentry[i]) == -1)
125 errExit("asprintf");
126 }
127 free(fname);
128 return rv;
129 }
130 free(fname);
131 i++;
132 }
133 80
81static char *resolve_xdg(int nowhitelist_flag, const char *var, size_t length, const char *prnt) {
82 EUID_ASSERT();
83 char *fname;
84 struct stat s;
85
86 if (asprintf(&fname, "%s/.config/user-dirs.dirs", cfg.homedir) == -1)
87 errExit("asprintf");
88 FILE *fp = fopen(fname, "r");
89 if (!fp) {
90 free(fname);
91 return NULL;
92 }
93 free(fname);
94
95 char buf[MAXBUF];
96 while (fgets(buf, MAXBUF, fp)) {
97 char *ptr = buf;
98
99 // skip blanks
100 while (*ptr == ' ' || *ptr == '\t')
101 ptr++;
102 if (*ptr == '\0' || *ptr == '\n' || *ptr == '#')
103 continue;
104
105 if (strncmp(ptr, var, length) == 0) {
106 char *ptr1 = ptr + length;
107 char *ptr2 = strchr(ptr1, '"');
108 if (ptr2) {
134 fclose(fp); 109 fclose(fp);
135 return NULL; 110 *ptr2 = '\0';
136 111 if (arg_debug || arg_debug_whitelists)
137errout: 112 printf("extracted %s from ~/.config/user-dirs.dirs\n", ptr1);
138 if (!arg_private) { 113 if (strlen(ptr1) != 0) {
139 fprintf(stderr, "***\n"); 114 if (arg_debug || arg_debug_whitelists)
140 fprintf(stderr, "*** Error: Downloads directory was not found in user home.\n"); 115 printf("%s ",prnt);
141 fprintf(stderr, "*** \tAny files saved by the program, will be lost when the sandbox is closed.\n"); 116 printf("directory resolved as \"%s\"\n", ptr1);
142 fprintf(stderr, "***\n"); 117
118 if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1)
119 errExit("asprintf");
120
121 if (stat(fname, &s) == -1) {
122 free(fname);
123 goto errout;
124 }
125
126 char *rv;
127 if (nowhitelist_flag) {
128 if (asprintf(&rv, "nowhitelist ~/%s", ptr + length) == -1)
129 errExit("asprintf");
130 }
131 else {
132 if (asprintf(&rv, "whitelist ~/%s", ptr + length) == -1)
133 errExit("asprintf");
134 }
135 return rv;
143 } 136 }
137 else
138 goto errout;
139 }
140 }
141 }
142
143 fclose(fp);
144 return NULL;
145
146 errout:
147 if (!arg_private) {
148 fprintf(stderr, "***\n");
149 fprintf(stderr, "*** Error: %s directory was not found in user home.\n",prnt);
150 fprintf(stderr, "*** \tAny files saved by the program, will be lost when the sandbox is closed.\n");
151 fprintf(stderr, "***\n");
152 }
153 return NULL;
154}
144 155
145 return NULL; 156static char *resolve_hardcoded(int nowhitelist_flag, char *entries[], const char *prnt) {
157 EUID_ASSERT();
158 char *fname;
159 struct stat s;
160
161 int i = 0;
162 while (entries[i] != NULL) {
163 if (asprintf(&fname, "%s/%s", cfg.homedir, entries[i]) == -1)
164 errExit("asprintf");
165
166 if (stat(fname, &s) == 0) {
167 if (arg_debug || arg_debug_whitelists) {
168 printf("%s ", prnt);
169 printf("directory resolved as \"%s\"\n", fname);
170 }
171
172 char *rv;
173 if (nowhitelist_flag) {
174 if (asprintf(&rv, "nowhitelist ~/%s", entries[i]) == -1)
175 errExit("asprintf");
176 }
177 else {
178 if (asprintf(&rv, "whitelist ~/%s", entries[i]) == -1)
179 errExit("asprintf");
180 }
181 free(fname);
182 return rv;
183 }
184 free(fname);
185 i++;
186 }
187
188 return NULL;
146} 189}
147 190
148static int mkpath(const char* path, mode_t mode) { 191static int mkpath(const char* path, mode_t mode) {
@@ -424,11 +467,16 @@ void fs_whitelist(void) {
424 467
425 // resolve ${DOWNLOADS} 468 // resolve ${DOWNLOADS}
426 if (strcmp(dataptr, "${DOWNLOADS}") == 0) { 469 if (strcmp(dataptr, "${DOWNLOADS}") == 0) {
427 char *tmp = resolve_downloads(nowhitelist_flag); 470 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads");
471 char *tmp2 = resolve_hardcoded(nowhitelist_flag, dentry, "Downloads");
428 if (tmp) { 472 if (tmp) {
429 entry->data = tmp; 473 entry->data = tmp;
430 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 474 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
431 } 475 }
476 else if (tmp2) {
477 entry->data = tmp2;
478 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
479 }
432 else { 480 else {
433 if (!nowhitelist_flag && !arg_quiet && !arg_private) { 481 if (!nowhitelist_flag && !arg_quiet && !arg_private) {
434 fprintf(stderr, "***\n"); 482 fprintf(stderr, "***\n");
@@ -442,6 +490,131 @@ void fs_whitelist(void) {
442 } 490 }
443 } 491 }
444 492
493 // resolve ${MUSIC}
494 if (strcmp(dataptr, "${MUSIC}") == 0) {
495 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_MUSIC_DIR=\"$HOME/", 21, "Music");
496 char *tmp2 = resolve_hardcoded(nowhitelist_flag, mentry, "Music");
497 if (tmp) {
498 entry->data = tmp;
499 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
500 }
501 else if (tmp2) {
502 entry->data = tmp2;
503 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
504 }
505 else {
506 if (!nowhitelist_flag && !arg_quiet && !arg_private) {
507 fprintf(stderr, "***\n");
508 fprintf(stderr, "*** Warning: cannot whitelist Music directory\n");
509 fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
510 fprintf(stderr, "*** \tPlease create a proper Music directory for your application.\n");
511 fprintf(stderr, "***\n");
512 }
513 entry->data = EMPTY_STRING;
514 continue;
515 }
516 }
517
518 // resolve ${VIDEOS}
519 if (strcmp(dataptr, "${VIDEOS}") == 0) {
520 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos");
521 char *tmp2 = resolve_hardcoded(nowhitelist_flag, ventry, "Videos");
522 if (tmp) {
523 entry->data = tmp;
524 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
525 }
526 else if (tmp2) {
527 entry->data = tmp2;
528 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
529 }
530 else {
531 if (!nowhitelist_flag && !arg_quiet && !arg_private) {
532 fprintf(stderr, "***\n");
533 fprintf(stderr, "*** Warning: cannot whitelist Videos directory\n");
534 fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
535 fprintf(stderr, "*** \tPlease create a proper Videos directory for your application.\n");
536 fprintf(stderr, "***\n");
537 }
538 entry->data = EMPTY_STRING;
539 continue;
540 }
541 }
542
543 // resolve ${PICTURES}
544 if (strcmp(dataptr, "${PICTURES}") == 0) {
545 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures");
546 char *tmp2 = resolve_hardcoded(nowhitelist_flag, pentry, "Pictures");
547 if (tmp) {
548 entry->data = tmp;
549 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
550 }
551 else if (tmp2) {
552 entry->data = tmp2;
553 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
554 }
555 else {
556 if (!nowhitelist_flag && !arg_quiet && !arg_private) {
557 fprintf(stderr, "***\n");
558 fprintf(stderr, "*** Warning: cannot whitelist Pictures directory\n");
559 fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
560 fprintf(stderr, "*** \tPlease create a proper Pictures directory for your application.\n");
561 fprintf(stderr, "***\n");
562 }
563 entry->data = EMPTY_STRING;
564 continue;
565 }
566 }
567
568 // resolve ${DESKTOP}
569 if (strcmp(dataptr, "${DESKTOP}") == 0) {
570 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop");
571 char *tmp2 = resolve_hardcoded(nowhitelist_flag, deentry, "Desktop");
572 if (tmp) {
573 entry->data = tmp;
574 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
575 }
576 else if (tmp2) {
577 entry->data = tmp2;
578 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
579 }
580 else {
581 if (!nowhitelist_flag && !arg_quiet && !arg_private) {
582 fprintf(stderr, "***\n");
583 fprintf(stderr, "*** Warning: cannot whitelist Desktop directory\n");
584 fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
585 fprintf(stderr, "*** \tPlease create a proper Desktop directory for your application.\n");
586 fprintf(stderr, "***\n");
587 }
588 entry->data = EMPTY_STRING;
589 continue;
590 }
591 }
592
593 // resolve ${DOCUMENTS}
594 if (strcmp(dataptr, "${DOCUMENTS}") == 0) {
595 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_DOCUMENTS_DIR=\"$HOME/", 25, "Documents");
596 char *tmp2 = resolve_hardcoded(nowhitelist_flag, doentry, "Documents");
597 if (tmp) {
598 entry->data = tmp;
599 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
600 }
601 else if (tmp2) {
602 entry->data = tmp2;
603 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
604 }
605 else {
606 if (!nowhitelist_flag && !arg_quiet && !arg_private) {
607 fprintf(stderr, "***\n");
608 fprintf(stderr, "*** Warning: cannot whitelist Documents directory\n");
609 fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
610 fprintf(stderr, "*** \tPlease create a proper Documents directory for your application.\n");
611 fprintf(stderr, "***\n");
612 }
613 entry->data = EMPTY_STRING;
614 continue;
615 }
616 }
617
445 // replace ~/ or ${HOME} into /home/username 618 // replace ~/ or ${HOME} into /home/username
446 new_name = expand_home(dataptr, cfg.homedir); 619 new_name = expand_home(dataptr, cfg.homedir);
447 assert(new_name); 620 assert(new_name);
diff --git a/src/firejail/util.c b/src/firejail/util.c
index f634ff700..fa32ffcc8 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -826,6 +826,16 @@ void invalid_filename(const char *fname, int globbing) {
826 ptr = fname + 7; 826 ptr = fname + 7;
827 else if (strcmp(fname, "${DOWNLOADS}") == 0) 827 else if (strcmp(fname, "${DOWNLOADS}") == 0)
828 return; 828 return;
829 else if (strcmp(fname, "${MUSIC}") == 0)
830 return;
831 else if (strcmp(fname, "${VIDEOS}") == 0)
832 return;
833 else if (strcmp(fname, "${PICTURES}") == 0)
834 return;
835 else if (strcmp(fname, "${DESKTOP}") == 0)
836 return;
837 else if (strcmp(fname, "${DOCUMENTS}") == 0)
838 return;
829 839
830 int len = strlen(ptr); 840 int len = strlen(ptr);
831 841