From 58b86ce5535860d93119a4cc6e19a0aac640a3eb Mon Sep 17 00:00:00 2001 From: CMGS Date: Fri, 3 Jul 2026 23:52:04 +0800 Subject: [PATCH] fix(agent): drop baked /var/lib/dbus/machine-id so regen yields a fresh id regenMachineID truncated /etc/machine-id, but systemd-machine-id-setup's source order falls back to a baked-in regular-file /var/lib/dbus/machine-id and re-adopts the old id. dropStaleDBusMachineID removes that copy first; a symlink into /etc/machine-id or a missing file is left alone, and any other lstat error is surfaced so regen fails loudly instead of silently reusing the old id. CRNG reseed was never affected. --- agent/reseed_linux.go | 24 ++++++++++++++++++ agent/reseed_linux_test.go | 51 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 agent/reseed_linux_test.go diff --git a/agent/reseed_linux.go b/agent/reseed_linux.go index 960e9d7..8502121 100644 --- a/agent/reseed_linux.go +++ b/agent/reseed_linux.go @@ -24,6 +24,7 @@ const ( urandomPath = "/dev/urandom" systemdRandomSeed = "/var/lib/systemd/random-seed" machineIDPath = "/etc/machine-id" + dbusMachineIDPath = "/var/lib/dbus/machine-id" ) // runReseed injects host-fed entropy and forces a CRNG reseed so clones don't @@ -117,6 +118,9 @@ func regenMachineID(ctx context.Context) error { if err := os.Truncate(machineIDPath, 0); err != nil { return fmt.Errorf("truncate %s: %w", machineIDPath, err) } + if err := dropStaleDBusMachineID(dbusMachineIDPath); err != nil { + return err + } if path, err := exec.LookPath("systemd-machine-id-setup"); err == nil { if err := exec.CommandContext(ctx, path).Run(); err == nil { //nolint:gosec // path resolved by LookPath for a fixed binary name, not user input return nil @@ -126,6 +130,26 @@ func regenMachineID(ctx context.Context) error { return writeRandomMachineID() } +// dropStaleDBusMachineID removes a baked regular-file D-Bus copy that +// systemd-machine-id-setup would re-adopt; a symlink or missing file is left +// alone, and any other lstat error is surfaced so regen fails loudly. +func dropStaleDBusMachineID(path string) error { + fi, err := os.Lstat(path) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return nil + } + return fmt.Errorf("lstat %s: %w", path, err) + } + if !fi.Mode().IsRegular() { + return nil + } + if err := os.Remove(path); err != nil { + return fmt.Errorf("remove %s: %w", path, err) + } + return nil +} + // writeRandomMachineID is the fallback when systemd-machine-id-setup is // unavailable: a fresh random id, matching /etc/machine-id's own format. func writeRandomMachineID() error { diff --git a/agent/reseed_linux_test.go b/agent/reseed_linux_test.go new file mode 100644 index 0000000..a210878 --- /dev/null +++ b/agent/reseed_linux_test.go @@ -0,0 +1,51 @@ +//go:build linux + +package agent + +import ( + "errors" + "io/fs" + "os" + "path/filepath" + "testing" +) + +func TestDropStaleDBusMachineID(t *testing.T) { + t.Run("regular file is removed", func(t *testing.T) { + path := filepath.Join(t.TempDir(), "machine-id") + if err := os.WriteFile(path, []byte("oldid\n"), 0o444); err != nil { + t.Fatalf("seed: %v", err) + } + if err := dropStaleDBusMachineID(path); err != nil { + t.Fatalf("dropStaleDBusMachineID: %v", err) + } + if _, err := os.Lstat(path); !errors.Is(err, fs.ErrNotExist) { + t.Errorf("regular file still present (err=%v), want removed", err) + } + }) + + t.Run("symlink is preserved", func(t *testing.T) { + dir := t.TempDir() + target := filepath.Join(dir, "etc-machine-id") + if err := os.WriteFile(target, []byte("id\n"), 0o444); err != nil { + t.Fatalf("seed target: %v", err) + } + link := filepath.Join(dir, "machine-id") + if err := os.Symlink(target, link); err != nil { + t.Fatalf("symlink: %v", err) + } + if err := dropStaleDBusMachineID(link); err != nil { + t.Fatalf("dropStaleDBusMachineID: %v", err) + } + if fi, err := os.Lstat(link); err != nil || fi.Mode()&os.ModeSymlink == 0 { + t.Errorf("symlink not preserved (fi=%v err=%v)", fi, err) + } + }) + + t.Run("missing file is a no-op", func(t *testing.T) { + path := filepath.Join(t.TempDir(), "does-not-exist") + if err := dropStaleDBusMachineID(path); err != nil { + t.Errorf("dropStaleDBusMachineID on missing file: %v, want nil", err) + } + }) +}