aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/dbus.c
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kris7topher@gmail.com>2020-02-28 20:59:15 +0100
committerLibravatar Kristóf Marussy <kris7topher@gmail.com>2020-04-06 21:26:41 +0200
commit31df60f61d2c286674d7a062797fba494d1fd47c (patch)
tree2f85182069cff035bf73aeff0338e8fa6643897f /src/firejail/dbus.c
parentAdd xdg-dbus-proxy support (diff)
downloadfirejail-31df60f61d2c286674d7a062797fba494d1fd47c.tar.gz
firejail-31df60f61d2c286674d7a062797fba494d1fd47c.tar.zst
firejail-31df60f61d2c286674d7a062797fba494d1fd47c.zip
Add dbus filter options
The options --dbus-user.talk, --dbus-user.own, --dbus-system.talk, and --dbus-system.own control which names can be accessed and owned on the user and system buses.
Diffstat (limited to 'src/firejail/dbus.c')
-rw-r--r--src/firejail/dbus.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/src/firejail/dbus.c b/src/firejail/dbus.c
index 5cdd4b372..bf1ae9a1e 100644
--- a/src/firejail/dbus.c
+++ b/src/firejail/dbus.c
@@ -24,6 +24,7 @@
24#include <sys/wait.h> 24#include <sys/wait.h>
25#include <unistd.h> 25#include <unistd.h>
26#include <fcntl.h> 26#include <fcntl.h>
27#include <string.h>
27 28
28#define DBUS_SOCKET_PATH_PREFIX "unix:path=" 29#define DBUS_SOCKET_PATH_PREFIX "unix:path="
29#define DBUS_USER_SOCKET_FORMAT "/run/user/%d/bus" 30#define DBUS_USER_SOCKET_FORMAT "/run/user/%d/bus"
@@ -33,12 +34,82 @@
33#define DBUS_SESSION_BUS_ADDRESS_ENV "DBUS_SESSION_BUS_ADDRESS" 34#define DBUS_SESSION_BUS_ADDRESS_ENV "DBUS_SESSION_BUS_ADDRESS"
34#define DBUS_USER_PROXY_SOCKET_FORMAT RUN_FIREJAIL_DBUS_DIR "/%d-user" 35#define DBUS_USER_PROXY_SOCKET_FORMAT RUN_FIREJAIL_DBUS_DIR "/%d-user"
35#define DBUS_SYSTEM_PROXY_SOCKET_FORMAT RUN_FIREJAIL_DBUS_DIR "/%d-system" 36#define DBUS_SYSTEM_PROXY_SOCKET_FORMAT RUN_FIREJAIL_DBUS_DIR "/%d-system"
37#define DBUS_MAX_NAME_LENGTH 255
36 38
37static pid_t dbus_proxy_pid = 0; 39static pid_t dbus_proxy_pid = 0;
38static int dbus_proxy_status_fd = -1; 40static int dbus_proxy_status_fd = -1;
39static char *dbus_user_proxy_socket = NULL; 41static char *dbus_user_proxy_socket = NULL;
40static char *dbus_system_proxy_socket = NULL; 42static char *dbus_system_proxy_socket = NULL;
41 43
44int dbus_check_name(const char *name) {
45 unsigned long length = strlen(name);
46 if (length == 0 || length > DBUS_MAX_NAME_LENGTH)
47 return 0;
48 const char *p = name;
49 int segments = 1;
50 int in_segment = 0;
51 while (*p) {
52 int alpha = (*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z');
53 int digit = *p >= '0' && *p <= '9';
54 if (in_segment) {
55 if (*p == '.') {
56 ++segments;
57 in_segment = 0;
58 } else if (!alpha && !digit && *p != '_' && *p != '-') {
59 return 0;
60 }
61 }
62 else {
63 if (*p == '*') {
64 return *(p + 1) == '\0';
65 } else if (!alpha && *p != '_' && *p != '-') {
66 return 0;
67 }
68 in_segment = 1;
69 }
70 ++p;
71 }
72 return in_segment && segments >= 2;
73}
74
75static void dbus_check_bus_profile(char const *prefix, DbusPolicy policy) {
76 size_t prefix_length = strlen(prefix);
77 ProfileEntry *it = cfg.profile;
78 while (it) {
79 char *data = it->data;
80 it = it->next;
81 if (strncmp(prefix, data, prefix_length) == 0) {
82 switch (policy) {
83 case DBUS_POLICY_ALLOW:
84 // We should never get here, because profile parsing will fail earlier.
85 fprintf(stderr,
86 "Error: %s filter rule configured, but the bus is not "
87 "set to filter.\n",
88 prefix);
89 exit(1);
90 break;
91 case DBUS_POLICY_FILTER:
92 // All good.
93 break;
94 case DBUS_POLICY_BLOCK:
95 fwarning("%s filter rule configured, but the bus is blocked.\n", prefix);
96 fwarning("Ignoring \"%s\" and any other %s filter rules.\n", data, prefix);
97 break;
98 default:
99 fprintf(stderr, "Error: Unknown %s policy.\n", prefix);
100 exit(1);
101 break;
102 }
103 break;
104 }
105 }
106}
107
108void dbus_check_profile(void) {
109 dbus_check_bus_profile("dbus-user", arg_dbus_user);
110 dbus_check_bus_profile("dbus-system", arg_dbus_system);
111}
112
42static void write_arg(int fd, char const *format, ...) { 113static void write_arg(int fd, char const *format, ...) {
43 va_list ap; 114 va_list ap;
44 va_start(ap, format); 115 va_start(ap, format);
@@ -55,6 +126,24 @@ static void write_arg(int fd, char const *format, ...) {
55 free(arg); 126 free(arg);
56} 127}
57 128
129static void write_profile(int fd, char const *prefix) {
130 size_t prefix_length = strlen(prefix);
131 ProfileEntry *it = cfg.profile;
132 while (it) {
133 char *data = it->data;
134 it = it->next;
135 if (strncmp(prefix, data, prefix_length) != 0)
136 continue;
137 data += prefix_length;
138 int arg_length = 0;
139 while (data[arg_length] != '\0' && data[arg_length] != ' ')
140 arg_length++;
141 if (data[arg_length] != ' ')
142 continue;
143 write_arg(fd, "--%.*s=%s", arg_length, data, &data[arg_length + 1]);
144 }
145}
146
58void dbus_proxy_start(void) { 147void dbus_proxy_start(void) {
59 int status_pipe[2]; 148 int status_pipe[2];
60 if (pipe(status_pipe) == -1) 149 if (pipe(status_pipe) == -1)
@@ -96,7 +185,7 @@ void dbus_proxy_start(void) {
96 errExit("asprintf"); 185 errExit("asprintf");
97 write_arg(args_pipe[1], dbus_user_proxy_socket); 186 write_arg(args_pipe[1], dbus_user_proxy_socket);
98 write_arg(args_pipe[1], "--filter"); 187 write_arg(args_pipe[1], "--filter");
99 // TODO Write filter rules to pipe 188 write_profile(args_pipe[1], "dbus-user.");
100 } 189 }
101 190
102 if (arg_dbus_system == DBUS_POLICY_FILTER) { 191 if (arg_dbus_system == DBUS_POLICY_FILTER) {
@@ -105,7 +194,7 @@ void dbus_proxy_start(void) {
105 errExit("asprintf"); 194 errExit("asprintf");
106 write_arg(args_pipe[1], dbus_system_proxy_socket); 195 write_arg(args_pipe[1], dbus_system_proxy_socket);
107 write_arg(args_pipe[1], "--filter"); 196 write_arg(args_pipe[1], "--filter");
108 // TODO Write filter rules to pipe 197 write_profile(args_pipe[1], "dbus-system.");
109 } 198 }
110 199
111 if (close(args_pipe[1]) == -1) 200 if (close(args_pipe[1]) == -1)