diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index b96ba0fe33..88f633138e 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -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); diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c index 0a0bb35fb5..cef3ec7fd5 100644 --- a/src/udev/udevadm-control.c +++ b/src/udev/udevadm-control.c @@ -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; } diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index bb6f03d540..0a38e6ee06 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -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; } diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index f2944b02f3..78c9520017 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -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; diff --git a/test/units/TEST-17-UDEV.IMPORT.sh b/test/units/TEST-17-UDEV.IMPORT.sh index f09b171066..f2f9a4100e 100755 --- a/test/units/TEST-17-UDEV.IMPORT.sh +++ b/test/units/TEST-17-UDEV.IMPORT.sh @@ -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 diff --git a/test/units/TEST-17-UDEV.database.sh b/test/units/TEST-17-UDEV.database.sh index 56a79a665b..ed50daa5ad 100755 --- a/test/units/TEST-17-UDEV.database.sh +++ b/test/units/TEST-17-UDEV.database.sh @@ -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 diff --git a/test/units/TEST-17-UDEV.sanity-check.sh b/test/units/TEST-17-UDEV.sanity-check.sh index 6246638fc9..18326c03ad 100755 --- a/test/units/TEST-17-UDEV.sanity-check.sh +++ b/test/units/TEST-17-UDEV.sanity-check.sh @@ -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