diff --git a/meta/recipes-core/systemd/systemd-tools-native_259.5.bb b/meta/recipes-core/systemd/systemd-tools-native_259.5.bb
index d25e36ff3c0..744e874a1a2 100644
--- a/meta/recipes-core/systemd/systemd-tools-native_259.5.bb
+++ b/meta/recipes-core/systemd/systemd-tools-native_259.5.bb
@@ -4,6 +4,8 @@ require systemd.inc
 
 SUMMARY = "native tools from systemd"
 
+SRC_URI += "file://0001-hwdb-strip-the-root-from-filenames-when-generating-h.patch"
+
 # We don't actually need jinja to generate code, but it's checked for at configure time
 DEPENDS = "gperf-native python3-jinja2-native"
 
@@ -12,16 +14,27 @@ inherit pkgconfig meson native
 # Disable everything that is auto-detected by default
 EXTRA_OEMESON += "--auto-features disabled"
 
-# Link systemctl statically
-EXTRA_OEMESON += "-Dlink-systemctl-shared=false"
+# Link the binaries statically as we don't install libsystemd-shared.so
+EXTRA_OEMESON += "-Dlink-systemctl-shared=false -Dlink-udev-shared=false"
 
 # Ensure unused build paths are not in the binary
 EXTRA_OEMESON += "-Dsysvinit-path= -Dsysvrcnd-path="
 
-# Systemctl is supposed to operate on target, but the target sysroot is not
-# determined at run-time, but rather set during configure
-# More details are here https://github.com/systemd/systemd/issues/35897#issuecomment-2665405887
-EXTRA_OEMESON += "--sysconfdir ${sysconfdir_native}"
+# Target-absolute paths that satisfy both tools from one meson configure:
+#  - systemd-hwdb needs prefix=/usr so the compiled-in UDEVLIBEXECDIR
+#    (/usr/lib/udev) matches the target rootfs layout, letting
+#    "update --root $D --usr" find hwdb.d sources and write hwdb.bin there.
+#  - systemctl needs sysconfdir=/etc; it operates on the target rootfs but the
+#    sysroot is fixed at configure time rather than run time.
+#    See https://github.com/systemd/systemd/issues/35897#issuecomment-2665405887
+EXTRA_OEMESON += "--prefix /usr --sysconfdir /etc"
+# TODO libdir?
 
-MESON_TARGET = "systemctl"
+MESON_TARGET = "systemctl systemd-hwdb"
 MESON_INSTALL_TAGS = "systemctl"
+
+do_install:append() {
+    # Can't install this with a tag "hwdb" also tries to install the hwdb
+    # itself, and there's no separate tag for systemd-hwdb.
+    install ${B}/systemd-hwdb ${D}${bindir}/systemd-hwdb
+}
diff --git a/meta/recipes-core/systemd/systemd/0001-hwdb-strip-the-root-from-filenames-when-generating-h.patch b/meta/recipes-core/systemd/systemd/0001-hwdb-strip-the-root-from-filenames-when-generating-h.patch
new file mode 100644
index 00000000000..f11199c553b
--- /dev/null
+++ b/meta/recipes-core/systemd/systemd/0001-hwdb-strip-the-root-from-filenames-when-generating-h.patch
@@ -0,0 +1,40 @@
+From 0031715c560e8138cc320f017a0a2c7160b1f7fe Mon Sep 17 00:00:00 2001
+From: Ross Burton <ross.burton@arm.com>
+Date: Fri, 17 Jul 2026 17:25:31 +0100
+Subject: [PATCH] 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.
+
+Upstream-Status: Backport [https://github.com/systemd/systemd/pull/43062]
+Signed-off-by: Ross Burton <ross.burton@arm.com>
+---
+ src/shared/hwdb-util.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/shared/hwdb-util.c b/src/shared/hwdb-util.c
+index b42681a289..5386b4e9f4 100644
+--- a/src/shared/hwdb-util.c
++++ b/src/shared/hwdb-util.c
+@@ -632,9 +632,11 @@ int hwdb_update(const char *root, const char *hwdb_bin_dir, bool strict, bool co
+ 
+         FOREACH_ARRAY(i, files, n_files) {
+                 ConfFile *c = *i;
++                char *path_in_root;
+ 
+                 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));
++                path_in_root = path_startswith_full(c->original_path, empty_to_root(root), PATH_STARTSWITH_RETURN_LEADING_SLASH);
++                RET_GATHER(ret, import_file(trie, c->fd, path_in_root, file_priority++, compat));
+         }
+ 
+         strbuf_complete(trie->strings);
+-- 
+2.43.0
+
