mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-12 09:17:44 +03:00
Merge pull request #15870 from poettering/proc-cmdline-efi-fix
udev /proc/cmdline handling fixes
This commit is contained in:
commit
7c15a55f8b
@ -119,6 +119,7 @@ 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. */
|
||||
|
||||
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");
|
||||
@ -128,6 +129,8 @@ int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, ProcCmdlineF
|
||||
return r;
|
||||
|
||||
line = mfree(line);
|
||||
}
|
||||
|
||||
r = proc_cmdline(&line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -218,7 +221,7 @@ static int cmdline_get_key(const char *line, const char *key, ProcCmdlineFlags f
|
||||
}
|
||||
|
||||
int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **ret_value) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
_cleanup_free_ char *line = NULL, *v = NULL;
|
||||
int r;
|
||||
|
||||
/* Looks for a specific key on the kernel command line and (with lower priority) the EFI variable.
|
||||
@ -245,14 +248,27 @@ int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **ret_val
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = cmdline_get_key(line, key, flags, ret_value);
|
||||
if (r != 0) /* Either error or true if found. */
|
||||
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;
|
||||
if (r > 0) {
|
||||
if (ret_value)
|
||||
*ret_value = TAKE_PTR(v);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
line = mfree(line);
|
||||
r = systemd_efi_options_variable(&line);
|
||||
if (r == -ENODATA)
|
||||
if (r == -ENODATA) {
|
||||
if (ret_value)
|
||||
*ret_value = NULL;
|
||||
|
||||
return false; /* Not found */
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -286,6 +302,7 @@ int proc_cmdline_get_bool(const char *key, bool *ret) {
|
||||
|
||||
int proc_cmdline_get_key_many_internal(ProcCmdlineFlags flags, ...) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
bool processing_efi = true;
|
||||
const char *p;
|
||||
va_list ap;
|
||||
int r, ret = 0;
|
||||
@ -296,9 +313,11 @@ int proc_cmdline_get_key_many_internal(ProcCmdlineFlags flags, ...) {
|
||||
|
||||
/* This call may clobber arguments on failure! */
|
||||
|
||||
r = proc_cmdline(&line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
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 (;;) {
|
||||
@ -307,8 +326,22 @@ int proc_cmdline_get_key_many_internal(ProcCmdlineFlags flags, ...) {
|
||||
r = proc_cmdline_extract_first(&p, &word, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
if (r == 0) {
|
||||
/* We finished with this command line. If this was the EFI one, then let's proceed with the regular one */
|
||||
if (processing_efi) {
|
||||
processing_efi = false;
|
||||
|
||||
line = mfree(line);
|
||||
r = proc_cmdline(&line);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = line;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
va_start(ap, flags);
|
||||
|
||||
|
@ -9,6 +9,7 @@ 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_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);
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user