diff options
author | Kristóf Marussy <kris7topher@gmail.com> | 2020-03-07 14:40:30 +0100 |
---|---|---|
committer | Kristóf Marussy <kris7topher@gmail.com> | 2020-04-06 21:26:41 +0200 |
commit | db4c5b0f50e7d572116994fffe19af3967c8853e (patch) | |
tree | e32c73b1d51611ad53d9f4e3a73c5bd8b84eb0ef | |
parent | Add documentation for DBus filtering (diff) | |
download | firejail-db4c5b0f50e7d572116994fffe19af3967c8853e.tar.gz firejail-db4c5b0f50e7d572116994fffe19af3967c8853e.tar.zst firejail-db4c5b0f50e7d572116994fffe19af3967c8853e.zip |
xdg-dbus-proxy hardening
-rw-r--r-- | src/firejail/dbus.c | 59 | ||||
-rw-r--r-- | src/firejail/main.c | 4 | ||||
-rw-r--r-- | src/firejail/preproc.c | 12 |
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 | ||
39 | static pid_t dbus_proxy_pid = 0; | 45 | static 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 | ||
153 | static 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 | |||
147 | void dbus_proxy_start(void) { | 173 | void 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 | ||
247 | static void socket_overlay(char *socket_path, char *proxy_path) { | 277 | static 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 | ||
252 | static void disable_socket_dir(void) { | 297 | static 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)) { |