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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user