You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
8.5 KiB
201 lines
8.5 KiB
From be9fad86ae9ab721cd295210962da85706b839e9 Mon Sep 17 00:00:00 2001 |
|
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= <lnykryn@redhat.com> |
|
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 39d19bc71..236c20d5f 100644 |
|
--- a/man/systemd-system.conf.xml |
|
+++ b/man/systemd-system.conf.xml |
|
@@ -101,6 +101,17 @@ |
|
arguments.</para></listitem> |
|
</varlistentry> |
|
|
|
+ <varlistentry> |
|
+ <term><varname>CtrlAltDelBurstAction=</varname></term> |
|
+ |
|
+ <listitem><para>Defines what action will be performed |
|
+ if user presses Ctr-Alt-Delete more than 7 times in 2s. |
|
+ Can be set to <literal>reboot-force</literal>, <literal>poweroff-force</literal> |
|
+ or disabled with <literal>ignore</literal>. Defaults to |
|
+ <literal>reboot-force</literal>. |
|
+ </para></listitem> |
|
+ </varlistentry> |
|
+ |
|
<varlistentry> |
|
<term><varname>CPUAffinity=</varname></term> |
|
|
|
diff --git a/src/core/main.c b/src/core/main.c |
|
index c9d8ce4a4..6ac9c9d44 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 6d045fdf3..9048dde96 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 3e855db46..42be1fc43 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 231609033..a11f59903 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
|
|
|