if (streq(name, "ProtectKernelLogs"))
return bus_set_transient_bool(u, name, &c->protect_kernel_logs, message, flags, error);
+ if (streq(name, "ProtectClock"))
+ return bus_set_transient_bool(u, name, &c->protect_clock, message, flags, error);
+
if (streq(name, "ProtectControlGroups"))
return bus_set_transient_bool(u, name, &c->protect_control_groups, message, flags, error);
c->restrict_realtime ||
c->restrict_suid_sgid ||
exec_context_restrict_namespaces_set(c) ||
+ c->protect_clock ||
c->protect_kernel_tunables ||
c->protect_kernel_modules ||
c->protect_kernel_logs ||
return seccomp_protect_syslog();
}
+static int apply_protect_clock(const Unit *u, const ExecContext *c) {
+ assert(u);
+ assert(c);
+
+ if (!c->protect_clock)
+ return 0;
+
+ if (skip_seccomp_unavailable(u, "ProtectClock="))
+ return 0;
+
+ return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_CLOCK, SCMP_ACT_ERRNO(EPERM), false);
+}
+
static int apply_private_devices(const Unit *u, const ExecContext *c) {
assert(u);
assert(c);
return log_unit_error_errno(unit, r, "Failed to apply kernel log restrictions: %m");
}
+ r = apply_protect_clock(unit, context);
+ if (r < 0) {
+ *exit_status = EXIT_SECCOMP;
+ return log_unit_error_errno(unit, r, "Failed to apply clock restrictions: %m");
+ }
+
r = apply_private_devices(unit, context);
if (r < 0) {
*exit_status = EXIT_SECCOMP;
"%sProtectKernelTunables: %s\n"
"%sProtectKernelModules: %s\n"
"%sProtectKernelLogs: %s\n"
+ "%sProtectClock: %s\n"
"%sProtectControlGroups: %s\n"
"%sPrivateNetwork: %s\n"
"%sPrivateUsers: %s\n"
prefix, yes_no(c->protect_kernel_tunables),
prefix, yes_no(c->protect_kernel_modules),
prefix, yes_no(c->protect_kernel_logs),
+ prefix, yes_no(c->protect_clock),
prefix, yes_no(c->protect_control_groups),
prefix, yes_no(c->private_network),
prefix, yes_no(c->private_users),
bool protect_kernel_tunables;
bool protect_kernel_modules;
bool protect_kernel_logs;
+ bool protect_clock;
bool protect_control_groups;
ProtectSystem protect_system;
ProtectHome protect_home;
$1.ProtectKernelTunables, config_parse_bool, 0, offsetof($1, exec_context.protect_kernel_tunables)
$1.ProtectKernelModules, config_parse_bool, 0, offsetof($1, exec_context.protect_kernel_modules)
$1.ProtectKernelLogs, config_parse_bool, 0, offsetof($1, exec_context.protect_kernel_logs)
+$1.ProtectClock, config_parse_bool, 0, offsetof($1, exec_context.protect_clock)
$1.ProtectControlGroups, config_parse_bool, 0, offsetof($1, exec_context.protect_control_groups)
$1.NetworkNamespacePath, config_parse_unit_path_printf, 0, offsetof($1, exec_context.network_namespace_path)
$1.PrivateNetwork, config_parse_bool, 0, offsetof($1, exec_context.private_network)
if (ec->protect_kernel_logs)
ec->capability_bounding_set &= ~(UINT64_C(1) << CAP_SYSLOG);
+ if (ec->protect_clock)
+ ec->capability_bounding_set &= ~((UINT64_C(1) << CAP_SYS_TIME) | (UINT64_C(1) << CAP_WAKE_ALARM));
+
if (ec->dynamic_user) {
if (!ec->user) {
r = user_from_unit_name(u, &ec->user);
if (r < 0)
return r;
}
+
+ if (ec->protect_clock) {
+ r = cgroup_add_device_allow(cc, "char-rtc", "r");
+ if (r < 0)
+ return r;
+ }
}
return 0;
"ProtectKernelTunables",
"ProtectKernelModules",
"ProtectKernelLogs",
+ "ProtectClock",
"ProtectControlGroups",
"MountAPIVFS",
"CPUSchedulingResetOnFork",