From 860e2a11154b4065691c882dcf05af3f5a14485a Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Fri, 24 Mar 2023 08:00:00 +0000 Subject: [PATCH] udev-rules: extend the check for conflicting expressions Log an error when a rule line contains the following kind of conflicting match expressions: KEY=="foo*", KEY=="bar*" --- src/udev/udev-rules.c | 27 ++++++++++++++++++++++----- test/units/testsuite-17.11.sh | 4 ++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index ecf5989312..c234c265ee 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -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) { diff --git a/test/units/testsuite-17.11.sh b/test/units/testsuite-17.11.sh index c7c793e71b..65c47dbcf9 100755 --- a/test/units/testsuite-17.11.sh +++ b/test/units/testsuite-17.11.sh @@ -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}" -- 2.25.1