aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/firejail/fs_whitelist.c1
-rw-r--r--src/firejail/macros.c123
-rwxr-xr-xtest/fs/fs.sh3
-rw-r--r--test/fs/macro-blacklist.profile6
-rw-r--r--test/fs/macro-readonly.profile6
-rw-r--r--test/fs/macro-whitelist.profile6
-rwxr-xr-xtest/fs/macro.exp174
7 files changed, 209 insertions, 110 deletions
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index a2803ccbc..bfcf9c209 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -35,6 +35,7 @@
35#define EMPTY_STRING ("") 35#define EMPTY_STRING ("")
36#define MAXBUF 4098 36#define MAXBUF 4098
37 37
38// returns mallocated memory
38char *parse_nowhitelist(int nowhitelist_flag, char *ptr1) { 39char *parse_nowhitelist(int nowhitelist_flag, char *ptr1) {
39 char *rv; 40 char *rv;
40 if (nowhitelist_flag) { 41 if (nowhitelist_flag) {
diff --git a/src/firejail/macros.c b/src/firejail/macros.c
index f111802d7..ef8e0cd79 100644
--- a/src/firejail/macros.c
+++ b/src/firejail/macros.c
@@ -69,7 +69,7 @@ Macro macro[] = {
69}; 69};
70 70
71// return -1 if not found 71// return -1 if not found
72int macro_id(const char *name) { 72static int macro_id(const char *name) {
73 int i = 0; 73 int i = 0;
74 while (macro[i].name != NULL) { 74 while (macro[i].name != NULL) {
75 if (strcmp(name, macro[i].name) == 0) 75 if (strcmp(name, macro[i].name) == 0)
@@ -90,6 +90,7 @@ int is_macro(const char *name) {
90 return 0; 90 return 0;
91} 91}
92 92
93// returns mallocated memory
93static char *resolve_xdg(const char *var) { 94static char *resolve_xdg(const char *var) {
94 char *fname; 95 char *fname;
95 struct stat s; 96 struct stat s;
@@ -145,6 +146,7 @@ static char *resolve_xdg(const char *var) {
145 return NULL; 146 return NULL;
146} 147}
147 148
149// returns mallocated memory
148static char *resolve_hardcoded(char *entries[]) { 150static char *resolve_hardcoded(char *entries[]) {
149 char *fname; 151 char *fname;
150 struct stat s; 152 struct stat s;
@@ -156,7 +158,10 @@ static char *resolve_hardcoded(char *entries[]) {
156 158
157 if (stat(fname, &s) == 0) { 159 if (stat(fname, &s) == 0) {
158 free(fname); 160 free(fname);
159 return entries[i]; 161 char *rv = strdup(entries[i]);
162 if (!rv)
163 errExit("strdup");
164 return rv;
160 } 165 }
161 free(fname); 166 free(fname);
162 i++; 167 i++;
@@ -165,6 +170,7 @@ static char *resolve_hardcoded(char *entries[]) {
165 return NULL; 170 return NULL;
166} 171}
167 172
173// returns mallocated memory
168char *resolve_macro(const char *name) { 174char *resolve_macro(const char *name) {
169 char *rv = NULL; 175 char *rv = NULL;
170 int id = macro_id(name); 176 int id = macro_id(name);
@@ -223,121 +229,18 @@ char *expand_home(const char *path, const char *homedir) {
223 EUID_ROOT(); 229 EUID_ROOT();
224 return new_name; 230 return new_name;
225 } 231 }
226#if 0 232 else {
227 else if (strncmp(path, "${DOWNLOADS}", 12) == 0) { 233 char *directory = resolve_macro(path);
228 char *tmp = resolve_xdg("XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads"); 234 if (directory) {
229 char *tmp2 = resolve_hardcoded(dentry, "Downloads"); 235 if (asprintf(&new_name, "%s/%s", cfg.homedir, directory) == -1)
230 if(tmp) {
231 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1)
232 errExit("asprintf");
233 if(called_as_root)
234 EUID_ROOT();
235 return new_name;
236 }
237 else if(tmp2) {
238 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1)
239 errExit("asprintf");
240 if(called_as_root)
241 EUID_ROOT();
242 return new_name;
243 }
244 }
245
246 else if (strncmp(path, "${MUSIC}", 8) == 0) {
247 char *tmp = resolve_xdg("XDG_MUSIC_DIR=\"$HOME/", 21, "Music");
248 char *tmp2 = resolve_hardcoded(mentry, "Music");
249 if(tmp) {
250 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 8) == -1)
251 errExit("asprintf");
252 if(called_as_root)
253 EUID_ROOT();
254 return new_name;
255 }
256 else if(tmp2) {
257 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 8) == -1)
258 errExit("asprintf");
259 if(called_as_root)
260 EUID_ROOT();
261 return new_name;
262 }
263 }
264
265 else if (strncmp(path, "${VIDEOS}", 9) == 0) {
266 char *tmp = resolve_xdg("XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos");
267 char *tmp2 = resolve_hardcoded(ventry, "Videos");
268 if(tmp) {
269 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 9) == -1)
270 errExit("asprintf");
271 if(called_as_root)
272 EUID_ROOT();
273 return new_name;
274 }
275 else if(tmp2) {
276 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 9) == -1)
277 errExit("asprintf");
278 if(called_as_root)
279 EUID_ROOT();
280 return new_name;
281 }
282 }
283
284 else if (strncmp(path, "${PICTURES}", 11) == 0) {
285 char *tmp = resolve_xdg("XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures");
286 char *tmp2 = resolve_hardcoded(pentry, "Pictures");
287 if(tmp) {
288 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 11) == -1)
289 errExit("asprintf");
290 if(called_as_root)
291 EUID_ROOT();
292 return new_name;
293 }
294 else if(tmp2) {
295 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 11) == -1)
296 errExit("asprintf");
297 if(called_as_root)
298 EUID_ROOT();
299 return new_name;
300 }
301 }
302
303 else if (strncmp(path, "${DESKTOP}", 10) == 0) {
304 char *tmp = resolve_xdg("XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop");
305 char *tmp2 = resolve_hardcoded(deentry, "Desktop");
306 if(tmp) {
307 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 10) == -1)
308 errExit("asprintf");
309 if(called_as_root)
310 EUID_ROOT();
311 return new_name;
312 }
313 else if(tmp2) {
314 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 10) == -1)
315 errExit("asprintf"); 236 errExit("asprintf");
316 if(called_as_root) 237 if(called_as_root)
317 EUID_ROOT(); 238 EUID_ROOT();
239 free(directory);
318 return new_name; 240 return new_name;
319 } 241 }
320 } 242 }
321 243
322 else if (strncmp(path, "${DOCUMENTS}", 12) == 0) {
323 char *tmp = resolve_xdg("XDG_DOCUMENTS_DIR=\"$HOME/", 25, "Documents");
324 char *tmp2 = resolve_hardcoded(doentry, "Documents");
325 if(tmp) {
326 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1)
327 errExit("asprintf");
328 if(called_as_root)
329 EUID_ROOT();
330 return new_name;
331 }
332 else if(tmp2) {
333 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1)
334 errExit("asprintf");
335 if(called_as_root)
336 EUID_ROOT();
337 return new_name;
338 }
339 }
340#endif
341 char *rv = strdup(path); 244 char *rv = strdup(path);
342 if (!rv) 245 if (!rv)
343 errExit("strdup"); 246 errExit("strdup");
diff --git a/test/fs/fs.sh b/test/fs/fs.sh
index 774c61750..c1b589c29 100755
--- a/test/fs/fs.sh
+++ b/test/fs/fs.sh
@@ -58,6 +58,9 @@ echo "TESTING: empty private-etc (test/fs/private-etc-empty.exp)"
58echo "TESTING: private-bin (test/fs/private-bin.exp)" 58echo "TESTING: private-bin (test/fs/private-bin.exp)"
59./private-bin.exp 59./private-bin.exp
60 60
61echo "TESTING: macros (test/fs/macro..exp)"
62./macro.exp
63
61echo "TESTING: whitelist empty (test/fs/whitelist-empty.exp)" 64echo "TESTING: whitelist empty (test/fs/whitelist-empty.exp)"
62./whitelist-empty.exp 65./whitelist-empty.exp
63 66
diff --git a/test/fs/macro-blacklist.profile b/test/fs/macro-blacklist.profile
new file mode 100644
index 000000000..2421d1b7c
--- /dev/null
+++ b/test/fs/macro-blacklist.profile
@@ -0,0 +1,6 @@
1blacklist ${VIDEOS}
2blacklist ${DOCUMENTS}
3blacklist ${MUSIC}
4blacklist ${DOWNLOADS}
5blacklist ${PICTURES}
6blacklist ${DESKTOP}
diff --git a/test/fs/macro-readonly.profile b/test/fs/macro-readonly.profile
new file mode 100644
index 000000000..2f3d5bd78
--- /dev/null
+++ b/test/fs/macro-readonly.profile
@@ -0,0 +1,6 @@
1read-only ${VIDEOS}
2read-only ${DOCUMENTS}
3read-only ${MUSIC}
4read-only ${DOWNLOADS}
5read-only ${PICTURES}
6read-only ${DESKTOP}
diff --git a/test/fs/macro-whitelist.profile b/test/fs/macro-whitelist.profile
new file mode 100644
index 000000000..fed7f76fc
--- /dev/null
+++ b/test/fs/macro-whitelist.profile
@@ -0,0 +1,6 @@
1whitelist ${VIDEOS}
2whitelist ${DOCUMENTS}
3whitelist ${MUSIC}
4whitelist ${DOWNLOADS}
5whitelist ${PICTURES}
6whitelist ${DESKTOP}
diff --git a/test/fs/macro.exp b/test/fs/macro.exp
new file mode 100755
index 000000000..8080a8108
--- /dev/null
+++ b/test/fs/macro.exp
@@ -0,0 +1,174 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10
11send -- "firejail --profile=macro-whitelist.profile ls ~\r"
12expect {
13 timeout {puts "TESTING ERROR 0\n";exit}
14 "Child process initialized"
15}
16expect {
17 timeout {puts "TESTING ERROR 1\n";exit}
18 "Desktop"
19}
20expect {
21 timeout {puts "TESTING ERROR 2\n";exit}
22 "Documents"
23}
24expect {
25 timeout {puts "TESTING ERROR 3\n";exit}
26 "Downloads"
27}
28expect {
29 timeout {puts "TESTING ERROR 4\n";exit}
30 "Music"
31}
32expect {
33 timeout {puts "TESTING ERROR 5\n";exit}
34 "Pictures"
35}
36expect {
37 timeout {puts "TESTING ERROR 6\n";exit}
38 "Videos"
39}
40sleep 1
41
42send -- "firejail --profile=macro-blacklist.profile ls ~/Desktop\r"
43expect {
44 timeout {puts "TESTING ERROR 7\n";exit}
45 "Child process initialized"
46}
47expect {
48 timeout {puts "TESTING ERROR 8\n";exit}
49 "Permission denied"
50}
51sleep 1
52
53send -- "firejail --profile=macro-blacklist.profile ls ~/Documents\r"
54expect {
55 timeout {puts "TESTING ERROR 9n";exit}
56 "Child process initialized"
57}
58expect {
59 timeout {puts "TESTING ERROR 10\n";exit}
60 "Permission denied"
61}
62sleep 1
63
64send -- "firejail --profile=macro-blacklist.profile ls ~/Downloads\r"
65expect {
66 timeout {puts "TESTING ERROR 11n";exit}
67 "Child process initialized"
68}
69expect {
70 timeout {puts "TESTING ERROR 12n";exit}
71 "Permission denied"
72}
73sleep 1
74
75send -- "firejail --profile=macro-blacklist.profile ls ~/Music\r"
76expect {
77 timeout {puts "TESTING ERROR 13\n";exit}
78 "Child process initialized"
79}
80expect {
81 timeout {puts "TESTING ERROR 14\n";exit}
82 "Permission denied"
83}
84sleep 1
85
86send -- "firejail --profile=macro-blacklist.profile ls ~/Pictures\r"
87expect {
88 timeout {puts "TESTING ERROR 15\n";exit}
89 "Child process initialized"
90}
91expect {
92 timeout {puts "TESTING ERROR 16\n";exit}
93 "Permission denied"
94}
95sleep 1
96
97send -- "firejail --profile=macro-blacklist.profile ls ~/Videos\r"
98expect {
99 timeout {puts "TESTING ERROR 17\n";exit}
100 "Child process initialized"
101}
102expect {
103 timeout {puts "TESTING ERROR 18\n";exit}
104 "Permission denied"
105}
106sleep 1
107
108send -- "firejail --profile=macro-readonly.profile touch ~/Desktop/blablabla\r"
109expect {
110 timeout {puts "TESTING ERROR 19\n";exit}
111 "Child process initialized"
112}
113expect {
114 timeout {puts "TESTING ERROR 20\n";exit}
115 "Read-only file system"
116}
117sleep 1
118
119send -- "firejail --profile=macro-readonly.profile touch ~/Documents/blablabla\r"
120expect {
121 timeout {puts "TESTING ERROR 21\n";exit}
122 "Child process initialized"
123}
124expect {
125 timeout {puts "TESTING ERROR 22\n";exit}
126 "Read-only file system"
127}
128sleep 1
129
130send -- "firejail --profile=macro-readonly.profile touch ~/Downloads/blablabla\r"
131expect {
132 timeout {puts "TESTING ERROR 23\n";exit}
133 "Child process initialized"
134}
135expect {
136 timeout {puts "TESTING ERROR 24\n";exit}
137 "Read-only file system"
138}
139sleep 1
140
141send -- "firejail --profile=macro-readonly.profile touch ~/Music/blablabla\r"
142expect {
143 timeout {puts "TESTING ERROR 25\n";exit}
144 "Child process initialized"
145}
146expect {
147 timeout {puts "TESTING ERROR 26\n";exit}
148 "Read-only file system"
149}
150sleep 1
151
152send -- "firejail --profile=macro-readonly.profile touch ~/Pictures/blablabla\r"
153expect {
154 timeout {puts "TESTING ERROR 27\n";exit}
155 "Child process initialized"
156}
157expect {
158 timeout {puts "TESTING ERROR 28\n";exit}
159 "Read-only file system"
160}
161sleep 1
162
163send -- "firejail --profile=macro-readonly.profile touch ~/Videos/blablabla\r"
164expect {
165 timeout {puts "TESTING ERROR 29\n";exit}
166 "Child process initialized"
167}
168expect {
169 timeout {puts "TESTING ERROR 30\n";exit}
170 "Read-only file system"
171}
172sleep 1
173
174puts "\nall done\n"