]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev-rules: extend the check for conflicting expressions
authorDmitry V. Levin <ldv@strace.io>
Fri, 24 Mar 2023 08:00:00 +0000 (08:00 +0000)
committerDmitry V. Levin <ldv@strace.io>
Mon, 27 Mar 2023 10:00:30 +0000 (10:00 +0000)
Log an error when a rule line contains the following kind of conflicting
match expressions:

  KEY=="foo*", KEY=="bar*"

src/udev/udev-rules.c
test/units/testsuite-17.11.sh

index ecf5989312865e45aa9a4b4690ec2eeb369f9642..c234c265ee1f059bb6bf0225de2788c0ee18c3cd 100644 (file)
@@ -1348,17 +1348,34 @@ static bool nulstr_tokens_conflict(const UdevRuleToken *a, const UdevRuleToken *
               a->op == b->op &&
               a->op == OP_MATCH &&
               a->match_type == b->match_type &&
-              a->match_type == MATCH_TYPE_PLAIN &&
               a->attr_subst_type == b->attr_subst_type &&
               a->attr_match_remove_trailing_whitespace == b->attr_match_remove_trailing_whitespace &&
               token_type_and_data_eq(a, b)))
                 return false;
 
-        NULSTR_FOREACH(i, a->value)
-                if (nulstr_contains(b->value, i))
-                        return false;
+        if (a->match_type == MATCH_TYPE_PLAIN) {
+                NULSTR_FOREACH(i, a->value)
+                        if (nulstr_contains(b->value, i))
+                                return false;
+                return true;
+        }
 
-        return true;
+        if (a->match_type == MATCH_TYPE_GLOB) {
+                NULSTR_FOREACH(i, a->value) {
+                        size_t i_n = strcspn(i, GLOB_CHARS);
+                        if (i_n == 0)
+                                return false;
+                        NULSTR_FOREACH(j, b->value) {
+                                size_t j_n = strcspn(j, GLOB_CHARS);
+                                if (j_n == 0 || strneq(i, j, MIN(i_n, j_n)))
+                                        return false;
+                        }
+
+                }
+                return true;
+        }
+
+        return false;
 }
 
 static void udev_check_unused_labels(UdevRuleLine *line) {
index c7c793e71ba2c12e0f474d4d0225e8ebe4033fa1..65c47dbcf9333375cc5b4f0e94bcaec9458a1127 100755 (executable)
@@ -282,6 +282,8 @@ test_syntax_error 'KERNEL=="a|b", KERNEL=="c|d|e", NAME="f"' 'conflicting match
 # shellcheck disable=SC2016
 test_syntax_error 'ENV{DISKSEQ}=="?*", ENV{DEVTYPE}!="partition", ENV{DISKSEQ}!="?*", ENV{ID_IGNORE_DISKSEQ}!="1", SYMLINK+="disk/by-diskseq/$env{DISKSEQ}"' \
                   'conflicting match expressions, the line takes no effect'
+test_syntax_error 'ACTION=="a*", ACTION=="bc*", NAME="d"' 'conflicting match expressions, the line takes no effect'
+test_syntax_error 'ACTION=="a*|bc*", ACTION=="d*|ef*", NAME="g"' 'conflicting match expressions, the line takes no effect'
 test_syntax_error 'KERNEL!="", KERNEL=="?*", NAME="a"' 'duplicate expressions'
 test_syntax_error 'KERNEL=="|a|b", KERNEL=="b|a|", NAME="c"' 'duplicate expressions'
 # shellcheck disable=SC2016
@@ -302,6 +304,8 @@ KERNEL=="a|b", KERNEL=="a|c", NAME="d"
 KERNEL=="a|b", KERNEL!="a|c", NAME="d"
 KERNEL!="a", KERNEL!="b", NAME="c"
 KERNEL=="|a", KERNEL=="|b", NAME="c"
+KERNEL=="*", KERNEL=="a*", NAME="b"
+KERNEL=="a*", KERNEL=="c*|ab*", NAME="d"
 EOF
 assert_0 "${rules}"