proc-cmdline: make checking of EFI options variable optional

And do not use it in the IMPORT{cmdline} udev code. Wherever we expose
direct interfaces to check the kernel cmdline, let's not consult our
systemd-specific EFI variable, but strictly use the actual kernel
variable, because that's what we claim we do. i.e. it's fine to use the
EFI variable for our own settings, but for the generic APIs to the
kernel cmdline we should not use it.

Specifically, this applies to IMPORT{cmdline} and
ConditionKernelCommandLine=. In the latter case we weren#t checking the
EFI variable anyway, hence let's do the same for the udev case, too.

Fixes: #15739
This commit is contained in:
Lennart Poettering
2020-05-20 19:22:09 +02:00
parent 05a7827e87
commit 09835de3cc
3 changed files with 23 additions and 14 deletions

View File

@@ -119,15 +119,18 @@ int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, ProcCmdlineF
/* We parse the EFI variable first, because later settings have higher priority. */
r = systemd_efi_options_variable(&line);
if (r < 0 && r != -ENODATA)
log_debug_errno(r, "Failed to get SystemdOptions EFI variable, ignoring: %m");
if (!FLAGS_SET(flags, PROC_CMDLINE_IGNORE_EFI_OPTIONS)) {
r = systemd_efi_options_variable(&line);
if (r < 0 && r != -ENODATA)
log_debug_errno(r, "Failed to get SystemdOptions EFI variable, ignoring: %m");
r = proc_cmdline_parse_given(line, parse_item, data, flags);
if (r < 0)
return r;
r = proc_cmdline_parse_given(line, parse_item, data, flags);
if (r < 0)
return r;
line = mfree(line);
}
line = mfree(line);
r = proc_cmdline(&line);
if (r < 0)
return r;
@@ -245,6 +248,9 @@ int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **ret_val
if (r < 0)
return r;
if (FLAGS_SET(flags, PROC_CMDLINE_IGNORE_EFI_OPTIONS)) /* Shortcut */
return cmdline_get_key(line, key, flags, ret_value);
r = cmdline_get_key(line, key, flags, ret_value ? &v : NULL);
if (r < 0)
return r;
@@ -307,9 +313,11 @@ int proc_cmdline_get_key_many_internal(ProcCmdlineFlags flags, ...) {
/* This call may clobber arguments on failure! */
r = systemd_efi_options_variable(&line);
if (r < 0 && r != -ENODATA)
log_debug_errno(r, "Failed to get SystemdOptions EFI variable, ignoring: %m");
if (!FLAGS_SET(flags, PROC_CMDLINE_IGNORE_EFI_OPTIONS)) {
r = systemd_efi_options_variable(&line);
if (r < 0 && r != -ENODATA)
log_debug_errno(r, "Failed to get SystemdOptions EFI variable, ignoring: %m");
}
p = line;
for (;;) {

View File

@@ -6,9 +6,10 @@
#include "log.h"
typedef enum ProcCmdlineFlags {
PROC_CMDLINE_STRIP_RD_PREFIX = 1 << 0, /* automatically strip "rd." prefix if it is set (and we are in the initrd, since otherwise we'd not consider it anyway) */
PROC_CMDLINE_VALUE_OPTIONAL = 1 << 1, /* the value is optional (for boolean switches that can omit the value) */
PROC_CMDLINE_RD_STRICT = 1 << 2, /* ignore this in the initrd */
PROC_CMDLINE_STRIP_RD_PREFIX = 1 << 0, /* automatically strip "rd." prefix if it is set (and we are in the initrd, since otherwise we'd not consider it anyway) */
PROC_CMDLINE_VALUE_OPTIONAL = 1 << 1, /* the value is optional (for boolean switches that can omit the value) */
PROC_CMDLINE_RD_STRICT = 1 << 2, /* ignore this in the initrd */
PROC_CMDLINE_IGNORE_EFI_OPTIONS = 1 << 3, /* don't check systemd's private EFI variable */
} ProcCmdlineFlags;
typedef int (*proc_cmdline_parse_t)(const char *key, const char *value, void *data);

View File

@@ -1814,7 +1814,7 @@ static int udev_rule_apply_token_to_event(
case TK_M_IMPORT_CMDLINE: {
_cleanup_free_ char *value = NULL;
r = proc_cmdline_get_key(token->value, PROC_CMDLINE_VALUE_OPTIONAL, &value);
r = proc_cmdline_get_key(token->value, PROC_CMDLINE_VALUE_OPTIONAL|PROC_CMDLINE_IGNORE_EFI_OPTIONS, &value);
if (r < 0)
return log_rule_error_errno(dev, rules, r,
"Failed to read '%s' option from /proc/cmdline: %m",