#include <linux/oom.h>
#include <sys/poll.h>
#include <glob.h>
+#include <sys/personality.h>
#include <libgen.h>
#undef basename
#include <seccomp.h>
#endif
+#ifdef HAVE_APPARMOR
+#include <sys/apparmor.h>
+#endif
+
#include "execute.h"
#include "strv.h"
#include "macro.h"
#include "async.h"
#include "selinux-util.h"
#include "errno-list.h"
+#include "apparmor-util.h"
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
if (!seccomp)
return -ENOMEM;
- SET_FOREACH(id, c->syscall_archs, i) {
- r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
- if (r == -EEXIST)
- continue;
+ if (c->syscall_archs) {
+
+ SET_FOREACH(id, c->syscall_archs, i) {
+ r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
+ if (r == -EEXIST)
+ continue;
+ if (r < 0) {
+ seccomp_release(seccomp);
+ return r;
+ }
+ }
+ } else {
+
+ r = seccomp_add_secondary_archs(seccomp);
if (r < 0) {
seccomp_release(seccomp);
return r;
goto fail_child;
}
+ if (context->personality != 0xffffffffUL)
+ if (personality(context->personality) < 0) {
+ err = -errno;
+ r = EXIT_PERSONALITY;
+ goto fail_child;
+ }
+
if (context->utmp_id)
utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
#ifdef HAVE_SELINUX
if (context->selinux_context && use_selinux()) {
- bool ignore;
- char* c;
-
- c = context->selinux_context;
- if (c[0] == '-') {
- c++;
- ignore = true;
- } else
- ignore = false;
-
- err = setexeccon(c);
- if (err < 0 && !ignore) {
+ err = setexeccon(context->selinux_context);
+ if (err < 0 && !context->selinux_context_ignore) {
r = EXIT_SELINUX_CONTEXT;
goto fail_child;
}
}
#endif
+
+#ifdef HAVE_APPARMOR
+ if (context->apparmor_profile && use_apparmor()) {
+ err = aa_change_onexec(context->apparmor_profile);
+ if (err < 0 && !context->apparmor_profile_ignore) {
+ r = EXIT_APPARMOR_PROFILE;
+ goto fail_child;
+ }
+ }
+#endif
}
err = build_environment(context, n_fds, watchdog_usec, home, username, shell, &our_env);
c->syslog_level_prefix = true;
c->ignore_sigpipe = true;
c->timer_slack_nsec = (nsec_t) -1;
+ c->personality = 0xffffffffUL;
}
void exec_context_done(ExecContext *c) {
free(c->selinux_context);
c->selinux_context = NULL;
+ free(c->apparmor_profile);
+ c->apparmor_profile = NULL;
+
#ifdef HAVE_SECCOMP
set_free(c->syscall_filter);
c->syscall_filter = NULL;
fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max);
if (c->ioprio_set) {
- char *class_str;
- int r;
+ _cleanup_free_ char *class_str = NULL;
- r = ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
- if (r < 0)
- class_str = NULL;
+ ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
fprintf(f,
"%sIOSchedulingClass: %s\n"
"%sIOPriority: %i\n",
prefix, strna(class_str),
prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
- free(class_str);
}
if (c->cpu_sched_set) {
- char *policy_str;
- int r;
+ _cleanup_free_ char *policy_str = NULL;
- r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
- if (r < 0)
- policy_str = NULL;
+ sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
fprintf(f,
"%sCPUSchedulingPolicy: %s\n"
"%sCPUSchedulingPriority: %i\n"
prefix, strna(policy_str),
prefix, c->cpu_sched_priority,
prefix, yes_no(c->cpu_sched_reset_on_fork));
- free(policy_str);
}
if (c->cpuset) {
if (c->selinux_context)
fprintf(f,
- "%sSELinuxContext: %s\n",
- prefix, c->selinux_context);
+ "%sSELinuxContext: %s%s\n",
+ prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
+
+ if (c->personality != 0xffffffffUL)
+ fprintf(f,
+ "%sPersonality: %s\n",
+ prefix, strna(personality_to_string(c->personality)));
if (c->syscall_filter) {
#ifdef HAVE_SECCOMP
fprintf(f,
"%sSystemCallErrorNumber: %s\n",
prefix, strna(errno_to_name(c->syscall_errno)));
+
+ if (c->apparmor_profile)
+ fprintf(f,
+ "%sAppArmorProfile: %s%s\n",
+ prefix, c->apparmor_profile_ignore ? "-" : "", c->apparmor_profile);
}
void exec_status_start(ExecStatus *s, pid_t pid) {