]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
proc-cmdline: make checking of EFI options variable optional 15870/head
authorLennart Poettering <lennart@poettering.net>
Wed, 20 May 2020 17:22:09 +0000 (19:22 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 20 May 2020 17:22:09 +0000 (19:22 +0200)
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
src/basic/proc-cmdline.c
src/basic/proc-cmdline.h
src/udev/udev-rules.c

index 5545543fbddf58552c37c35952d4f34ddef82937..eb45682f3a4a6cdaf10422649cc5e75f552d73ab 100644 (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 (;;) {
index 275f46c89ec22987ec77eff2beb182de60683c0b..077d3a99fb91e72fc66aa55eb92a02576358a2d2 100644 (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);
index 4c955b0c079c3ee0a67db3a3001d681800ba871f..e9975030aae3cf518ed44a7cb2d54150b432efe1 100644 (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",