exec: SystemCallLog= directive
With new directive SystemCallLog= it's possible to list system calls to be logged. This can be used for auditing or temporarily when constructing system call filters. --- v5: drop intermediary, update HASHMAP_FOREACH_KEY() use v4: skip useless debug messages, actually parse directive v3: don't declare unused variables with old libseccomp v2: fix build without seccomp or old libseccomp
This commit is contained in:
@@ -1407,6 +1407,13 @@ static bool context_has_syscall_filters(const ExecContext *c) {
|
||||
!hashmap_isempty(c->syscall_filter);
|
||||
}
|
||||
|
||||
static bool context_has_syscall_logs(const ExecContext *c) {
|
||||
assert(c);
|
||||
|
||||
return c->syscall_log_allow_list ||
|
||||
!hashmap_isempty(c->syscall_log);
|
||||
}
|
||||
|
||||
static bool context_has_no_new_privileges(const ExecContext *c) {
|
||||
assert(c);
|
||||
|
||||
@@ -1428,6 +1435,7 @@ static bool context_has_no_new_privileges(const ExecContext *c) {
|
||||
c->protect_kernel_logs ||
|
||||
c->private_devices ||
|
||||
context_has_syscall_filters(c) ||
|
||||
context_has_syscall_logs(c) ||
|
||||
!set_isempty(c->syscall_archs) ||
|
||||
c->lock_personality ||
|
||||
c->protect_hostname;
|
||||
@@ -1484,6 +1492,39 @@ static int apply_syscall_filter(const Unit* u, const ExecContext *c, bool needs_
|
||||
return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action, false);
|
||||
}
|
||||
|
||||
static int apply_syscall_log(const Unit* u, const ExecContext *c) {
|
||||
#ifdef SCMP_ACT_LOG
|
||||
uint32_t default_action, action;
|
||||
#endif
|
||||
|
||||
assert(u);
|
||||
assert(c);
|
||||
|
||||
if (!context_has_syscall_logs(c))
|
||||
return 0;
|
||||
|
||||
#ifdef SCMP_ACT_LOG
|
||||
if (skip_seccomp_unavailable(u, "SystemCallLog="))
|
||||
return 0;
|
||||
|
||||
if (c->syscall_log_allow_list) {
|
||||
/* Log nothing but the ones listed */
|
||||
default_action = SCMP_ACT_ALLOW;
|
||||
action = SCMP_ACT_LOG;
|
||||
} else {
|
||||
/* Log everything but the ones listed */
|
||||
default_action = SCMP_ACT_LOG;
|
||||
action = SCMP_ACT_ALLOW;
|
||||
}
|
||||
|
||||
return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_log, action, false);
|
||||
#else
|
||||
/* old libseccomp */
|
||||
log_unit_debug(u, "SECCOMP feature SCMP_ACT_LOG not available, skipping SystemCallLog=");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int apply_syscall_archs(const Unit *u, const ExecContext *c) {
|
||||
assert(u);
|
||||
assert(c);
|
||||
@@ -4438,6 +4479,12 @@ static int exec_child(
|
||||
return log_unit_error_errno(unit, r, "Failed to lock personalities: %m");
|
||||
}
|
||||
|
||||
r = apply_syscall_log(unit, context);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_SECCOMP;
|
||||
return log_unit_error_errno(unit, r, "Failed to apply system call log filters: %m");
|
||||
}
|
||||
|
||||
/* This really should remain the last step before the execve(), to make sure our own code is unaffected
|
||||
* by the filter as little as possible. */
|
||||
r = apply_syscall_filter(unit, context, needs_ambient_hack);
|
||||
|
||||
Reference in New Issue
Block a user