aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kris7topher@gmail.com>2020-03-07 14:40:30 +0100
committerLibravatar Kristóf Marussy <kris7topher@gmail.com>2020-04-06 21:26:41 +0200
commitdb4c5b0f50e7d572116994fffe19af3967c8853e (patch)
treee32c73b1d51611ad53d9f4e3a73c5bd8b84eb0ef
parentAdd documentation for DBus filtering (diff)
downloadfirejail-db4c5b0f50e7d572116994fffe19af3967c8853e.tar.gz
firejail-db4c5b0f50e7d572116994fffe19af3967c8853e.tar.zst
firejail-db4c5b0f50e7d572116994fffe19af3967c8853e.zip
xdg-dbus-proxy hardening
-rw-r--r--src/firejail/dbus.c59
-rw-r--r--src/firejail/main.c4
-rw-r--r--src/firejail/preproc.c12
3 files changed, 64 insertions, 11 deletions
diff --git a/src/firejail/dbus.c b/src/firejail/dbus.c
index bf1ae9a1e..9efd7bc85 100644
--- a/src/firejail/dbus.c
+++ b/src/firejail/dbus.c
@@ -22,18 +22,24 @@
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <sys/types.h> 23#include <sys/types.h>
24#include <sys/wait.h> 24#include <sys/wait.h>
25#include <errno.h>
25#include <unistd.h> 26#include <unistd.h>
26#include <fcntl.h> 27#include <fcntl.h>
27#include <string.h> 28#include <string.h>
28 29
30#ifndef O_PATH
31#define O_PATH 010000000
32#endif
33
29#define DBUS_SOCKET_PATH_PREFIX "unix:path=" 34#define DBUS_SOCKET_PATH_PREFIX "unix:path="
30#define DBUS_USER_SOCKET_FORMAT "/run/user/%d/bus" 35#define DBUS_USER_SOCKET_FORMAT "/run/user/%d/bus"
31#define DBUS_USER_SOCKET_PATH_FORMAT DBUS_SOCKET_PATH_PREFIX DBUS_USER_SOCKET_FORMAT 36#define DBUS_USER_SOCKET_PATH_FORMAT DBUS_SOCKET_PATH_PREFIX DBUS_USER_SOCKET_FORMAT
32#define DBUS_SYSTEM_SOCKET "/run/dbus/system_bus_socket" 37#define DBUS_SYSTEM_SOCKET "/run/dbus/system_bus_socket"
33#define DBUS_SYSTEM_SOCKET_PATH DBUS_SOCKET_PATH_PREFIX DBUS_SYSTEM_SOCKET 38#define DBUS_SYSTEM_SOCKET_PATH DBUS_SOCKET_PATH_PREFIX DBUS_SYSTEM_SOCKET
34#define DBUS_SESSION_BUS_ADDRESS_ENV "DBUS_SESSION_BUS_ADDRESS" 39#define DBUS_SESSION_BUS_ADDRESS_ENV "DBUS_SESSION_BUS_ADDRESS"
35#define DBUS_USER_PROXY_SOCKET_FORMAT RUN_FIREJAIL_DBUS_DIR "/%d-user" 40#define DBUS_USER_DIR_FORMAT RUN_FIREJAIL_DBUS_DIR "/%d"
36#define DBUS_SYSTEM_PROXY_SOCKET_FORMAT RUN_FIREJAIL_DBUS_DIR "/%d-system" 41#define DBUS_USER_PROXY_SOCKET_FORMAT DBUS_USER_DIR_FORMAT "/%d-user"
42#define DBUS_SYSTEM_PROXY_SOCKET_FORMAT DBUS_USER_DIR_FORMAT "/%d-system"
37#define DBUS_MAX_NAME_LENGTH 255 43#define DBUS_MAX_NAME_LENGTH 255
38 44
39static pid_t dbus_proxy_pid = 0; 45static pid_t dbus_proxy_pid = 0;
@@ -144,7 +150,29 @@ static void write_profile(int fd, char const *prefix) {
144 } 150 }
145} 151}
146 152
153static void dbus_create_user_dir(void) {
154 char *path;
155 if (asprintf(&path, DBUS_USER_DIR_FORMAT, (int) getuid()) == -1)
156 errExit("asprintf");
157 struct stat s;
158 mode_t mode = 0700;
159 uid_t uid = getuid();
160 gid_t gid = getgid();
161 if (stat(path, &s)) {
162 if (arg_debug)
163 printf("Creating %s directory for DBus proxy sockets\n", path);
164 if (mkdir(path, mode) == -1 && errno != EEXIST)
165 errExit("mkdir");
166 if (set_perms(path, uid, gid, mode))
167 errExit("set_perms");
168 ASSERT_PERMS(path, uid, gid, mode);
169 }
170 free(path);
171}
172
147void dbus_proxy_start(void) { 173void dbus_proxy_start(void) {
174 dbus_create_user_dir();
175
148 int status_pipe[2]; 176 int status_pipe[2];
149 if (pipe(status_pipe) == -1) 177 if (pipe(status_pipe) == -1)
150 errExit("pipe"); 178 errExit("pipe");
@@ -181,7 +209,8 @@ void dbus_proxy_start(void) {
181 } else { 209 } else {
182 write_arg(args_pipe[1], dbus_user_path_env); 210 write_arg(args_pipe[1], dbus_user_path_env);
183 } 211 }
184 if (asprintf(&dbus_user_proxy_socket, DBUS_USER_PROXY_SOCKET_FORMAT, (int) getpid()) == -1) 212 if (asprintf(&dbus_user_proxy_socket, DBUS_USER_PROXY_SOCKET_FORMAT,
213 (int) getuid(), (int) getpid()) == -1)
185 errExit("asprintf"); 214 errExit("asprintf");
186 write_arg(args_pipe[1], dbus_user_proxy_socket); 215 write_arg(args_pipe[1], dbus_user_proxy_socket);
187 write_arg(args_pipe[1], "--filter"); 216 write_arg(args_pipe[1], "--filter");
@@ -190,7 +219,8 @@ void dbus_proxy_start(void) {
190 219
191 if (arg_dbus_system == DBUS_POLICY_FILTER) { 220 if (arg_dbus_system == DBUS_POLICY_FILTER) {
192 write_arg(args_pipe[1], DBUS_SYSTEM_SOCKET_PATH); 221 write_arg(args_pipe[1], DBUS_SYSTEM_SOCKET_PATH);
193 if (asprintf(&dbus_system_proxy_socket, DBUS_SYSTEM_PROXY_SOCKET_FORMAT, (int) getpid()) == -1) 222 if (asprintf(&dbus_system_proxy_socket, DBUS_SYSTEM_PROXY_SOCKET_FORMAT,
223 (int) getuid(), (int) getpid()) == -1)
194 errExit("asprintf"); 224 errExit("asprintf");
195 write_arg(args_pipe[1], dbus_system_proxy_socket); 225 write_arg(args_pipe[1], dbus_system_proxy_socket);
196 write_arg(args_pipe[1], "--filter"); 226 write_arg(args_pipe[1], "--filter");
@@ -245,8 +275,23 @@ void dbus_proxy_stop(void) {
245} 275}
246 276
247static void socket_overlay(char *socket_path, char *proxy_path) { 277static void socket_overlay(char *socket_path, char *proxy_path) {
248 if (mount(proxy_path, socket_path, NULL, MS_BIND, NULL) == -1) 278 int fd = safe_fd(proxy_path, O_PATH | O_NOFOLLOW | O_CLOEXEC);
249 errExit("mount"); 279 if (fd == -1)
280 errExit("opening DBus proxy socket");
281 struct stat s;
282 if (fstat(fd, &s) == -1)
283 errExit("fstat");
284 if (!S_ISSOCK(s.st_mode)) {
285 errno = ENOTSOCK;
286 errExit("mounting DBus proxy socket");
287 }
288 char *proxy_fd_path;
289 if (asprintf(&proxy_fd_path, "/proc/self/fd/%d", fd) == -1)
290 errExit("asprintf");
291 if (mount(proxy_path, socket_path, NULL, MS_BIND | MS_REC, NULL) == -1)
292 errExit("mount bind");
293 free(proxy_fd_path);
294 close(fd);
250} 295}
251 296
252static void disable_socket_dir(void) { 297static void disable_socket_dir(void) {
@@ -281,7 +326,7 @@ void dbus_apply_policy(void) {
281 } else { 326 } else {
282 dbus_orig_user_socket_path = dbus_new_user_socket_path; 327 dbus_orig_user_socket_path = dbus_new_user_socket_path;
283 } 328 }
284 char *dbus_orig_user_socket = dbus_user_path_env + strlen(DBUS_SOCKET_PATH_PREFIX); 329 char *dbus_orig_user_socket = dbus_orig_user_socket_path + strlen(DBUS_SOCKET_PATH_PREFIX);
285 330
286 if (arg_dbus_user != DBUS_POLICY_ALLOW) { 331 if (arg_dbus_user != DBUS_POLICY_ALLOW) {
287 if (arg_dbus_user == DBUS_POLICY_FILTER) { 332 if (arg_dbus_user == DBUS_POLICY_FILTER) {
diff --git a/src/firejail/main.c b/src/firejail/main.c
index f59fc26e4..dc213b988 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -181,6 +181,7 @@ static void myexit(int rv) {
181 181
182 182
183 // delete sandbox files in shared memory 183 // delete sandbox files in shared memory
184 dbus_proxy_stop();
184 EUID_ROOT(); 185 EUID_ROOT();
185 delete_run_files(sandbox_pid); 186 delete_run_files(sandbox_pid);
186 appimage_clear(); 187 appimage_clear();
@@ -3023,9 +3024,6 @@ printf("**********************************\n");
3023 // end of signal-safe code 3024 // end of signal-safe code
3024 //***************************** 3025 //*****************************
3025 3026
3026 // stop dbus proxy (if any)
3027 dbus_proxy_stop();
3028
3029 // free globals 3027 // free globals
3030 if (cfg.profile) { 3028 if (cfg.profile) {
3031 ProfileEntry *prf = cfg.profile; 3029 ProfileEntry *prf = cfg.profile;
diff --git a/src/firejail/preproc.c b/src/firejail/preproc.c
index 61573b220..c0b09e945 100644
--- a/src/firejail/preproc.c
+++ b/src/firejail/preproc.c
@@ -59,7 +59,17 @@ void preproc_build_firejail_dir(void) {
59 } 59 }
60 60
61 if (stat(RUN_FIREJAIL_DBUS_DIR, &s)) { 61 if (stat(RUN_FIREJAIL_DBUS_DIR, &s)) {
62 create_empty_dir_as_root(RUN_FIREJAIL_DBUS_DIR, 01777); 62 create_empty_dir_as_root(RUN_FIREJAIL_DBUS_DIR, 0755);
63 if (arg_debug)
64 printf("Remounting the " RUN_FIREJAIL_DBUS_DIR
65 " directory as noexec\n");
66 if (mount(RUN_FIREJAIL_DBUS_DIR, RUN_FIREJAIL_DBUS_DIR, NULL,
67 MS_BIND, NULL) == -1)
68 errExit("mounting " RUN_FIREJAIL_DBUS_DIR);
69 if (mount(NULL, RUN_FIREJAIL_DBUS_DIR, NULL,
70 MS_REMOUNT | MS_BIND | MS_NOSUID | MS_NOEXEC | MS_NODEV,
71 "mode=755,gid=0") == -1)
72 errExit("remounting " RUN_FIREJAIL_DBUS_DIR);
63 } 73 }
64 74
65 if (stat(RUN_FIREJAIL_APPIMAGE_DIR, &s)) { 75 if (stat(RUN_FIREJAIL_APPIMAGE_DIR, &s)) {