aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kris7topher@gmail.com>2020-03-31 18:24:29 +0200
committerLibravatar Kristóf Marussy <kris7topher@gmail.com>2020-04-06 21:26:41 +0200
commit870c8c816fb7f99ea0fe5cc1b7cf900a857cfed7 (patch)
tree3a8fc9d53e0c41375808a136099d5bdf885753b2 /src
parentxdg-dbus-proxy socket finding and mount hardening (diff)
downloadfirejail-870c8c816fb7f99ea0fe5cc1b7cf900a857cfed7.tar.gz
firejail-870c8c816fb7f99ea0fe5cc1b7cf900a857cfed7.tar.zst
firejail-870c8c816fb7f99ea0fe5cc1b7cf900a857cfed7.zip
Turn DBus profile errors into warnings
This patch also allows setting the DBus policies to filter even if xdg-dbus-proxy is not installed. In that case, unrestricted access to the bus is allowed, but a warning is emitted.
Diffstat (limited to 'src')
-rw-r--r--src/firejail/dbus.c68
-rw-r--r--src/firejail/profile.c24
2 files changed, 42 insertions, 50 deletions
diff --git a/src/firejail/dbus.c b/src/firejail/dbus.c
index e358aaa49..0f4f18c57 100644
--- a/src/firejail/dbus.c
+++ b/src/firejail/dbus.c
@@ -41,6 +41,7 @@
41#define DBUS_USER_PROXY_SOCKET_FORMAT DBUS_USER_DIR_FORMAT "/%d-user" 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" 42#define DBUS_SYSTEM_PROXY_SOCKET_FORMAT DBUS_USER_DIR_FORMAT "/%d-system"
43#define DBUS_MAX_NAME_LENGTH 255 43#define DBUS_MAX_NAME_LENGTH 255
44#define XDG_DBUS_PROXY_PATH "/usr/bin/xdg-dbus-proxy"
44 45
45static pid_t dbus_proxy_pid = 0; 46static pid_t dbus_proxy_pid = 0;
46static int dbus_proxy_status_fd = -1; 47static int dbus_proxy_status_fd = -1;
@@ -78,42 +79,57 @@ int dbus_check_name(const char *name) {
78 return in_segment && segments >= 2; 79 return in_segment && segments >= 2;
79} 80}
80 81
81static void dbus_check_bus_profile(char const *prefix, DbusPolicy policy) { 82static void dbus_check_bus_profile(char const *prefix, DbusPolicy *policy) {
83 if (*policy == DBUS_POLICY_FILTER) {
84 struct stat s;
85 if (stat(XDG_DBUS_PROXY_PATH, &s) == -1) {
86 if (errno == ENOENT) {
87 fprintf(stderr,
88 "Warning: " XDG_DBUS_PROXY_PATH
89 " was not found, downgrading %s policy to allow.\n"
90 "To enable DBus filtering, install the xdg-dbus-proxy "
91 "program.\n", prefix);
92 *policy = DBUS_POLICY_ALLOW;
93 } else {
94 errExit("stat");
95 }
96 } else {
97 // No need to warn on profile entries.
98 return;
99 }
100 }
101
82 size_t prefix_length = strlen(prefix); 102 size_t prefix_length = strlen(prefix);
83 ProfileEntry *it = cfg.profile; 103 ProfileEntry *it = cfg.profile;
104 int num_matches = 0;
105 const char *first_match = NULL;
84 while (it) { 106 while (it) {
85 char *data = it->data; 107 char *data = it->data;
86 it = it->next; 108 it = it->next;
87 if (strncmp(prefix, data, prefix_length) == 0) { 109 if (strncmp(prefix, data, prefix_length) == 0) {
88 switch (policy) { 110 ++num_matches;
89 case DBUS_POLICY_ALLOW: 111 if (first_match == NULL)
90 // We should never get here, because profile parsing will fail earlier. 112 first_match = data;
91 fprintf(stderr, 113 }
92 "Error: %s filter rule configured, but the bus is not " 114 }
93 "set to filter.\n", 115
94 prefix); 116 if (num_matches > 0) {
95 exit(1); 117 assert(first_match != NULL);
96 break; 118 if (num_matches == 1) {
97 case DBUS_POLICY_FILTER: 119 fprintf(stderr, "Ignoring \"%s\".\n", first_match);
98 // All good. 120 } else if (num_matches == 2) {
99 break; 121 fprintf(stderr, "Ignoring \"%s\" and 1 other %s filter rule.\n",
100 case DBUS_POLICY_BLOCK: 122 first_match, prefix);
101 fwarning("%s filter rule configured, but the bus is blocked.\n", prefix); 123 } else {
102 fwarning("Ignoring \"%s\" and any other %s filter rules.\n", data, prefix); 124 fprintf(stderr, "Ignoring \"%s\" and %d other %s filter rules.\n",
103 break; 125 first_match, num_matches - 1, prefix);
104 default:
105 fprintf(stderr, "Error: Unknown %s policy.\n", prefix);
106 exit(1);
107 break;
108 }
109 break;
110 } 126 }
111 } 127 }
112} 128}
113 129
114void dbus_check_profile(void) { 130void dbus_check_profile(void) {
115 dbus_check_bus_profile("dbus-user", arg_dbus_user); 131 dbus_check_bus_profile("dbus-user", &arg_dbus_user);
116 dbus_check_bus_profile("dbus-system", arg_dbus_system); 132 dbus_check_bus_profile("dbus-system", &arg_dbus_system);
117} 133}
118 134
119static void write_arg(int fd, char const *format, ...) { 135static void write_arg(int fd, char const *format, ...) {
@@ -221,7 +237,7 @@ void dbus_proxy_start(void) {
221 if (i != status_pipe[1] && i != args_pipe[0]) 237 if (i != status_pipe[1] && i != args_pipe[0])
222 close(i); // close open files 238 close(i); // close open files
223 } 239 }
224 char *args[4] = {"/usr/bin/xdg-dbus-proxy", NULL, NULL, NULL}; 240 char *args[4] = {XDG_DBUS_PROXY_PATH, NULL, NULL, NULL};
225 if (asprintf(&args[1], "--fd=%d", status_pipe[1]) == -1 241 if (asprintf(&args[1], "--fd=%d", status_pipe[1]) == -1
226 || asprintf(&args[2], "--args=%d", args_pipe[0]) == -1) 242 || asprintf(&args[2], "--args=%d", args_pipe[0]) == -1)
227 errExit("asprintf"); 243 errExit("asprintf");
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 9bfd2ff1c..0be119903 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -453,12 +453,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
453 return 0; 453 return 0;
454 } 454 }
455 else if (strncmp(ptr, "dbus-user.talk ", 15) == 0) { 455 else if (strncmp(ptr, "dbus-user.talk ", 15) == 0) {
456 if (arg_dbus_user == DBUS_POLICY_ALLOW) {
457 fprintf(stderr, "Session DBus filtering (dbus-user filter) is "
458 "required for dbus-user.talk rules\n");
459 exit(1);
460 }
461
462 if (!dbus_check_name(ptr + 15)) { 456 if (!dbus_check_name(ptr + 15)) {
463 printf("Invalid dbus-user.talk name: %s\n", ptr + 15); 457 printf("Invalid dbus-user.talk name: %s\n", ptr + 15);
464 exit(1); 458 exit(1);
@@ -466,12 +460,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
466 return 1; 460 return 1;
467 } 461 }
468 else if (strncmp(ptr, "dbus-user.own ", 14) == 0) { 462 else if (strncmp(ptr, "dbus-user.own ", 14) == 0) {
469 if (arg_dbus_user == DBUS_POLICY_ALLOW) {
470 fprintf(stderr, "Session DBus filtering (dbus-user filter) is "
471 "required for dbus-user.own rules\n");
472 exit(1);
473 }
474
475 if (!dbus_check_name(ptr + 14)) { 463 if (!dbus_check_name(ptr + 14)) {
476 fprintf(stderr, "Invalid dbus-user.own name: %s\n", ptr + 14); 464 fprintf(stderr, "Invalid dbus-user.own name: %s\n", ptr + 14);
477 exit(1); 465 exit(1);
@@ -495,12 +483,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
495 return 0; 483 return 0;
496 } 484 }
497 else if (strncmp(ptr, "dbus-system.talk ", 17) == 0) { 485 else if (strncmp(ptr, "dbus-system.talk ", 17) == 0) {
498 if (arg_dbus_system == DBUS_POLICY_ALLOW) {
499 fprintf(stderr, "System DBus filtering (dbus-system filter) is "
500 "required for dbus-system.talk rules\n");
501 exit(1);
502 }
503
504 if (!dbus_check_name(ptr + 17)) { 486 if (!dbus_check_name(ptr + 17)) {
505 fprintf(stderr, "Invalid dbus-system.talk name: %s\n", ptr + 17); 487 fprintf(stderr, "Invalid dbus-system.talk name: %s\n", ptr + 17);
506 exit(1); 488 exit(1);
@@ -508,12 +490,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
508 return 1; 490 return 1;
509 } 491 }
510 else if (strncmp(ptr, "dbus-system.own ", 16) == 0) { 492 else if (strncmp(ptr, "dbus-system.own ", 16) == 0) {
511 if (arg_dbus_system == DBUS_POLICY_ALLOW) {
512 fprintf(stderr, "System DBus filtering (dbus-system filter) is "
513 "required for dbus-system.own rules\n");
514 exit(1);
515 }
516
517 if (!dbus_check_name(ptr + 16)) { 493 if (!dbus_check_name(ptr + 16)) {
518 fprintf(stderr, "Invalid dbus-system.own name: %s\n", ptr + 16); 494 fprintf(stderr, "Invalid dbus-system.own name: %s\n", ptr + 16);
519 exit(1); 495 exit(1);