diff options
author | Kristóf Marussy <kris7topher@gmail.com> | 2020-03-31 18:24:29 +0200 |
---|---|---|
committer | Kristóf Marussy <kris7topher@gmail.com> | 2020-04-06 21:26:41 +0200 |
commit | 870c8c816fb7f99ea0fe5cc1b7cf900a857cfed7 (patch) | |
tree | 3a8fc9d53e0c41375808a136099d5bdf885753b2 /src | |
parent | xdg-dbus-proxy socket finding and mount hardening (diff) | |
download | firejail-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.c | 68 | ||||
-rw-r--r-- | src/firejail/profile.c | 24 |
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 | ||
45 | static pid_t dbus_proxy_pid = 0; | 46 | static pid_t dbus_proxy_pid = 0; |
46 | static int dbus_proxy_status_fd = -1; | 47 | static 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 | ||
81 | static void dbus_check_bus_profile(char const *prefix, DbusPolicy policy) { | 82 | static 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 | ||
114 | void dbus_check_profile(void) { | 130 | void 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 | ||
119 | static void write_arg(int fd, char const *format, ...) { | 135 | static 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); |