#include "sd-messages.h"
#include "ioprio.h"
#include "securebits.h"
-#include "cgroup.h"
#include "namespace.h"
#include "tcpwrap.h"
#include "exit-status.h"
#include "syscall-list.h"
#include "env-util.h"
#include "fileio.h"
+#include "unit.h"
#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
return 0;
}
-static const char *tty_path(const ExecContext *context) {
+_pure_ static const char *tty_path(const ExecContext *context) {
assert(context);
if (context->tty_path)
static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd) {
int fd, r;
- union sockaddr_union sa;
+ union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/journal/stdout",
+ };
assert(context);
assert(output < _EXEC_OUTPUT_MAX);
if (fd < 0)
return -errno;
- zero(sa);
- sa.un.sun_family = AF_UNIX;
- strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path));
-
r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
if (r < 0) {
close_nointr_nofail(fd);
return r;
}
-static int write_confirm_message(const char *format, ...) {
+_printf_attr_(1, 2) static int write_confirm_message(const char *format, ...) {
int fd;
va_list ap;
int i;
unsigned n;
struct sock_filter *f;
- struct sock_fprog prog;
+ struct sock_fprog prog = {};
assert(syscall_filter);
memcpy(f + (ELEMENTSOF(header) + 2*n), footer, sizeof(footer));
/* Third: install the filter */
- zero(prog);
prog.len = ELEMENTSOF(header) + ELEMENTSOF(footer) + 2*n;
prog.filter = f;
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
bool apply_chroot,
bool apply_tty_stdin,
bool confirm_spawn,
- CGroupBonding *cgroup_bondings,
- CGroupAttribute *cgroup_attributes,
- const char *cgroup_suffix,
+ CGroupControllerMask cgroup_mask,
+ const char *cgroup_path,
const char *unit_id,
int idle_pipe[2],
pid_t *ret) {
+ _cleanup_strv_free_ char **files_env = NULL;
+ int socket_fd;
+ char *line;
pid_t pid;
int r;
- char *line;
- int socket_fd;
- char _cleanup_strv_free_ **files_env = NULL;
assert(command);
assert(context);
return log_oom();
log_struct_unit(LOG_DEBUG,
- unit_id,
- "MESSAGE=About to execute %s", line,
- NULL);
+ unit_id,
+ "EXECUTABLE=%s", command->path,
+ "MESSAGE=About to execute: %s", line,
+ NULL);
free(line);
- r = cgroup_bonding_realize_list(cgroup_bondings);
- if (r < 0)
- return r;
-
- cgroup_attribute_apply_list(cgroup_attributes, cgroup_bondings);
-
if (context->private_tmp && !context->tmp_dir && !context->var_tmp_dir) {
r = setup_tmpdirs(&context->tmp_dir, &context->var_tmp_dir);
if (r < 0)
const char *username = NULL, *home = NULL;
uid_t uid = (uid_t) -1;
gid_t gid = (gid_t) -1;
- char _cleanup_strv_free_ **our_env = NULL, **pam_env = NULL,
+ _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL,
**final_env = NULL, **final_argv = NULL;
unsigned n_env = 0;
- bool set_access = false;
/* child */
goto fail_child;
}
- if (cgroup_bondings) {
- err = cgroup_bonding_install_list(cgroup_bondings, 0, cgroup_suffix);
+ if (cgroup_path) {
+ err = cg_attach_with_mask(cgroup_mask, cgroup_path, 0);
if (err < 0) {
r = EXIT_CGROUP;
goto fail_child;
snprintf(t, sizeof(t), "%i", context->oom_score_adjust);
char_array_0(t);
- if (write_one_line_file("/proc/self/oom_score_adj", t) < 0) {
+ if (write_string_file("/proc/self/oom_score_adj", t) < 0) {
err = -errno;
r = EXIT_OOM_ADJUST;
goto fail_child;
}
if (context->cpu_sched_set) {
- struct sched_param param;
-
- zero(param);
- param.sched_priority = context->cpu_sched_priority;
+ struct sched_param param = {
+ .sched_priority = context->cpu_sched_priority,
+ };
r = sched_setscheduler(0,
context->cpu_sched_policy |
goto fail_child;
}
}
-
- if (cgroup_bondings && context->control_group_modify) {
- err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid);
- if (err >= 0)
- err = cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid, context->control_group_persistent);
- if (err < 0) {
- r = EXIT_CGROUP;
- goto fail_child;
- }
-
- set_access = true;
- }
- }
-
- if (cgroup_bondings && !set_access && context->control_group_persistent >= 0) {
- err = cgroup_bonding_set_task_access_list(cgroup_bondings, (mode_t) -1, (uid_t) -1, (uid_t) -1, context->control_group_persistent);
- if (err < 0) {
- r = EXIT_CGROUP;
- goto fail_child;
- }
}
if (apply_permissions) {
goto fail_child;
}
} else {
- char _cleanup_free_ *d = NULL;
+ _cleanup_free_ char *d = NULL;
if (asprintf(&d, "%s/%s",
context->root_directory ? context->root_directory : "",
final_env = strv_env_clean(final_env);
+ if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) {
+ line = exec_command_line(final_argv);
+ if (line) {
+ log_open();
+ log_struct_unit(LOG_DEBUG,
+ unit_id,
+ "EXECUTABLE=%s", command->path,
+ "MESSAGE=Executing: %s", line,
+ NULL);
+ log_close();
+ free(line);
+ line = NULL;
+ }
+ }
execve(command->path, final_argv, final_env);
err = -errno;
r = EXIT_EXEC;
* outside of the cgroup) and in the parent (so that we can be
* sure that when we kill the cgroup the process will be
* killed too). */
- if (cgroup_bondings)
- cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix);
+ if (cgroup_path)
+ cg_attach(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, pid);
exec_status_start(&command->exec_status, pid);
c->cpu_sched_policy = SCHED_OTHER;
c->syslog_priority = LOG_DAEMON|LOG_INFO;
c->syslog_level_prefix = true;
- c->control_group_persistent = -1;
c->ignore_sigpipe = true;
c->timer_slack_nsec = (nsec_t) -1;
}
int k;
bool ignore = false;
char **p;
- glob_t pglob;
+ _cleanup_globfree_ glob_t pglob = {};
int count, n;
fn = *i;
}
if (!path_is_absolute(fn)) {
-
if (ignore)
continue;
}
/* Filename supports globbing, take all matching files */
- zero(pglob);
errno = 0;
if (glob(fn, 0, NULL, &pglob) != 0) {
- globfree(&pglob);
if (ignore)
continue;
}
count = pglob.gl_pathc;
if (count == 0) {
- globfree(&pglob);
if (ignore)
continue;
return -EINVAL;
}
for (n = 0; n < count; n++) {
- k = load_env_file(pglob.gl_pathv[n], &p);
+ k = load_env_file(pglob.gl_pathv[n], NULL, &p);
if (k < 0) {
if (ignore)
continue;
strv_free(r);
- globfree(&pglob);
return k;
- }
+ }
+ /* Log invalid environment variables with filename */
+ if (p)
+ p = strv_env_clean_log(p, pglob.gl_pathv[n]);
if (r == NULL)
r = p;
m = strv_env_merge(2, r, p);
strv_free(r);
strv_free(p);
-
- if (!m) {
- globfree(&pglob);
+ if (!m)
return -ENOMEM;
- }
r = m;
}
}
- globfree(&pglob);
}
*l = r;
}
void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
- char ** e;
+ char **e;
unsigned i;
assert(c);
assert(f);
- if (!prefix)
- prefix = "";
+ prefix = strempty(prefix);
fprintf(f,
"%sUMask: %04o\n"
"%sRootDirectory: %s\n"
"%sNonBlocking: %s\n"
"%sPrivateTmp: %s\n"
- "%sControlGroupModify: %s\n"
- "%sControlGroupPersistent: %s\n"
"%sPrivateNetwork: %s\n"
"%sIgnoreSIGPIPE: %s\n",
prefix, c->umask,
prefix, c->root_directory ? c->root_directory : "/",
prefix, yes_no(c->non_blocking),
prefix, yes_no(c->private_tmp),
- prefix, yes_no(c->control_group_modify),
- prefix, yes_no(c->control_group_persistent),
prefix, yes_no(c->private_network),
prefix, yes_no(c->ignore_sigpipe));