aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/dbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/dbus.c')
-rw-r--r--src/firejail/dbus.c59
1 files changed, 52 insertions, 7 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) {