From d024c58b8e9c0ddbed8e02604758b69ae3bd63a2 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Mon, 20 Jul 2026 10:38:43 +0100 Subject: [PATCH 1/2] hwdb: add debug logging for the output filename It's useful to see exactly what file was written to when updating the HWDB. --- src/shared/hwdb-util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/hwdb-util.c b/src/shared/hwdb-util.c index b42681a289..b3c48e2a5f 100644 --- a/src/shared/hwdb-util.c +++ b/src/shared/hwdb-util.c @@ -418,6 +418,7 @@ static int trie_store(struct trie *trie, const char *filename, bool compat) { /* write succeeded */ log_debug("=== trie on-disk ==="); + log_debug("filename: %s", filename); log_debug("size: %8"PRIi64" bytes", size); log_debug("header: %8zu bytes", sizeof(struct trie_header_f)); log_debug("nodes: %8"PRIu64" bytes (%8"PRIu64")", From ab9be70e94dad2166b4a5b2cf80f6f46ffc9e2c3 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Fri, 17 Jul 2026 17:25:31 +0100 Subject: [PATCH 2/2] hwdb: strip the root from filenames when generating hwdb.bin The modern hwdb.bin format contains the filenames of the input data that makes up the database. This is useful but in offline builds where --root is used, the filenames are the full build paths including the specified root. This introduces build paths and thus information leakage and non-reproducible data. Solve this by stripping the root prefix off the original path when passing to import_file. Add TEST-17-UDEV.hwdb.sh to verify that hwdb.bin files contain the path inside the root, but not the path of the root. --- src/shared/hwdb-util.c | 25 +++++++++++++++++++---- test/units/TEST-17-UDEV.hwdb.sh | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) create mode 100755 test/units/TEST-17-UDEV.hwdb.sh diff --git a/src/shared/hwdb-util.c b/src/shared/hwdb-util.c index b3c48e2a5f..f6415694e1 100644 --- a/src/shared/hwdb-util.c +++ b/src/shared/hwdb-util.c @@ -578,7 +578,7 @@ static int import_file(struct trie *trie, int fd, const char *filename, uint16_t } int hwdb_update(const char *root, const char *hwdb_bin_dir, bool strict, bool compat) { - _cleanup_free_ char *hwdb_bin = NULL; + _cleanup_free_ char *hwdb_bin = NULL, *root_abs = NULL; _cleanup_(trie_freep) struct trie *trie = NULL; uint16_t file_priority = 1; int r, ret = 0; @@ -588,7 +588,18 @@ int hwdb_update(const char *root, const char *hwdb_bin_dir, bool strict, bool co * source. If true, then hwdb.bin will be created without the information. systemd-hwdb command * should set the argument false, and 'udevadm hwdb' command should set it true. */ - hwdb_bin = path_join(root, hwdb_bin_dir ?: "/etc/udev", "hwdb.bin"); + r = empty_or_root_harder_to_null(&root); + if (r < 0) + return log_error_errno(r, "Failed to determine if '%s' points to the root directory: %m", strempty(root)); + + if (root) { + r = path_make_absolute_cwd(root, &root_abs); + if (r < 0) + return log_error_errno(r, "Failed to make '%s' absolute: %m", root); + path_simplify(root_abs); + } + + hwdb_bin = path_join(root_abs, hwdb_bin_dir ?: "/etc/udev", "hwdb.bin"); if (!hwdb_bin) return -ENOMEM; @@ -613,7 +624,7 @@ int hwdb_update(const char *root, const char *hwdb_bin_dir, bool strict, bool co CLEANUP_ARRAY(files, n_files, conf_file_free_array); - r = conf_files_list_strv_full(".hwdb", root, + r = conf_files_list_strv_full(".hwdb", root_abs, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN, conf_file_dirs, &files, &n_files); if (r < 0) @@ -635,7 +646,13 @@ int hwdb_update(const char *root, const char *hwdb_bin_dir, bool strict, bool co ConfFile *c = *i; log_debug("Reading file \"%s\" -> \"%s\"", c->original_path, c->resolved_path); - RET_GATHER(ret, import_file(trie, c->fd, c->original_path, file_priority++, compat)); + + const char *path_in_root = path_startswith_full(c->original_path, + empty_to_root(root_abs), + PATH_STARTSWITH_RETURN_LEADING_SLASH); + assert(path_in_root); + + RET_GATHER(ret, import_file(trie, c->fd, path_in_root, file_priority++, compat)); } strbuf_complete(trie->strings); diff --git a/test/units/TEST-17-UDEV.hwdb.sh b/test/units/TEST-17-UDEV.hwdb.sh new file mode 100755 index 0000000000..c953fbdb27 --- /dev/null +++ b/test/units/TEST-17-UDEV.hwdb.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +if ! command -v systemd-hwdb >/dev/null; then + echo "systemd-hwdb not found, skipping." + exit 0 +fi + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +at_exit() ( + set +e + + [[ -d "$ROOTFS" ]] && rm -rf "$ROOTFS" +) +trap at_exit EXIT + +ROOTFS="$(mktemp -d -t test-17-udev-hwdb.XXXX)" +HWDB=$ROOTFS/usr/lib/udev/hwdb.d + +mkdir -p "$HWDB" +cat >"$HWDB/99-test.hwdb" <