From be9fad86ae9ab721cd295210962da85706b839e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= Date: Fri, 7 Oct 2016 03:08:21 +0200 Subject: [PATCH] core: add possibility to set action for ctrl-alt-del burst (#4105) For some certification, it should not be possible to reboot the machine through ctrl-alt-delete. Currently we suggest our customers to mask the ctrl-alt-delete target, but that is obviously not enough. Patching the keymaps to disable that is really not a way to go for them, because the settings need to be easily checked by some SCAP tools. Cherry-picked from: 24dd31c19ede505143833346ff850af942694aa6 Resolves: #1353028 --- man/systemd-system.conf.xml | 11 ++++++++ src/core/main.c | 5 ++++ src/core/manager.c | 51 +++++++++++++++++++++++++++---------- src/core/manager.h | 14 +++++++++- src/core/system.conf | 1 + 5 files changed, 68 insertions(+), 14 deletions(-) diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index 39d19bc71a..236c20d5f9 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -101,6 +101,17 @@ arguments. + + CtrlAltDelBurstAction= + + Defines what action will be performed + if user presses Ctr-Alt-Delete more than 7 times in 2s. + Can be set to reboot-force, poweroff-force + or disabled with ignore. Defaults to + reboot-force. + + + CPUAffinity= diff --git a/src/core/main.c b/src/core/main.c index c9d8ce4a40..6ac9c9d44f 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -115,6 +115,7 @@ static FILE* arg_serialization = NULL; static bool arg_default_cpu_accounting = false; static bool arg_default_blockio_accounting = false; static bool arg_default_memory_accounting = false; +static CADBurstAction arg_cad_burst_action = CAD_BURST_ACTION_REBOOT; static void nop_handler(int sig) {} @@ -625,6 +626,8 @@ static int config_parse_join_controllers(const char *unit, return 0; } +static DEFINE_CONFIG_PARSE_ENUM(config_parse_cad_burst_action, cad_burst_action, CADBurstAction, "Failed to parse service restart specifier"); + static int parse_config_file(void) { const ConfigTableItem items[] = { @@ -673,6 +676,7 @@ static int parse_config_file(void) { { "Manager", "DefaultCPUAccounting", config_parse_bool, 0, &arg_default_cpu_accounting }, { "Manager", "DefaultBlockIOAccounting", config_parse_bool, 0, &arg_default_blockio_accounting }, { "Manager", "DefaultMemoryAccounting", config_parse_bool, 0, &arg_default_memory_accounting }, + { "Manager", "CtrlAltDelBurstAction", config_parse_cad_burst_action, 0, &arg_cad_burst_action}, {} }; @@ -1690,6 +1694,7 @@ int main(int argc, char *argv[]) { m->initrd_timestamp = initrd_timestamp; m->security_start_timestamp = security_start_timestamp; m->security_finish_timestamp = security_finish_timestamp; + m->cad_burst_action = arg_cad_burst_action; manager_set_default_rlimits(m, arg_default_rlimit); manager_environment_add(m, NULL, arg_default_environment); diff --git a/src/core/manager.c b/src/core/manager.c index 6d045fdf35..9048dde96e 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1859,6 +1859,35 @@ static int manager_start_target(Manager *m, const char *name, JobMode mode) { return r; } +static void manager_handle_ctrl_alt_del(Manager *m) { + /* If the user presses C-A-D more than + * 7 times within 2s, we reboot/shutdown immediately, + * unless it was disabled in system.conf */ + + if (ratelimit_test(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == CAD_BURST_ACTION_IGNORE) + manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY); + else { + switch (m->cad_burst_action) { + + case CAD_BURST_ACTION_REBOOT: + m->exit_code = MANAGER_REBOOT; + break; + + case CAD_BURST_ACTION_POWEROFF: + m->exit_code = MANAGER_POWEROFF; + break; + + default: + assert_not_reached("Unknown action."); + } + + log_notice("Ctrl-Alt-Del was pressed more than 7 times within 2s, performing immediate %s.", + cad_burst_action_to_string(m->cad_burst_action)); + status_printf(NULL, true, false, "Ctrl-Alt-Del was pressed more than 7 times within 2s, performing immediate %s.", + cad_burst_action_to_string(m->cad_burst_action)); + } +} + static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) { Manager *m = userdata; ssize_t n; @@ -1909,19 +1938,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t case SIGINT: if (m->running_as == SYSTEMD_SYSTEM) { - - /* If the user presses C-A-D more than - * 7 times within 2s, we reboot - * immediately. */ - - if (ratelimit_test(&m->ctrl_alt_del_ratelimit)) - manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY); - else { - log_notice("Ctrl-Alt-Del was pressed more than 7 times within 2s, rebooting immediately."); - status_printf(NULL, true, false, "Ctrl-Alt-Del was pressed more than 7 times within 2s, rebooting immediately."); - m->exit_code = MANAGER_REBOOT; - } - + manager_handle_ctrl_alt_del(m); break; } @@ -3319,3 +3336,11 @@ static const char *const manager_state_table[_MANAGER_STATE_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState); + +static const char *const cad_burst_action_table[_CAD_BURST_ACTION_MAX] = { + [CAD_BURST_ACTION_IGNORE] = "ignore", + [CAD_BURST_ACTION_REBOOT] = "reboot-force", + [CAD_BURST_ACTION_POWEROFF] = "poweroff-force", +}; + +DEFINE_STRING_TABLE_LOOKUP(cad_burst_action, CADBurstAction); diff --git a/src/core/manager.h b/src/core/manager.h index 3e855db466..42be1fc437 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -64,6 +64,14 @@ typedef enum ManagerExitCode { _MANAGER_EXIT_CODE_INVALID = -1 } ManagerExitCode; +typedef enum CADBurstAction { + CAD_BURST_ACTION_IGNORE, + CAD_BURST_ACTION_REBOOT, + CAD_BURST_ACTION_POWEROFF, + _CAD_BURST_ACTION_MAX, + _CAD_BURST_ACTION_INVALID = -1 +} CADBurstAction; + typedef enum StatusType { STATUS_TYPE_EPHEMERAL, STATUS_TYPE_NORMAL, @@ -300,8 +308,9 @@ struct Manager { /* Used for processing polkit authorization responses */ Hashmap *polkit_registry; - /* When the user hits C-A-D more than 7 times per 2s, reboot immediately... */ + /* When the user hits C-A-D more than 7 times per 2s, do something immediately... */ RateLimit ctrl_alt_del_ratelimit; + CADBurstAction cad_burst_action; }; int manager_new(SystemdRunningAs running_as, bool test_run, Manager **m); @@ -372,3 +381,6 @@ ManagerState manager_state(Manager *m); const char *manager_state_to_string(ManagerState m) _const_; ManagerState manager_state_from_string(const char *s) _pure_; + +const char *cad_burst_action_to_string(CADBurstAction a) _const_; +CADBurstAction cad_burst_action_from_string(const char *s) _pure_; diff --git a/src/core/system.conf b/src/core/system.conf index 231609033b..a11f599038 100644 --- a/src/core/system.conf +++ b/src/core/system.conf @@ -20,6 +20,7 @@ #CrashShell=no #ShowStatus=yes #CrashChVT=1 +#CtrlAltDelBurstAction=reboot-force #CPUAffinity=1 2 #JoinControllers=cpu,cpuacct net_cls,net_prio #RuntimeWatchdogSec=0