Submitted By: Douglas R. Reno Date: 2019-09-20 Initial Package Version: 243 Upstream Status: Applied Origin: https://github.com/systemd/systemd/issues/13518 Description: Fixes a bug in systemd-243 where devices in the evdev class of udev do not have device nodes created at startup. diff -Naurp systemd-243.orig/src/udev/udev-rules.c systemd-243/src/udev/udev-rules.c --- systemd-243.orig/src/udev/udev-rules.c 2019-09-03 04:27:19.000000000 -0500 +++ systemd-243/src/udev/udev-rules.c 2019-09-20 11:14:17.904506115 -0500 @@ -43,10 +43,12 @@ typedef enum { } UdevRuleOperatorType; typedef enum { - MATCH_TYPE_EMPTY, /* empty string */ - MATCH_TYPE_PLAIN, /* no special characters */ - MATCH_TYPE_GLOB, /* shell globs ?,*,[] */ - MATCH_TYPE_SUBSYSTEM, /* "subsystem", "bus", or "class" */ + MATCH_TYPE_EMPTY, /* empty string */ + MATCH_TYPE_PLAIN, /* no special characters */ + MATCH_TYPE_PLAIN_WITH_EMPTY, /* no special characters with empty string, e.g., "|foo" */ + MATCH_TYPE_GLOB, /* shell globs ?,*,[] */ + MATCH_TYPE_GLOB_WITH_EMPTY, /* shell globs ?,*,[] with empty string, e.g., "|foo*" */ + MATCH_TYPE_SUBSYSTEM, /* "subsystem", "bus", or "class" */ _MATCH_TYPE_MAX, _MATCH_TYPE_INVALID = -1 } UdevRuleMatchType; @@ -431,35 +433,30 @@ static int rule_line_add_token(UdevRuleL if (type < TK_M_TEST || type == TK_M_RESULT) { /* Convert value string to nulstr. */ - len = strlen(value); - if (len > 1 && (value[len - 1] == '|' || strstr(value, "||"))) { - /* In this case, just replacing '|' -> '\0' does not work... */ - _cleanup_free_ char *tmp = NULL; - char *i, *j; - bool v = true; + bool bar = true, empty = false; + char *a, *b; - tmp = strdup(value); - if (!tmp) - return log_oom(); - - for (i = tmp, j = value; *i != '\0'; i++) - if (*i == '|') - v = true; - else { - if (v) { - *j++ = '\0'; - v = false; - } - *j++ = *i; - } - j[0] = j[1] = '\0'; - } else { - /* Simple conversion. */ - char *i; - - for (i = value; *i != '\0'; i++) - if (*i == '|') - *i = '\0'; + for (a = b = value; *a != '\0'; a++) { + if (*a != '|') { + *b++ = *a; + bar = false; + } else { + if (bar) + empty = true; + else + *b++ = '\0'; + bar = true; + } + } + *b = '\0'; + if (bar) + empty = true; + + if (empty) { + if (match_type == MATCH_TYPE_GLOB) + match_type = MATCH_TYPE_GLOB_WITH_EMPTY; + if (match_type == MATCH_TYPE_PLAIN) + match_type = MATCH_TYPE_PLAIN_WITH_EMPTY; } } } @@ -1325,7 +1322,17 @@ static bool token_match_string(UdevRuleT match = isempty(str); break; case MATCH_TYPE_SUBSYSTEM: - value = "subsystem\0class\0bus\0"; + NULSTR_FOREACH(i, "subsystem\0class\0bus\0") + if (streq(i, str)) { + match = true; + break; + } + break; + case MATCH_TYPE_PLAIN_WITH_EMPTY: + if (isempty(str)) { + match = true; + break; + } _fallthrough_; case MATCH_TYPE_PLAIN: NULSTR_FOREACH(i, value) @@ -1334,6 +1341,12 @@ static bool token_match_string(UdevRuleT break; } break; + case MATCH_TYPE_GLOB_WITH_EMPTY: + if (isempty(str)) { + match = true; + break; + } + _fallthrough_; case MATCH_TYPE_GLOB: NULSTR_FOREACH(i, value) if ((fnmatch(i, str, 0) == 0)) { diff -Naurp systemd-243.orig/test/udev-test.pl systemd-243/test/udev-test.pl --- systemd-243.orig/test/udev-test.pl 2019-09-03 04:27:19.000000000 -0500 +++ systemd-243/test/udev-test.pl 2019-09-20 11:10:28.252116973 -0500 @@ -1259,6 +1259,72 @@ KERNEL=="ttyACM0a|nothing", SYMLINK+="wr EOF }, { + desc => "test multi matches 5", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", + not_exp_name => "bad", + rules => < "test multi matches 6", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", + not_exp_name => "bad", + rules => < "test multi matches 7", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", + not_exp_name => "bad", + rules => < "test multi matches 8", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", + not_exp_name => "bad", + rules => < "test multi matches 9", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", + not_exp_name => "bad", + rules => < "test multi matches 10", + devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", + exp_name => "found", + not_exp_name => "bad", + rules => < "IMPORT parent test sequence 1/2 (keep)", devpath => "/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda", exp_name => "parent",