diff options
-rw-r--r-- | etc/inc/archiver-common.inc | 13 | ||||
-rw-r--r-- | etc/inc/disable-common.inc | 3 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 51 | ||||
-rw-r--r-- | src/firejail/pulseaudio.c | 23 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 2 | ||||
-rw-r--r-- | src/firejail/util.c | 3 |
6 files changed, 53 insertions, 42 deletions
diff --git a/etc/inc/archiver-common.inc b/etc/inc/archiver-common.inc index 2c5e4d8bf..9812e3ebb 100644 --- a/etc/inc/archiver-common.inc +++ b/etc/inc/archiver-common.inc | |||
@@ -6,12 +6,21 @@ include archiver-common.local | |||
6 | 6 | ||
7 | blacklist ${RUNUSER} | 7 | blacklist ${RUNUSER} |
8 | 8 | ||
9 | include disable-common.inc | 9 | # WARNING: |
10 | # Users can (un)restrict file access for **all** archivers by commenting/uncommenting the needed | ||
11 | # include file(s) here or by putting those into archiver-common.local. | ||
12 | # Another option is to do this **per archiver** in the relevant <archiver>.local. | ||
13 | # Just beware that things tend to break when overtightening profiles. For example, because you only | ||
14 | # need to (un)compress files in ${DOWNLOADS}, other applications may need access to ${HOME}/.local/share. | ||
15 | |||
16 | # Uncomment the next line (or put it into your archiver-common.local) if you don't need to compress files in disable-common.inc. | ||
17 | #include disable-common.inc | ||
10 | include disable-devel.inc | 18 | include disable-devel.inc |
11 | include disable-exec.inc | 19 | include disable-exec.inc |
12 | include disable-interpreters.inc | 20 | include disable-interpreters.inc |
13 | include disable-passwdmgr.inc | 21 | include disable-passwdmgr.inc |
14 | include disable-programs.inc | 22 | # Uncomment the next line (or put it into your archiver-common.local) if you don't need to compress files in disable-programs.inc. |
23 | #include disable-programs.inc | ||
15 | include disable-shell.inc | 24 | include disable-shell.inc |
16 | 25 | ||
17 | apparmor | 26 | apparmor |
diff --git a/etc/inc/disable-common.inc b/etc/inc/disable-common.inc index 2b56bb5be..d88506d90 100644 --- a/etc/inc/disable-common.inc +++ b/etc/inc/disable-common.inc | |||
@@ -517,16 +517,19 @@ blacklist /proc/config.gz | |||
517 | blacklist ${PATH}/dig | 517 | blacklist ${PATH}/dig |
518 | blacklist ${PATH}/dlint | 518 | blacklist ${PATH}/dlint |
519 | blacklist ${PATH}/dns2tcp | 519 | blacklist ${PATH}/dns2tcp |
520 | blacklist ${PATH}/dnssec-* | ||
520 | blacklist ${PATH}/dnswalk | 521 | blacklist ${PATH}/dnswalk |
521 | blacklist ${PATH}/drill | 522 | blacklist ${PATH}/drill |
522 | blacklist ${PATH}/host | 523 | blacklist ${PATH}/host |
523 | blacklist ${PATH}/iodine | 524 | blacklist ${PATH}/iodine |
524 | blacklist ${PATH}/kdig | 525 | blacklist ${PATH}/kdig |
526 | blacklist ${PATH}/khost | ||
525 | blacklist ${PATH}/knsupdate | 527 | blacklist ${PATH}/knsupdate |
526 | blacklist ${PATH}/ldns-* | 528 | blacklist ${PATH}/ldns-* |
527 | blacklist ${PATH}/ldnsd | 529 | blacklist ${PATH}/ldnsd |
528 | blacklist ${PATH}/nslookup | 530 | blacklist ${PATH}/nslookup |
529 | blacklist ${PATH}/resolvectl | 531 | blacklist ${PATH}/resolvectl |
532 | blacklist ${PATH}/unbound-host | ||
530 | 533 | ||
531 | # rest of ${RUNUSER} | 534 | # rest of ${RUNUSER} |
532 | blacklist ${RUNUSER}/*.lock | 535 | blacklist ${RUNUSER}/*.lock |
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index af891d61f..8c7c19203 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -360,43 +360,38 @@ void fs_private(void) { | |||
360 | selinux_relabel_path("/root", "/root"); | 360 | selinux_relabel_path("/root", "/root"); |
361 | fs_logger("tmpfs /root"); | 361 | fs_logger("tmpfs /root"); |
362 | 362 | ||
363 | if (arg_allusers) { | 363 | // mask /home |
364 | if (u != 0) | 364 | if (!arg_allusers) { |
365 | // mask user home directory | ||
366 | // the directory should be owned by the current user | ||
367 | fs_tmpfs(homedir, 1); | ||
368 | } | ||
369 | else { // mask /home | ||
370 | if (arg_debug) | 365 | if (arg_debug) |
371 | printf("Mounting a new /home directory\n"); | 366 | printf("Mounting a new /home directory\n"); |
372 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0) | 367 | if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0) |
373 | errExit("mounting /home directory"); | 368 | errExit("mounting /home directory"); |
374 | selinux_relabel_path("/home", "/home"); | 369 | selinux_relabel_path("/home", "/home"); |
375 | fs_logger("tmpfs /home"); | 370 | fs_logger("tmpfs /home"); |
371 | } | ||
376 | 372 | ||
377 | if (u != 0) { | 373 | if (u != 0) { |
378 | if (strncmp(homedir, "/home/", 6) == 0) { | 374 | if (!arg_allusers && strncmp(homedir, "/home/", 6) == 0) { |
379 | // create /home/user | 375 | // create new empty /home/user directory |
380 | if (arg_debug) | 376 | if (arg_debug) |
381 | printf("Create a new user directory\n"); | 377 | printf("Create a new user directory\n"); |
382 | if (mkdir(homedir, S_IRWXU) == -1) { | 378 | if (mkdir(homedir, S_IRWXU) == -1) { |
383 | if (mkpath_as_root(homedir) == -1) | 379 | if (mkpath_as_root(homedir) == -1) |
384 | errExit("mkpath"); | 380 | errExit("mkpath"); |
385 | if (mkdir(homedir, S_IRWXU) == -1 && errno != EEXIST) | 381 | if (mkdir(homedir, S_IRWXU) == -1) |
386 | errExit("mkdir"); | 382 | errExit("mkdir"); |
387 | } | ||
388 | if (chown(homedir, u, g) < 0) | ||
389 | errExit("chown"); | ||
390 | |||
391 | selinux_relabel_path(homedir, homedir); | ||
392 | fs_logger2("mkdir", homedir); | ||
393 | fs_logger2("tmpfs", homedir); | ||
394 | } | 383 | } |
395 | else | 384 | if (chown(homedir, u, g) < 0) |
396 | // mask user home directory | 385 | errExit("chown"); |
397 | // the directory should be owned by the current user | 386 | |
398 | fs_tmpfs(homedir, 1); | 387 | selinux_relabel_path(homedir, homedir); |
388 | fs_logger2("mkdir", homedir); | ||
389 | fs_logger2("tmpfs", homedir); | ||
399 | } | 390 | } |
391 | else | ||
392 | // mask user home directory | ||
393 | // the directory should be owned by the current user | ||
394 | fs_tmpfs(homedir, 1); | ||
400 | } | 395 | } |
401 | 396 | ||
402 | skel(homedir, u, g); | 397 | skel(homedir, u, g); |
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c index 84cbb1977..a5c924a70 100644 --- a/src/firejail/pulseaudio.c +++ b/src/firejail/pulseaudio.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #define O_PATH 010000000 | 31 | #define O_PATH 010000000 |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #define PULSE_CLIENT_SYSCONF "/etc/pulse/client.conf" | ||
35 | |||
34 | // disable pulseaudio socket | 36 | // disable pulseaudio socket |
35 | void pulseaudio_disable(void) { | 37 | void pulseaudio_disable(void) { |
36 | if (arg_debug) | 38 | if (arg_debug) |
@@ -73,8 +75,8 @@ void pulseaudio_disable(void) { | |||
73 | closedir(dir); | 75 | closedir(dir); |
74 | } | 76 | } |
75 | 77 | ||
76 | static void pulseaudio_set_environment(const char *path) { | 78 | static void pulseaudio_fallback(const char *path) { |
77 | assert(path); | 79 | fmessage("Cannot mount tmpfs on %s/.config/pulse\n", cfg.homedir); |
78 | if (setenv("PULSE_CLIENTCONFIG", path, 1) < 0) | 80 | if (setenv("PULSE_CLIENTCONFIG", path, 1) < 0) |
79 | errExit("setenv"); | 81 | errExit("setenv"); |
80 | } | 82 | } |
@@ -84,9 +86,9 @@ void pulseaudio_init(void) { | |||
84 | struct stat s; | 86 | struct stat s; |
85 | 87 | ||
86 | // do we have pulseaudio in the system? | 88 | // do we have pulseaudio in the system? |
87 | if (stat("/etc/pulse/client.conf", &s) == -1) { | 89 | if (stat(PULSE_CLIENT_SYSCONF, &s) == -1) { |
88 | if (arg_debug) | 90 | if (arg_debug) |
89 | printf("/etc/pulse/client.conf not found\n"); | 91 | printf("%s not found\n", PULSE_CLIENT_SYSCONF); |
90 | return; | 92 | return; |
91 | } | 93 | } |
92 | 94 | ||
@@ -101,7 +103,7 @@ void pulseaudio_init(void) { | |||
101 | char *pulsecfg = NULL; | 103 | char *pulsecfg = NULL; |
102 | if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1) | 104 | if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1) |
103 | errExit("asprintf"); | 105 | errExit("asprintf"); |
104 | if (copy_file("/etc/pulse/client.conf", pulsecfg, -1, -1, 0644)) // root needed | 106 | if (copy_file(PULSE_CLIENT_SYSCONF, pulsecfg, -1, -1, 0644)) // root needed |
105 | errExit("copy_file"); | 107 | errExit("copy_file"); |
106 | FILE *fp = fopen(pulsecfg, "a"); | 108 | FILE *fp = fopen(pulsecfg, "a"); |
107 | if (!fp) | 109 | if (!fp) |
@@ -126,11 +128,11 @@ void pulseaudio_init(void) { | |||
126 | if (create_empty_dir_as_user(homeusercfg, 0700)) | 128 | if (create_empty_dir_as_user(homeusercfg, 0700)) |
127 | fs_logger2("create", homeusercfg); | 129 | fs_logger2("create", homeusercfg); |
128 | 130 | ||
129 | // if ~/.config/pulse now exists and there are no symbolic links, mount the new directory | 131 | // if ~/.config/pulse exists and there are no symbolic links, mount the new directory |
130 | // else set environment variable | 132 | // else set environment variable |
131 | int fd = safe_fd(homeusercfg, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 133 | int fd = safe_fd(homeusercfg, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
132 | if (fd == -1) { | 134 | if (fd == -1) { |
133 | pulseaudio_set_environment(pulsecfg); | 135 | pulseaudio_fallback(pulsecfg); |
134 | goto out; | 136 | goto out; |
135 | } | 137 | } |
136 | // confirm the actual mount destination is owned by the user | 138 | // confirm the actual mount destination is owned by the user |
@@ -138,12 +140,12 @@ void pulseaudio_init(void) { | |||
138 | if (errno != EACCES) | 140 | if (errno != EACCES) |
139 | errExit("fstat"); | 141 | errExit("fstat"); |
140 | close(fd); | 142 | close(fd); |
141 | pulseaudio_set_environment(pulsecfg); | 143 | pulseaudio_fallback(pulsecfg); |
142 | goto out; | 144 | goto out; |
143 | } | 145 | } |
144 | if (s.st_uid != getuid()) { | 146 | if (s.st_uid != getuid()) { |
145 | close(fd); | 147 | close(fd); |
146 | pulseaudio_set_environment(pulsecfg); | 148 | pulseaudio_fallback(pulsecfg); |
147 | goto out; | 149 | goto out; |
148 | } | 150 | } |
149 | // preserve a read-only mount | 151 | // preserve a read-only mount |
@@ -171,8 +173,9 @@ void pulseaudio_init(void) { | |||
171 | char *p; | 173 | char *p; |
172 | if (asprintf(&p, "%s/client.conf", homeusercfg) == -1) | 174 | if (asprintf(&p, "%s/client.conf", homeusercfg) == -1) |
173 | errExit("asprintf"); | 175 | errExit("asprintf"); |
176 | if (setenv("PULSE_CLIENTCONFIG", p, 1) < 0) | ||
177 | errExit("setenv"); | ||
174 | fs_logger2("create", p); | 178 | fs_logger2("create", p); |
175 | pulseaudio_set_environment(p); | ||
176 | free(p); | 179 | free(p); |
177 | 180 | ||
178 | // RUN_PULSE_DIR not needed anymore, mask it | 181 | // RUN_PULSE_DIR not needed anymore, mask it |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 5c7b5e556..5115191ea 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -141,7 +141,7 @@ void set_apparmor(void) { | |||
141 | } | 141 | } |
142 | #endif | 142 | #endif |
143 | 143 | ||
144 | void seccomp_debug(void) { | 144 | static void seccomp_debug(void) { |
145 | if (arg_debug == 0) | 145 | if (arg_debug == 0) |
146 | return; | 146 | return; |
147 | 147 | ||
diff --git a/src/firejail/util.c b/src/firejail/util.c index e8b35a64b..6cc1bc720 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -75,10 +75,11 @@ static void clean_supplementary_groups(gid_t gid) { | |||
75 | goto clean_all; | 75 | goto clean_all; |
76 | 76 | ||
77 | // clean supplementary group list | 77 | // clean supplementary group list |
78 | // allow only tty, audio, video, games | 78 | // allow only firejail, tty, audio, video, games |
79 | gid_t new_groups[MAX_GROUPS]; | 79 | gid_t new_groups[MAX_GROUPS]; |
80 | int new_ngroups = 0; | 80 | int new_ngroups = 0; |
81 | char *allowed[] = { | 81 | char *allowed[] = { |
82 | "firejail", | ||
82 | "tty", | 83 | "tty", |
83 | "audio", | 84 | "audio", |
84 | "video", | 85 | "video", |