summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
060e088)
If BusPolicy= was passed, the parser function will have created
an ExecContext->bus_endpoint object, along with policy information.
In that case, create a kdbus endpoint, and pass its path name to the
namespace logic, to it will be mounted over the actual 'bus' node.
At endpoint creation time, no policy is updloaded. That is done after
fork(), through a separate call. This is necessary because we don't
know the real uid of the process earlier than that.
#include "af-list.h"
#include "mkdir.h"
#include "apparmor-util.h"
#include "af-list.h"
#include "mkdir.h"
#include "apparmor-util.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
_cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
const char *username = NULL, *home = NULL, *shell = NULL;
unsigned n_dont_close = 0;
_cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
const char *username = NULL, *home = NULL, *shell = NULL;
unsigned n_dont_close = 0;
- int dont_close[n_fds + 3];
+ int dont_close[n_fds + 4];
uid_t uid = (uid_t) -1;
gid_t gid = (gid_t) -1;
int i, err;
uid_t uid = (uid_t) -1;
gid_t gid = (gid_t) -1;
int i, err;
memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
n_dont_close += n_fds;
}
memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
n_dont_close += n_fds;
}
+ if (params->bus_endpoint_fd >= 0)
+ dont_close[n_dont_close++] = params->bus_endpoint_fd;
if (runtime) {
if (runtime->netns_storage_socket[0] >= 0)
dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
if (runtime) {
if (runtime->netns_storage_socket[0] >= 0)
dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
+#ifdef ENABLE_KDBUS
+ if (params->bus_endpoint_fd >= 0 && context->bus_endpoint) {
+ uid_t ep_uid = (uid == (uid_t) -1) ? 0 : uid;
+
+ err = bus_kernel_set_endpoint_policy(params->bus_endpoint_fd, ep_uid, context->bus_endpoint);
+ if (err < 0) {
+ *error = EXIT_BUS_ENDPOINT;
+ return err;
+ }
+ }
+#endif
+
#ifdef HAVE_PAM
if (params->cgroup_path && context->user && context->pam_name) {
err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0644, uid, gid);
#ifdef HAVE_PAM
if (params->cgroup_path && context->user && context->pam_name) {
err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0644, uid, gid);
!strv_isempty(context->inaccessible_dirs) ||
context->mount_flags != 0 ||
(context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir)) ||
!strv_isempty(context->inaccessible_dirs) ||
context->mount_flags != 0 ||
(context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir)) ||
+ params->bus_endpoint_path ||
context->private_devices ||
context->protect_system != PROTECT_SYSTEM_NO ||
context->protect_home != PROTECT_HOME_NO) {
context->private_devices ||
context->protect_system != PROTECT_SYSTEM_NO ||
context->protect_home != PROTECT_HOME_NO) {
context->inaccessible_dirs,
tmp,
var,
context->inaccessible_dirs,
tmp,
var,
+ params->bus_endpoint_path,
context->private_devices,
context->protect_home,
context->protect_system,
context->private_devices,
context->protect_home,
context->protect_system,
/* We repeat the fd closing here, to make sure that
* nothing is leaked from the PAM modules. Note that
* we are more aggressive this time since socket_fd
/* We repeat the fd closing here, to make sure that
* nothing is leaked from the PAM modules. Note that
* we are more aggressive this time since socket_fd
- * and the netns fds we don#t need anymore. */
+ * and the netns fds we don't need anymore. The custom
+ * endpoint fd was needed to upload the policy and can
+ * now be closed as well. */
err = close_all_fds(fds, n_fds);
if (err >= 0)
err = shift_fds(fds, n_fds);
err = close_all_fds(fds, n_fds);
if (err >= 0)
err = shift_fds(fds, n_fds);
const char *unit_id;
usec_t watchdog_usec;
int *idle_pipe;
const char *unit_id;
usec_t watchdog_usec;
int *idle_pipe;
+ char *bus_endpoint_path;
+ int bus_endpoint_fd;
};
int exec_spawn(ExecCommand *command,
};
int exec_spawn(ExecCommand *command,
#include "fileio.h"
#include "bus-error.h"
#include "bus-util.h"
#include "fileio.h"
#include "bus-error.h"
#include "bus-util.h"
static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
[SERVICE_DEAD] = UNIT_INACTIVE,
static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
[SERVICE_DEAD] = UNIT_INACTIVE,
s->restart_usec = u->manager->default_restart_usec;
s->type = _SERVICE_TYPE_INVALID;
s->socket_fd = -1;
s->restart_usec = u->manager->default_restart_usec;
s->type = _SERVICE_TYPE_INVALID;
s->socket_fd = -1;
+ s->bus_endpoint_fd = -1;
s->guess_main_pid = true;
RATELIMIT_INIT(s->start_limit, u->manager->default_start_limit_interval, u->manager->default_start_limit_burst);
s->guess_main_pid = true;
RATELIMIT_INIT(s->start_limit, u->manager->default_start_limit_interval, u->manager->default_start_limit_burst);
+ s->bus_endpoint_fd = safe_close(s->bus_endpoint_fd);
service_close_socket_fd(s);
service_connection_unref(s);
service_close_socket_fd(s);
service_connection_unref(s);
int *fds = NULL;
_cleanup_free_ int *fdsbuf = NULL;
unsigned n_fds = 0, n_env = 0;
int *fds = NULL;
_cleanup_free_ int *fdsbuf = NULL;
unsigned n_fds = 0, n_env = 0;
+ _cleanup_free_ char *bus_endpoint_path = NULL;
_cleanup_strv_free_ char
**argv = NULL, **final_env = NULL, **our_env = NULL;
const char *path;
_cleanup_strv_free_ char
**argv = NULL, **final_env = NULL, **our_env = NULL;
const char *path;
.apply_permissions = apply_permissions,
.apply_chroot = apply_chroot,
.apply_tty_stdin = apply_tty_stdin,
.apply_permissions = apply_permissions,
.apply_chroot = apply_chroot,
.apply_tty_stdin = apply_tty_stdin,
} else
path = UNIT(s)->cgroup_path;
} else
path = UNIT(s)->cgroup_path;
+#ifdef ENABLE_KDBUS
+ if (s->exec_context.bus_endpoint) {
+ r = bus_kernel_create_endpoint(UNIT(s)->manager->running_as == SYSTEMD_SYSTEM ? "system" : "user",
+ UNIT(s)->id, &bus_endpoint_path);
+ if (r < 0)
+ goto fail;
+
+ /* Pass the fd to the exec_params so that the child process can upload the policy.
+ * Keep a reference to the fd in the service, so the endpoint is kept alive as long
+ * as the service is running. */
+ exec_params.bus_endpoint_fd = s->bus_endpoint_fd = r;
+ }
+#endif
+
exec_params.argv = argv;
exec_params.fds = fds;
exec_params.n_fds = n_fds;
exec_params.argv = argv;
exec_params.fds = fds;
exec_params.n_fds = n_fds;
exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
exec_params.unit_id = UNIT(s)->id;
exec_params.watchdog_usec = s->watchdog_usec;
exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
exec_params.unit_id = UNIT(s)->id;
exec_params.watchdog_usec = s->watchdog_usec;
+ exec_params.bus_endpoint_path = bus_endpoint_path;
if (s->type == SERVICE_IDLE)
exec_params.idle_pipe = UNIT(s)->manager->idle_pipe;
if (s->type == SERVICE_IDLE)
exec_params.idle_pipe = UNIT(s)->manager->idle_pipe;
unit_serialize_item_format(u, f, "socket-fd", "%i", copy);
}
unit_serialize_item_format(u, f, "socket-fd", "%i", copy);
}
+ if (s->bus_endpoint_fd >= 0) {
+ int copy;
+
+ if ((copy = fdset_put_dup(fds, s->bus_endpoint_fd)) < 0)
+ return copy;
+
+ unit_serialize_item_format(u, f, "endpoint-fd", "%i", copy);
+ }
+
if (s->main_exec_status.pid > 0) {
unit_serialize_item_format(u, f, "main-exec-status-pid", PID_FMT,
s->main_exec_status.pid);
if (s->main_exec_status.pid > 0) {
unit_serialize_item_format(u, f, "main-exec-status-pid", PID_FMT,
s->main_exec_status.pid);
if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
log_debug_unit(u->id, "Failed to parse socket-fd value %s", value);
else {
if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
log_debug_unit(u->id, "Failed to parse socket-fd value %s", value);
else {
asynchronous_close(s->socket_fd);
s->socket_fd = fdset_remove(fds, fd);
}
asynchronous_close(s->socket_fd);
s->socket_fd = fdset_remove(fds, fd);
}
+ } else if (streq(key, "endpoint-fd")) {
+ int fd;
+
+ if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+ log_debug_unit(u->id, "Failed to parse endpoint-fd value %s", value);
+ else {
+ safe_close(s->bus_endpoint_fd);
+ s->bus_endpoint_fd = fdset_remove(fds, fd);
+ }
} else if (streq(key, "main-exec-status-pid")) {
pid_t pid;
} else if (streq(key, "main-exec-status-pid")) {
pid_t pid;
pid_t main_pid, control_pid;
int socket_fd;
pid_t main_pid, control_pid;
int socket_fd;
bool permissions_start_only;
bool root_directory_start_only;
bool remain_after_exit;
bool permissions_start_only;
bool root_directory_start_only;
bool remain_after_exit;