diff options
author | 2019-05-24 21:28:10 +0200 | |
---|---|---|
committer | 2019-05-24 21:28:10 +0200 | |
commit | 9314fff8cb801e3f2f7a2996764c12ca4e350bea (patch) | |
tree | 58416f0e3a01b43f8265ff785c255eaa97e73e65 /src | |
parent | add header guard to firecfg.h (diff) | |
parent | Add private-cwd option to control working directory within jail (diff) | |
download | firejail-9314fff8cb801e3f2f7a2996764c12ca4e350bea.tar.gz firejail-9314fff8cb801e3f2f7a2996764c12ca4e350bea.tar.zst firejail-9314fff8cb801e3f2f7a2996764c12ca4e350bea.zip |
Merge pull request #2712 from apmorton/features/private-cwd
Add private-cwd option to control working directory within jail
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 3 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 15 | ||||
-rw-r--r-- | src/firejail/main.c | 15 | ||||
-rw-r--r-- | src/firejail/profile.c | 14 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 4 | ||||
-rw-r--r-- | src/firejail/usage.c | 2 | ||||
-rw-r--r-- | src/man/firejail-profile.txt | 6 | ||||
-rw-r--r-- | src/man/firejail.txt | 42 |
8 files changed, 100 insertions, 1 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index b2083d6ad..f904d65d2 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -283,6 +283,7 @@ extern int arg_private_srv; // private srv directory | |||
283 | extern int arg_private_bin; // private bin directory | 283 | extern int arg_private_bin; // private bin directory |
284 | extern int arg_private_tmp; // private tmp directory | 284 | extern int arg_private_tmp; // private tmp directory |
285 | extern int arg_private_lib; // private lib directory | 285 | extern int arg_private_lib; // private lib directory |
286 | extern int arg_private_cwd; // private working directory | ||
286 | extern int arg_scan; // arp-scan all interfaces | 287 | extern int arg_scan; // arp-scan all interfaces |
287 | extern int arg_whitelist; // whitelist command | 288 | extern int arg_whitelist; // whitelist command |
288 | extern int arg_nosound; // disable sound | 289 | extern int arg_nosound; // disable sound |
@@ -522,6 +523,8 @@ void fs_private(void); | |||
522 | void fs_private_homedir(void); | 523 | void fs_private_homedir(void); |
523 | // check new private home directory (--private= option) - exit if it fails | 524 | // check new private home directory (--private= option) - exit if it fails |
524 | void fs_check_private_dir(void); | 525 | void fs_check_private_dir(void); |
526 | // check new private working directory (--private-cwd= option) - exit if it fails | ||
527 | void fs_check_private_cwd(void); | ||
525 | void fs_private_home_list(void); | 528 | void fs_private_home_list(void); |
526 | 529 | ||
527 | 530 | ||
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index b44d09acc..a1a16841a 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -370,6 +370,21 @@ void fs_check_private_dir(void) { | |||
370 | } | 370 | } |
371 | } | 371 | } |
372 | 372 | ||
373 | // check new private working directory (--private-cwd= option) - exit if it fails | ||
374 | void fs_check_private_cwd(void) { | ||
375 | EUID_ASSERT(); | ||
376 | invalid_filename(cfg.cwd, 0); // no globbing | ||
377 | |||
378 | // Expand the working directory | ||
379 | cfg.cwd = expand_macros(cfg.cwd); | ||
380 | |||
381 | // realpath/is_dir not used because path may not exist outside of jail | ||
382 | if (!cfg.cwd) { | ||
383 | fprintf(stderr, "Error: invalid private working directory\n"); | ||
384 | exit(1); | ||
385 | } | ||
386 | } | ||
387 | |||
373 | //*********************************************************************************** | 388 | //*********************************************************************************** |
374 | // --private-home | 389 | // --private-home |
375 | //*********************************************************************************** | 390 | //*********************************************************************************** |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 3e2cc3a17..7ac88f5a5 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -92,6 +92,7 @@ int arg_private_srv = 0; // private srv directory | |||
92 | int arg_private_bin = 0; // private bin directory | 92 | int arg_private_bin = 0; // private bin directory |
93 | int arg_private_tmp = 0; // private tmp directory | 93 | int arg_private_tmp = 0; // private tmp directory |
94 | int arg_private_lib = 0; // private lib directory | 94 | int arg_private_lib = 0; // private lib directory |
95 | int arg_private_cwd = 0; // private working directory | ||
95 | int arg_scan = 0; // arp-scan all interfaces | 96 | int arg_scan = 0; // arp-scan all interfaces |
96 | int arg_whitelist = 0; // whitelist command | 97 | int arg_whitelist = 0; // whitelist command |
97 | int arg_nosound = 0; // disable sound | 98 | int arg_nosound = 0; // disable sound |
@@ -1774,6 +1775,20 @@ int main(int argc, char **argv) { | |||
1774 | else | 1775 | else |
1775 | exit_err_feature("private-cache"); | 1776 | exit_err_feature("private-cache"); |
1776 | } | 1777 | } |
1778 | else if (strcmp(argv[i], "--private-cwd") == 0) { | ||
1779 | cfg.cwd = NULL; | ||
1780 | arg_private_cwd = 1; | ||
1781 | } | ||
1782 | else if (strncmp(argv[i], "--private-cwd=", 14) == 0) { | ||
1783 | cfg.cwd = argv[i] + 14; | ||
1784 | if (*cfg.cwd == '\0') { | ||
1785 | fprintf(stderr, "Error: invalid private-cwd option\n"); | ||
1786 | exit(1); | ||
1787 | } | ||
1788 | |||
1789 | fs_check_private_cwd(); | ||
1790 | arg_private_cwd = 1; | ||
1791 | } | ||
1777 | 1792 | ||
1778 | //************************************* | 1793 | //************************************* |
1779 | // hostname, etc | 1794 | // hostname, etc |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 55d3cf5b0..8d228fae6 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -338,7 +338,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
338 | arg_private = 1; | 338 | arg_private = 1; |
339 | return 0; | 339 | return 0; |
340 | } | 340 | } |
341 | if (strncmp(ptr, "private-home ", 13) == 0) { | 341 | else if (strncmp(ptr, "private-home ", 13) == 0) { |
342 | #ifdef HAVE_PRIVATE_HOME | 342 | #ifdef HAVE_PRIVATE_HOME |
343 | if (checkcfg(CFG_PRIVATE_HOME)) { | 343 | if (checkcfg(CFG_PRIVATE_HOME)) { |
344 | if (cfg.home_private_keep) { | 344 | if (cfg.home_private_keep) { |
@@ -353,6 +353,18 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
353 | #endif | 353 | #endif |
354 | return 0; | 354 | return 0; |
355 | } | 355 | } |
356 | else if (strcmp(ptr, "private-cwd") == 0) { | ||
357 | cfg.cwd = NULL; | ||
358 | arg_private_cwd = 1; | ||
359 | return 0; | ||
360 | } | ||
361 | else if (strncmp(ptr, "private-cwd ", 12) == 0) { | ||
362 | cfg.cwd = strdup(ptr + 12); | ||
363 | |||
364 | fs_check_private_cwd(); | ||
365 | arg_private_cwd = 1; | ||
366 | return 0; | ||
367 | } | ||
356 | else if (strcmp(ptr, "allusers") == 0) { | 368 | else if (strcmp(ptr, "allusers") == 0) { |
357 | arg_allusers = 1; | 369 | arg_allusers = 1; |
358 | return 0; | 370 | return 0; |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index c09a1bc73..58245fa38 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -1019,6 +1019,10 @@ int sandbox(void* sandbox_arg) { | |||
1019 | if (cfg.cwd) { | 1019 | if (cfg.cwd) { |
1020 | if (chdir(cfg.cwd) == 0) | 1020 | if (chdir(cfg.cwd) == 0) |
1021 | cwd = 1; | 1021 | cwd = 1; |
1022 | else if (arg_private_cwd) { | ||
1023 | fprintf(stderr, "Error: unabled to enter private working directory: %s: %s\n", cfg.cwd, strerror(errno)); | ||
1024 | exit(1); | ||
1025 | } | ||
1022 | } | 1026 | } |
1023 | 1027 | ||
1024 | if (!cwd) { | 1028 | if (!cwd) { |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index ab749413b..af3bac839 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -163,6 +163,8 @@ static char *usage_str = | |||
163 | " --private-etc=file,directory - build a new /etc in a temporary\n" | 163 | " --private-etc=file,directory - build a new /etc in a temporary\n" |
164 | "\tfilesystem, and copy the files and directories in the list.\n" | 164 | "\tfilesystem, and copy the files and directories in the list.\n" |
165 | " --private-tmp - mount a tmpfs on top of /tmp directory.\n" | 165 | " --private-tmp - mount a tmpfs on top of /tmp directory.\n" |
166 | " --private-cwd - do not inherit working directory inside jail.\n" | ||
167 | " --private-cwd=directory - set working directory inside jail.\n" | ||
166 | " --private-opt=file,directory - build a new /opt in a temporary filesystem.\n" | 168 | " --private-opt=file,directory - build a new /opt in a temporary filesystem.\n" |
167 | " --private-srv=file,directory - build a new /srv in a temporary filesystem.\n" | 169 | " --private-srv=file,directory - build a new /srv in a temporary filesystem.\n" |
168 | " --profile=filename|profile_name - use a custom profile.\n" | 170 | " --profile=filename|profile_name - use a custom profile.\n" |
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index cbc745af7..d3a563abd 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt | |||
@@ -288,6 +288,12 @@ All modifications are discarded when the sandbox is closed. | |||
288 | \fBprivate-tmp | 288 | \fBprivate-tmp |
289 | Mount an empty temporary filesystem on top of /tmp directory whitelisting /tmp/.X11-unix. | 289 | Mount an empty temporary filesystem on top of /tmp directory whitelisting /tmp/.X11-unix. |
290 | .TP | 290 | .TP |
291 | \fBprivate-cwd | ||
292 | Set working directory inside jail to the home directory, and failing that, the root directory. | ||
293 | .TP | ||
294 | \fBprivate-cwd directory | ||
295 | Set working directory inside the jail. | ||
296 | .TP | ||
291 | \fBread-only file_or_directory | 297 | \fBread-only file_or_directory |
292 | Make directory or file read-only. | 298 | Make directory or file read-only. |
293 | .TP | 299 | .TP |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index fcc7f66d7..c4e8b9175 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -1572,6 +1572,48 @@ drwx------ 2 nobody nogroup 4096 Apr 30 10:52 pulse-PKdhtXMmr18n | |||
1572 | drwxrwxrwt 2 nobody nogroup 4096 Apr 30 10:52 .X11-unix | 1572 | drwxrwxrwt 2 nobody nogroup 4096 Apr 30 10:52 .X11-unix |
1573 | .br | 1573 | .br |
1574 | 1574 | ||
1575 | .TP | ||
1576 | \fB\-\-private-cwd | ||
1577 | Set working directory inside jail to the home directory, and failing that, the root directory. | ||
1578 | .br | ||
1579 | Does not impact working directory of profile include paths. | ||
1580 | .br | ||
1581 | |||
1582 | .br | ||
1583 | Example: | ||
1584 | .br | ||
1585 | $ pwd | ||
1586 | .br | ||
1587 | /tmp | ||
1588 | .br | ||
1589 | $ firejail \-\-private-cwd | ||
1590 | .br | ||
1591 | $ pwd | ||
1592 | .br | ||
1593 | /home/user | ||
1594 | .br | ||
1595 | |||
1596 | .TP | ||
1597 | \fB\-\-private-cwd=directory | ||
1598 | Set working directory inside the jail. | ||
1599 | .br | ||
1600 | Does not impact working directory of profile include paths. | ||
1601 | .br | ||
1602 | |||
1603 | .br | ||
1604 | Example: | ||
1605 | .br | ||
1606 | $ pwd | ||
1607 | .br | ||
1608 | /tmp | ||
1609 | .br | ||
1610 | $ firejail \-\-private-cwd=/opt | ||
1611 | .br | ||
1612 | $ pwd | ||
1613 | .br | ||
1614 | /opt | ||
1615 | .br | ||
1616 | |||
1575 | 1617 | ||
1576 | .TP | 1618 | .TP |
1577 | \fB\-\-profile=filename_or_profilename | 1619 | \fB\-\-profile=filename_or_profilename |