udev: fix several reproducible command handling issues (#42958)

This PR fixes several independent udev command and rule handling issues.
Each commit contains the corresponding reproducer and fix details.
This commit is contained in:
Yu Watanabe
2026-07-10 20:04:51 +09:00
committed by GitHub
7 changed files with 32 additions and 7 deletions
+3 -3
View File
@@ -849,7 +849,7 @@ static int parse_token(
} else
r = rule_line_add_token(rule_line, TK_M_ENV, op, value, attr, is_case_insensitive, token_str);
} else if (streq(key, "CONST")) {
if (isempty(attr) || !STR_IN_SET(attr, "arch", "virt"))
if (isempty(attr) || !STR_IN_SET(attr, "arch", "virt", "cvm"))
return log_line_invalid_attr(rule_line, key);
if (!is_match)
return log_line_invalid_op(rule_line, key);
@@ -2482,14 +2482,14 @@ static int udev_rule_apply_token_to_event(
/* Drop the last line. */
bool found = false;
for (char *p = PTR_SUB1(buf + strlen(buf), buf); p; p = PTR_SUB1(p, buf))
for (char *p = PTR_SUB1(result + strlen(result), result); p; p = PTR_SUB1(p, result))
if (strchr(NEWLINE, *p)) {
*p = '\0';
found = true;
break;
}
if (!found)
buf[0] = '\0';
result[0] = '\0';
}
r = strv_split_newlines_full(&lines, result, EXTRACT_RETAIN_ESCAPE);
+3
View File
@@ -125,6 +125,9 @@ static int parse_argv(int argc, char *argv[]) {
r = safe_atou(opts.arg, &i);
if (r < 0)
return log_error_errno(r, "Failed to parse maximum number of children '%s': %m", opts.arg);
if (i > INT_MAX)
return log_error_errno(SYNTHETIC_ERRNO(ERANGE),
"Maximum number of children is too large: %s", opts.arg);
arg_max_children = i;
break;
}
+1 -1
View File
@@ -99,7 +99,7 @@ int verb_hwdb_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
}
if (arg_test)
return hwdb_query(arg_test, NULL);
return hwdb_query(arg_test, arg_root);
return 0;
}
+2 -3
View File
@@ -655,16 +655,16 @@ static void cleanup_dir(DIR *dir, mode_t mask, int depth) {
* entries for devices in /run/udev/data (such as "b8:16"), and removes
* all files except those that haven't been deleted in /run/udev/data
* (i.e. they were skipped during db cleanup because of the db_persist flag).
* If the database directory does not exist, all entries are considered stale.
*/
static void cleanup_dir_after_db_cleanup(DIR *dir, DIR *datadir) {
assert(dir);
assert(datadir);
FOREACH_DIRENT_ALL(dent, dir, break) {
if (dot_or_dot_dot(dent->d_name))
continue;
if (faccessat(dirfd(datadir), dent->d_name, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
if (datadir && faccessat(dirfd(datadir), dent->d_name, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
/* The corresponding udev database file still exists.
* Assuming the persistent flag is set for the database. */
continue;
@@ -675,7 +675,6 @@ static void cleanup_dir_after_db_cleanup(DIR *dir, DIR *datadir) {
static void cleanup_dirs_after_db_cleanup(DIR *dir, DIR *datadir) {
assert(dir);
assert(datadir);
FOREACH_DIRENT_ALL(dent, dir, break) {
struct stat stats;
+11
View File
@@ -17,6 +17,17 @@ test -f /run/udev/data/c1:3
udevadm info /dev/null | grep 'E: HOGE=aa\\x20\\x20\\x20bb' >/dev/null
udevadm info /dev/null | grep 'E: FOO=\\x20aaa\\x20' >/dev/null
cat >/run/udev/rules.d/50-testsuite.rules <<'EOF'
SUBSYSTEM=="mem", KERNEL=="null", OPTIONS="log_level=debug"
ACTION=="add", SUBSYSTEM=="mem", KERNEL=="null", IMPORT{program}="/bin/sh -c 'printf \"TRUNCATED_OK=yes\nTRUNCATED_BAD=\"; i=0; while [ \"$i\" -lt 20000 ]; do printf A; i=$((i + 1)); done'"
EOF
udevadm control --reload
SYSTEMD_LOG_LEVEL=debug udevadm trigger --verbose --settle --action add /dev/null
udevadm info /dev/null | grep 'E: TRUNCATED_OK=yes' >/dev/null
(! udevadm info /dev/null | grep 'E: TRUNCATED_BAD=' >/dev/null)
rm /run/udev/rules.d/50-testsuite.rules
udevadm control --reload
+11
View File
@@ -15,4 +15,15 @@ udevadm wait --timeout=10 --removed --settle "/sys/class/net/$IFNAME"
# CHeck if the database file is removed.
[[ ! -e "/run/udev/data/n$IFINDEX" ]]
unshare --mount --propagation private bash -eux <<'EOF'
mount -t tmpfs tmpfs /run/udev
mkdir -p /run/udev/links/test /run/udev/tags/test
touch /run/udev/links/test/stale /run/udev/tags/test/stale
udevadm info --cleanup-db
[[ ! -e /run/udev/links/test ]]
[[ ! -e /run/udev/tags/test ]]
EOF
exit 0
+1
View File
@@ -55,6 +55,7 @@ udevadm control -l notice
udevadm control --log-level info
udevadm control --log-level debug
(! udevadm control -l hello)
(! udevadm control -m 2147483648)
# Check if processing queued events has been stopped.
udevadm control --stop-exec-queue