aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/check-c.yml4
-rw-r--r--.github/workflows/check-python.yml4
-rw-r--r--Makefile1
-rw-r--r--RELNOTES6
-rw-r--r--etc/profile-a-l/lutris.profile2
-rw-r--r--src/firecfg/firecfg.h10
-rw-r--r--src/firecfg/main.c145
-rw-r--r--src/firejail/main.c40
-rw-r--r--src/firejail/profile.c8
-rw-r--r--src/man/firecfg.1.in57
10 files changed, 178 insertions, 99 deletions
diff --git a/.github/workflows/check-c.yml b/.github/workflows/check-c.yml
index 496efb76c..3324906f7 100644
--- a/.github/workflows/check-c.yml
+++ b/.github/workflows/check-c.yml
@@ -150,7 +150,7 @@ jobs:
150 150
151 # Initializes the CodeQL tools for scanning. 151 # Initializes the CodeQL tools for scanning.
152 - name: Initialize CodeQL 152 - name: Initialize CodeQL
153 uses: github/codeql-action/init@66b90a5db151a8042fa97405c6cf843bbe433f7b 153 uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75
154 with: 154 with:
155 languages: cpp 155 languages: cpp
156 156
@@ -161,4 +161,4 @@ jobs:
161 run: make -j "$(nproc)" 161 run: make -j "$(nproc)"
162 162
163 - name: Perform CodeQL Analysis 163 - name: Perform CodeQL Analysis
164 uses: github/codeql-action/analyze@66b90a5db151a8042fa97405c6cf843bbe433f7b 164 uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75
diff --git a/.github/workflows/check-python.yml b/.github/workflows/check-python.yml
index 535b9234b..4425af2b7 100644
--- a/.github/workflows/check-python.yml
+++ b/.github/workflows/check-python.yml
@@ -50,9 +50,9 @@ jobs:
50 50
51 # Initializes the CodeQL tools for scanning. 51 # Initializes the CodeQL tools for scanning.
52 - name: Initialize CodeQL 52 - name: Initialize CodeQL
53 uses: github/codeql-action/init@66b90a5db151a8042fa97405c6cf843bbe433f7b 53 uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75
54 with: 54 with:
55 languages: python 55 languages: python
56 56
57 - name: Perform CodeQL Analysis 57 - name: Perform CodeQL Analysis
58 uses: github/codeql-action/analyze@66b90a5db151a8042fa97405c6cf843bbe433f7b 58 uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75
diff --git a/Makefile b/Makefile
index d5ec11ea6..5b9335127 100644
--- a/Makefile
+++ b/Makefile
@@ -235,6 +235,7 @@ endif
235 install -m 0644 -t $(DESTDIR)$(docdir) COPYING README RELNOTES etc/templates/* 235 install -m 0644 -t $(DESTDIR)$(docdir) COPYING README RELNOTES etc/templates/*
236 # profiles and settings 236 # profiles and settings
237 install -m 0755 -d $(DESTDIR)$(sysconfdir)/firejail 237 install -m 0755 -d $(DESTDIR)$(sysconfdir)/firejail
238 install -m 0755 -d $(DESTDIR)$(sysconfdir)/firejail/firecfg.d
238 install -m 0644 -t $(DESTDIR)$(sysconfdir)/firejail src/firecfg/firecfg.config 239 install -m 0644 -t $(DESTDIR)$(sysconfdir)/firejail src/firecfg/firecfg.config
239 install -m 0644 -t $(DESTDIR)$(sysconfdir)/firejail etc/profile-a-l/*.profile etc/profile-m-z/*.profile etc/inc/*.inc etc/net/*.net etc/firejail.config 240 install -m 0644 -t $(DESTDIR)$(sysconfdir)/firejail etc/profile-a-l/*.profile etc/profile-m-z/*.profile etc/inc/*.inc etc/net/*.net etc/firejail.config
240 sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/firejail/login.users ]; then install -c -m 0644 etc/login.users $(DESTDIR)/$(sysconfdir)/firejail/.; fi;" 241 sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/firejail/login.users ]; then install -c -m 0644 etc/login.users $(DESTDIR)/$(sysconfdir)/firejail/.; fi;"
diff --git a/RELNOTES b/RELNOTES
index b81ae74c4..02d9259a9 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -22,12 +22,15 @@ firejail (0.9.73) baseline; urgency=low
22 * modif: improve errExit error messages (#5871) 22 * modif: improve errExit error messages (#5871)
23 * modif: drop deprecated 'shell' option references (#5894) 23 * modif: drop deprecated 'shell' option references (#5894)
24 * modif: keep pipewire group unless nosound is used (#5992 #5993) 24 * modif: keep pipewire group unless nosound is used (#5992 #5993)
25 * modif: Lookup xauth in PATH (#6006 #6087)
25 * bugfix: qutebrowser: links will not open in the existing instance (#5601 26 * bugfix: qutebrowser: links will not open in the existing instance (#5601
26 #5618) 27 #5618)
27 * bugfix: fix --hostname and --hosts-file commands 28 * bugfix: fix --hostname and --hosts-file commands
28 * bugfix: arp.c: ensure positive timeout on select(2) (#5806) 29 * bugfix: arp.c: ensure positive timeout on select(2) (#5806)
29 * bugfix: Wrong syscall names for s390_pci_mmio_read and s390_pci_mmio_write 30 * bugfix: Wrong syscall names for s390_pci_mmio_read and s390_pci_mmio_write
30 (#5965 #5976) 31 (#5965 #5976)
32 * bugfix: firejail --ls reports wrong file sizes for large files (#5982
33 #6086)
31 * build: auto-generate syntax files (#5627) 34 * build: auto-generate syntax files (#5627)
32 * build: mark all phony targets as such (#5637) 35 * build: mark all phony targets as such (#5637)
33 * build: mkdeb.sh: pass all arguments to ./configure (#5654) 36 * build: mkdeb.sh: pass all arguments to ./configure (#5654)
@@ -46,6 +49,7 @@ firejail (0.9.73) baseline; urgency=low
46 * build: firecfg.config sorting improvements (#5942) 49 * build: firecfg.config sorting improvements (#5942)
47 * build: codespell improvements (#5955) 50 * build: codespell improvements (#5955)
48 * build: add missing makefile dep & syntax improvements (#5956) 51 * build: add missing makefile dep & syntax improvements (#5956)
52 * build: sort.py: use case-sensitive sorting (#6070)
49 * ci: always update the package db before installing packages (#5742) 53 * ci: always update the package db before installing packages (#5742)
50 * ci: fix codeql unable to download its own bundle (#5783) 54 * ci: fix codeql unable to download its own bundle (#5783)
51 * ci: split configure/build/install commands on gitlab (#5784) 55 * ci: split configure/build/install commands on gitlab (#5784)
@@ -57,6 +61,8 @@ firejail (0.9.73) baseline; urgency=low
57 * ci: whitelist paths, reorganize workflows & speed-up tests (#5960) 61 * ci: whitelist paths, reorganize workflows & speed-up tests (#5960)
58 * ci: fix dependabot duplicated workflow runs (#5984) 62 * ci: fix dependabot duplicated workflow runs (#5984)
59 * ci: allow running workflows manually (#6026) 63 * ci: allow running workflows manually (#6026)
64 * contrib/syntax: remove 'text/plain' from firejail-profile.lang.in (#6057
65 #6059)
60 * contrib/vim: match profile files more broadly (#5850) 66 * contrib/vim: match profile files more broadly (#5850)
61 * test: split individual test groups in github workflows 67 * test: split individual test groups in github workflows
62 * test: add chroot, appimage and network tests in github workflows 68 * test: add chroot, appimage and network tests in github workflows
diff --git a/etc/profile-a-l/lutris.profile b/etc/profile-a-l/lutris.profile
index 226bc8dde..0462cb503 100644
--- a/etc/profile-a-l/lutris.profile
+++ b/etc/profile-a-l/lutris.profile
@@ -11,6 +11,7 @@ noblacklist ${HOME}/Games
11noblacklist ${HOME}/.cache/lutris 11noblacklist ${HOME}/.cache/lutris
12noblacklist ${HOME}/.cache/wine 12noblacklist ${HOME}/.cache/wine
13noblacklist ${HOME}/.cache/winetricks 13noblacklist ${HOME}/.cache/winetricks
14noblacklist ${HOME}/.config/MangoHud
14noblacklist ${HOME}/.config/lutris 15noblacklist ${HOME}/.config/lutris
15noblacklist ${HOME}/.local/share/lutris 16noblacklist ${HOME}/.local/share/lutris
16#noblacklist ${HOME}/.wine 17#noblacklist ${HOME}/.wine
@@ -45,6 +46,7 @@ whitelist ${HOME}/Games
45whitelist ${HOME}/.cache/lutris 46whitelist ${HOME}/.cache/lutris
46whitelist ${HOME}/.cache/wine 47whitelist ${HOME}/.cache/wine
47whitelist ${HOME}/.cache/winetricks 48whitelist ${HOME}/.cache/winetricks
49whitelist ${HOME}/.config/MangoHud
48whitelist ${HOME}/.config/lutris 50whitelist ${HOME}/.config/lutris
49whitelist ${HOME}/.local/share/lutris 51whitelist ${HOME}/.local/share/lutris
50#whitelist ${HOME}/.wine 52#whitelist ${HOME}/.wine
diff --git a/src/firecfg/firecfg.h b/src/firecfg/firecfg.h
index 8f74a1198..11e3ebc67 100644
--- a/src/firecfg/firecfg.h
+++ b/src/firecfg/firecfg.h
@@ -37,6 +37,16 @@
37#include "../include/common.h" 37#include "../include/common.h"
38#define MAX_BUF 4096 38#define MAX_BUF 4096
39 39
40// config files
41#define FIRECFG_CFGFILE SYSCONFDIR "/firecfg.config"
42#define FIRECFG_CONF_GLOB SYSCONFDIR "/firecfg.d/*.conf"
43
44// programs
45#define FIREJAIL_EXEC PREFIX "/bin/firejail"
46#define FIREJAIL_WELCOME_SH LIBDIR "/firejail/firejail-welcome.sh"
47#define FZENITY_EXEC LIBDIR "/firejail/fzenity"
48#define ZENITY_EXEC "/usr/bin/zenity"
49#define SUDO_EXEC "sudo"
40 50
41// main.c 51// main.c
42extern int arg_debug; 52extern int arg_debug;
diff --git a/src/firecfg/main.c b/src/firecfg/main.c
index 4ec81c5b3..604b12633 100644
--- a/src/firecfg/main.c
+++ b/src/firecfg/main.c
@@ -20,6 +20,8 @@
20 20
21#include "firecfg.h" 21#include "firecfg.h"
22#include "../include/firejail_user.h" 22#include "../include/firejail_user.h"
23#include <glob.h>
24
23int arg_debug = 0; 25int arg_debug = 0;
24char *arg_bindir = "/usr/local/bin"; 26char *arg_bindir = "/usr/local/bin";
25int arg_guide = 0; 27int arg_guide = 0;
@@ -76,10 +78,6 @@ static void list(void) {
76 exit(1); 78 exit(1);
77 } 79 }
78 80
79 char *firejail_exec;
80 if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1)
81 errExit("asprintf");
82
83 struct dirent *entry; 81 struct dirent *entry;
84 while ((entry = readdir(dir)) != NULL) { 82 while ((entry = readdir(dir)) != NULL) {
85 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) 83 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
@@ -92,7 +90,7 @@ static void list(void) {
92 if (is_link(fullname)) { 90 if (is_link(fullname)) {
93 char* fname = realpath(fullname, NULL); 91 char* fname = realpath(fullname, NULL);
94 if (fname) { 92 if (fname) {
95 if (strcmp(fname, firejail_exec) == 0) 93 if (strcmp(fname, FIREJAIL_EXEC) == 0)
96 printf("%s\n", fullname); 94 printf("%s\n", fullname);
97 free(fname); 95 free(fname);
98 } 96 }
@@ -101,7 +99,6 @@ static void list(void) {
101 } 99 }
102 100
103 closedir(dir); 101 closedir(dir);
104 free(firejail_exec);
105} 102}
106 103
107static void clean(void) { 104static void clean(void) {
@@ -114,10 +111,6 @@ static void clean(void) {
114 exit(1); 111 exit(1);
115 } 112 }
116 113
117 char *firejail_exec;
118 if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1)
119 errExit("asprintf");
120
121 struct dirent *entry; 114 struct dirent *entry;
122 while ((entry = readdir(dir)) != NULL) { 115 while ((entry = readdir(dir)) != NULL) {
123 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) 116 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
@@ -130,7 +123,7 @@ static void clean(void) {
130 if (is_link(fullname)) { 123 if (is_link(fullname)) {
131 char* fname = realpath(fullname, NULL); 124 char* fname = realpath(fullname, NULL);
132 if (fname) { 125 if (fname) {
133 if (strcmp(fname, firejail_exec) == 0) { 126 if (strcmp(fname, FIREJAIL_EXEC) == 0) {
134 char *ptr = strrchr(fullname, '/'); 127 char *ptr = strrchr(fullname, '/');
135 assert(ptr); 128 assert(ptr);
136 ptr++; 129 ptr++;
@@ -147,10 +140,43 @@ static void clean(void) {
147 } 140 }
148 141
149 closedir(dir); 142 closedir(dir);
150 free(firejail_exec);
151 printf("\n"); 143 printf("\n");
152} 144}
153 145
146#define ignorelist_maxlen 2048
147static const char *ignorelist[ignorelist_maxlen];
148static int ignorelist_len = 0;
149
150static int append_ignorelist(const char *const str) {
151 assert(str);
152 if (ignorelist_len >= ignorelist_maxlen) {
153 fprintf(stderr, "Warning: Ignore list is full (%d/%d), skipping %s\n",
154 ignorelist_len, ignorelist_maxlen, str);
155 return 0;
156 }
157
158 printf(" ignoring '%s'\n", str);
159 const char *const dup = strdup(str);
160 if (!dup)
161 errExit("strdup");
162
163 ignorelist[ignorelist_len] = dup;
164 ignorelist_len++;
165
166 return 1;
167}
168
169static int in_ignorelist(const char *const str) {
170 assert(str);
171 int i;
172 for (i = 0; i < ignorelist_len; i++) {
173 if (strcmp(str, ignorelist[i]) == 0)
174 return 1;
175 }
176
177 return 0;
178}
179
154static void set_file(const char *name, const char *firejail_exec) { 180static void set_file(const char *name, const char *firejail_exec) {
155 if (which(name) == 0) 181 if (which(name) == 0)
156 return; 182 return;
@@ -165,35 +191,26 @@ static void set_file(const char *name, const char *firejail_exec) {
165 if (rv) { 191 if (rv) {
166 fprintf(stderr, "Error: cannot create %s symbolic link\n", fname); 192 fprintf(stderr, "Error: cannot create %s symbolic link\n", fname);
167 perror("symlink"); 193 perror("symlink");
168 } 194 } else {
169 else
170 printf(" %s created\n", name); 195 printf(" %s created\n", name);
171 } 196 }
172 else { 197 } else {
173 fprintf(stderr, "Warning: cannot create %s - already exists! Skipping...\n", fname); 198 fprintf(stderr, "Warning: cannot create %s - already exists! Skipping...\n", fname);
174 } 199 }
175 200
176 free(fname); 201 free(fname);
177} 202}
178 203
179// parse /etc/firejail/firecfg.config file 204// parse a single config file
180static void set_links_firecfg(void) { 205static void set_links_firecfg(const char *cfgfile) {
181 char *cfgfile; 206 printf("Configuring symlinks in %s based on %s\n", arg_bindir, cfgfile);
182 if (asprintf(&cfgfile, "%s/firecfg.config", SYSCONFDIR) == -1)
183 errExit("asprintf");
184
185 char *firejail_exec;
186 if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1)
187 errExit("asprintf");
188 207
189 // parse /etc/firejail/firecfg.config file
190 FILE *fp = fopen(cfgfile, "r"); 208 FILE *fp = fopen(cfgfile, "r");
191 if (!fp) { 209 if (!fp) {
192 perror("fopen"); 210 perror("fopen");
193 fprintf(stderr, "Error: cannot open %s\n", cfgfile); 211 fprintf(stderr, "Error: cannot open %s\n", cfgfile);
194 exit(1); 212 exit(1);
195 } 213 }
196 printf("Configuring symlinks in %s based on firecfg.config\n", arg_bindir);
197 214
198 char buf[MAX_BUF]; 215 char buf[MAX_BUF];
199 int lineno = 0; 216 int lineno = 0;
@@ -223,13 +240,43 @@ static void set_links_firecfg(void) {
223 if (*start == '\0') 240 if (*start == '\0')
224 continue; 241 continue;
225 242
243 // handle ignore command
244 if (*start == '!') {
245 append_ignorelist(start + 1);
246 continue;
247 }
248
226 // set link 249 // set link
227 set_file(start, firejail_exec); 250 if (!in_ignorelist(start))
251 set_file(start, FIREJAIL_EXEC);
252 else
253 printf(" %s ignored\n", start);
228 } 254 }
229 255
230 fclose(fp); 256 fclose(fp);
231 free(cfgfile); 257 printf("\n");
232 free(firejail_exec); 258}
259
260// parse all config files matching pattern
261static void set_links_firecfg_glob(const char *pattern) {
262 printf("Looking for config files in %s\n", pattern);
263
264 glob_t globbuf;
265 int globerr = glob(pattern, 0, NULL, &globbuf);
266 if (globerr == GLOB_NOMATCH) {
267 fprintf(stderr, "No matches for glob pattern %s\n", pattern);
268 goto out;
269 } else if (globerr != 0) {
270 fprintf(stderr, "Warning: Failed to match glob pattern %s: %s\n",
271 pattern, strerror(errno));
272 goto out;
273 }
274
275 size_t i;
276 for (i = 0; i < globbuf.gl_pathc; i++)
277 set_links_firecfg(globbuf.gl_pathv[i]);
278out:
279 globfree(&globbuf);
233} 280}
234 281
235// parse ~/.config/firejail/ directory 282// parse ~/.config/firejail/ directory
@@ -246,10 +293,6 @@ static void set_links_homedir(const char *homedir) {
246 return; 293 return;
247 } 294 }
248 295
249 char *firejail_exec;
250 if (asprintf(&firejail_exec, "%s/bin/firejail", PREFIX) == -1)
251 errExit("asprintf");
252
253 // parse ~/.config/firejail/ directory 296 // parse ~/.config/firejail/ directory
254 printf("\nConfiguring symlinks in %s based on local firejail config directory\n", arg_bindir); 297 printf("\nConfiguring symlinks in %s based on local firejail config directory\n", arg_bindir);
255 298
@@ -260,6 +303,7 @@ static void set_links_homedir(const char *homedir) {
260 free(dirname); 303 free(dirname);
261 return; 304 return;
262 } 305 }
306 free(dirname);
263 307
264 struct dirent *entry; 308 struct dirent *entry;
265 while ((entry = readdir(dir))) { 309 while ((entry = readdir(dir))) {
@@ -280,12 +324,10 @@ static void set_links_homedir(const char *homedir) {
280 } 324 }
281 325
282 *ptr = '\0'; 326 *ptr = '\0';
283 set_file(exec, firejail_exec); 327 set_file(exec, FIREJAIL_EXEC);
284 free(exec); 328 free(exec);
285 } 329 }
286 closedir(dir); 330 closedir(dir);
287
288 free(firejail_exec);
289} 331}
290 332
291static const char *get_sudo_user(void) { 333static const char *get_sudo_user(void) {
@@ -449,18 +491,20 @@ int main(int argc, char **argv) {
449 } 491 }
450 492
451 if (arg_guide) { 493 if (arg_guide) {
494 const char *zenity_exec;
495 if (arg_debug)
496 zenity_exec = FZENITY_EXEC;
497 else
498 zenity_exec = ZENITY_EXEC;
499
452 char *cmd; 500 char *cmd;
453if (arg_debug) { 501 if (asprintf(&cmd, "%s %s %s %s %s",
454 if (asprintf(&cmd, "sudo %s/firejail/firejail-welcome.sh /usr/lib/firejail/fzenity %s %s", LIBDIR, SYSCONFDIR, user) == -1) 502 SUDO_EXEC, FIREJAIL_WELCOME_SH, zenity_exec, SYSCONFDIR, user) == -1)
455 errExit("asprintf"); 503 errExit("asprintf");
456} 504
457else {
458 if (asprintf(&cmd, "sudo %s/firejail/firejail-welcome.sh /usr/bin/zenity %s %s", LIBDIR, SYSCONFDIR, user) == -1)
459 errExit("asprintf");
460}
461 int status = system(cmd); 505 int status = system(cmd);
462 if (status == -1) { 506 if (status == -1) {
463 fprintf(stderr, "Error: cannot run firejail-welcome.sh\n"); 507 fprintf(stderr, "Error: cannot run %s\n", FIREJAIL_WELCOME_SH);
464 exit(1); 508 exit(1);
465 } 509 }
466 free(cmd); 510 free(cmd);
@@ -474,12 +518,15 @@ else {
474 // clear all symlinks 518 // clear all symlinks
475 clean(); 519 clean();
476 520
477 // set new symlinks based on /etc/firejail/firecfg.config 521 // set new symlinks based on .conf files
478 set_links_firecfg(); 522 set_links_firecfg_glob(FIRECFG_CONF_GLOB);
523
524 // set new symlinks based on firecfg.config
525 set_links_firecfg(FIRECFG_CFGFILE);
479 526
480 if (getuid() == 0) { 527 if (getuid() == 0) {
481 // add user to firejail access database - only for root 528 // add user to firejail access database - only for root
482 printf("\nAdding user %s to Firejail access database in %s/firejail.users\n", user, SYSCONFDIR); 529 printf("Adding user %s to Firejail access database in %s/firejail.users\n", user, SYSCONFDIR);
483 // temporarily set the umask, access database must be world-readable 530 // temporarily set the umask, access database must be world-readable
484 mode_t orig_umask = umask(022); 531 mode_t orig_umask = umask(022);
485 firejail_user_add(user); 532 firejail_user_add(user);
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 0c9c80137..0327f8bda 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -1572,7 +1572,7 @@ int main(int argc, char **argv, char **envp) {
1572 arg_trace = 1; 1572 arg_trace = 1;
1573 else if (strncmp(argv[i], "--trace=", 8) == 0) { 1573 else if (strncmp(argv[i], "--trace=", 8) == 0) {
1574 arg_trace = 1; 1574 arg_trace = 1;
1575 arg_tracefile = argv[i] + 8; 1575 arg_tracefile = expand_macros(argv[i] + 8);
1576 if (*arg_tracefile == '\0') { 1576 if (*arg_tracefile == '\0') {
1577 fprintf(stderr, "Error: invalid trace option\n"); 1577 fprintf(stderr, "Error: invalid trace option\n");
1578 exit(1); 1578 exit(1);
@@ -1582,13 +1582,6 @@ int main(int argc, char **argv, char **envp) {
1582 fprintf(stderr, "Error: invalid file name %s\n", arg_tracefile); 1582 fprintf(stderr, "Error: invalid file name %s\n", arg_tracefile);
1583 exit(1); 1583 exit(1);
1584 } 1584 }
1585 // if the filename starts with ~, expand the home directory
1586 if (*arg_tracefile == '~') {
1587 char *tmp;
1588 if (asprintf(&tmp, "%s%s", cfg.homedir, arg_tracefile + 1) == -1)
1589 errExit("asprintf");
1590 arg_tracefile = tmp;
1591 }
1592 } 1585 }
1593 else if (strcmp(argv[i], "--tracelog") == 0) { 1586 else if (strcmp(argv[i], "--tracelog") == 0) {
1594 if (checkcfg(CFG_TRACELOG)) 1587 if (checkcfg(CFG_TRACELOG))
@@ -1953,20 +1946,13 @@ int main(int argc, char **argv, char **envp) {
1953 } 1946 }
1954 1947
1955 // extract chroot dirname 1948 // extract chroot dirname
1956 cfg.chrootdir = argv[i] + 9; 1949 cfg.chrootdir = expand_macros(argv[i] + 9);
1957 if (*cfg.chrootdir == '\0') { 1950 if (*cfg.chrootdir == '\0') {
1958 fprintf(stderr, "Error: invalid chroot option\n"); 1951 fprintf(stderr, "Error: invalid chroot option\n");
1959 exit(1); 1952 exit(1);
1960 } 1953 }
1961 invalid_filename(cfg.chrootdir, 0); // no globbing 1954 invalid_filename(cfg.chrootdir, 0); // no globbing
1962 1955
1963 // if the directory starts with ~, expand the home directory
1964 if (*cfg.chrootdir == '~') {
1965 char *tmp;
1966 if (asprintf(&tmp, "%s%s", cfg.homedir, cfg.chrootdir + 1) == -1)
1967 errExit("asprintf");
1968 cfg.chrootdir = tmp;
1969 }
1970 // check chroot directory 1956 // check chroot directory
1971 fs_check_chroot_dir(); 1957 fs_check_chroot_dir();
1972 } 1958 }
@@ -2748,16 +2734,7 @@ int main(int argc, char **argv, char **envp) {
2748 else if (strncmp(argv[i], "--netfilter=", 12) == 0) { 2734 else if (strncmp(argv[i], "--netfilter=", 12) == 0) {
2749 if (checkcfg(CFG_NETWORK)) { 2735 if (checkcfg(CFG_NETWORK)) {
2750 arg_netfilter = 1; 2736 arg_netfilter = 1;
2751 arg_netfilter_file = argv[i] + 12; 2737 arg_netfilter_file = expand_macros(argv[i] + 12);
2752
2753 // expand tilde
2754 if (*arg_netfilter_file == '~') {
2755 char *tmp;
2756 if (asprintf(&tmp, "%s%s", cfg.homedir, arg_netfilter_file + 1) == -1)
2757 errExit("asprintf");
2758 arg_netfilter_file = tmp;
2759 }
2760
2761 check_netfilter_file(arg_netfilter_file); 2738 check_netfilter_file(arg_netfilter_file);
2762 } 2739 }
2763 else 2740 else
@@ -2767,16 +2744,7 @@ int main(int argc, char **argv, char **envp) {
2767 else if (strncmp(argv[i], "--netfilter6=", 13) == 0) { 2744 else if (strncmp(argv[i], "--netfilter6=", 13) == 0) {
2768 if (checkcfg(CFG_NETWORK)) { 2745 if (checkcfg(CFG_NETWORK)) {
2769 arg_netfilter6 = 1; 2746 arg_netfilter6 = 1;
2770 arg_netfilter6_file = argv[i] + 13; 2747 arg_netfilter6_file = expand_macros(argv[i] + 13);
2771
2772 // expand tilde
2773 if (*arg_netfilter6_file == '~') {
2774 char *tmp;
2775 if (asprintf(&tmp, "%s%s", cfg.homedir, arg_netfilter6_file + 1) == -1)
2776 errExit("asprintf");
2777 arg_netfilter6_file = tmp;
2778 }
2779
2780 check_netfilter_file(arg_netfilter6_file); 2748 check_netfilter_file(arg_netfilter6_file);
2781 } 2749 }
2782 else 2750 else
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 8cc5c1166..0f60e9b7d 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -635,9 +635,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
635#ifdef HAVE_NETWORK 635#ifdef HAVE_NETWORK
636 if (checkcfg(CFG_NETWORK)) { 636 if (checkcfg(CFG_NETWORK)) {
637 arg_netfilter = 1; 637 arg_netfilter = 1;
638 arg_netfilter_file = strdup(ptr + 10); 638 arg_netfilter_file = expand_macros(ptr + 10);
639 if (!arg_netfilter_file)
640 errExit("strdup");
641 check_netfilter_file(arg_netfilter_file); 639 check_netfilter_file(arg_netfilter_file);
642 } 640 }
643 else 641 else
@@ -649,9 +647,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
649#ifdef HAVE_NETWORK 647#ifdef HAVE_NETWORK
650 if (checkcfg(CFG_NETWORK)) { 648 if (checkcfg(CFG_NETWORK)) {
651 arg_netfilter6 = 1; 649 arg_netfilter6 = 1;
652 arg_netfilter6_file = strdup(ptr + 11); 650 arg_netfilter6_file = expand_macros(ptr + 11);
653 if (!arg_netfilter6_file)
654 errExit("strdup");
655 check_netfilter_file(arg_netfilter6_file); 651 check_netfilter_file(arg_netfilter6_file);
656 } 652 }
657 else 653 else
diff --git a/src/man/firecfg.1.in b/src/man/firecfg.1.in
index a85fbc5da..e43a573de 100644
--- a/src/man/firecfg.1.in
+++ b/src/man/firecfg.1.in
@@ -29,9 +29,13 @@ Note: The examples use \fBsudo\fR, but \fBdoas\fR is also supported.
29To set it up, run "sudo firecfg" after installing Firejail software. 29To set it up, run "sudo firecfg" after installing Firejail software.
30The same command should also be run after 30The same command should also be run after
31installing new programs. If the program is supported by Firejail, the symbolic link in /usr/local/bin 31installing new programs. If the program is supported by Firejail, the symbolic link in /usr/local/bin
32will be created. For a full list of programs supported by default run "cat /etc/firejail/firecfg.config". 32will be created.
33 33.PP
34For user-driven manual integration, see \fBDESKTOP INTEGRATION\fR section in \fBman 1 firejail\fR. 34To configure the list of programs used by firecfg when creating symlinks, see
35\fBFILES\fR and \fBSYNTAX\fR.
36.PP
37For user-driven manual integration, see \fBDESKTOP INTEGRATION\fR section in
38\fBman 1 firejail\fR.
35.SH DEFAULT ACTIONS 39.SH DEFAULT ACTIONS
36The following actions are implemented by default by running sudo firecfg: 40The following actions are implemented by default by running sudo firecfg:
37 41
@@ -135,8 +139,53 @@ $ sudo firecfg --clean
135/usr/local/bin/vlc removed 139/usr/local/bin/vlc removed
136.br 140.br
137[...] 141[...]
142.SH FILES
143.PP
144Configuration files are searched for and parsed in the following paths:
145.PP
146.RS
1471. /etc/firejail/firecfg.d/*.conf (in alphabetical order)
148.br
1492. /etc/firejail/firecfg.config
150.RE
151.PP
152The programs that are supported by default are listed in
153/etc/firejail/firecfg.config.
154It is recommended to leave it as is and put all customizations inside
155/etc/firejail/firecfg.d/.
156.PP
157Profile files are also searched in the user configuration directory:
158.PP
159.RS
1603. ~/.config/firejail/*.profile
161.RE
162.PP
163For every \fBPROGRAM.profile\fR file found, firecfg attempts to create a
164symlink for "PROGRAM", as if "PROGRAM" was listed in a configuration file.
165.SH SYNTAX
166Configuration file syntax:
167.PP
168A line that starts with \fB#\fR is considered a comment.
169.br
170A line that starts with \fB!PROGRAM\fR means to ignore "PROGRAM" when creating
171symlinks.
172.br
173A line that starts with anything else is considered to be the name of an
174executable and firecfg will attempt to create a symlink for it.
175.PP
176For example, to prevent firecfg from creating symlinks for "firefox" and
177"patch" while attempting to create a symlink for "myprog", the following lines
178could be added to /etc/firejail/firecfg.d/10-my.conf:
179.PP
180.RS
181!firefox
182.br
183!patch
184.br
138 185
139 186.br
187myprog
188.RE
140.SH LICENSE 189.SH LICENSE
141This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 190This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
142.PP 191.PP