From 8a56d19c34cd4a8d4b8147c75ee50711aa587d67 Mon Sep 17 00:00:00 2001 From: proxyctl coordinator Date: Fri, 17 Jul 2026 11:42:37 +0800 Subject: [PATCH] test: prove profile diagnostics do not read symlink targets --- internal/profile/diagnostic_test.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/internal/profile/diagnostic_test.go b/internal/profile/diagnostic_test.go index 7503584..2c95ba9 100644 --- a/internal/profile/diagnostic_test.go +++ b/internal/profile/diagnostic_test.go @@ -6,6 +6,7 @@ import ( "strings" "syscall" "testing" + "time" "proxyctl/internal/profile" ) @@ -111,6 +112,9 @@ func TestReadOnlyLoadRejectsSymlinksWithoutReadingOrChangingVictim(t *testing.T) if err := os.WriteFile(victim, []byte(content), 0o640); err != nil { t.Fatal(err) } + if err := os.Chtimes(victim, time.Unix(1, 0), time.Now()); err != nil { + t.Fatal(err) + } before := fileIdentity(t, victim) path := test.path(t, t.TempDir(), victim) @@ -121,6 +125,10 @@ func TestReadOnlyLoadRejectsSymlinksWithoutReadingOrChangingVictim(t *testing.T) if strings.Contains(err.Error(), "parse Profile configuration") { t.Fatalf("ReadOnlyLoad followed and parsed the victim: %v", err) } + after := fileIdentity(t, victim) + if before != after { + t.Fatalf("victim was read or its metadata changed: before=%+v after=%+v", before, after) + } got, readErr := os.ReadFile(victim) if readErr != nil { t.Fatal(readErr) @@ -128,10 +136,6 @@ func TestReadOnlyLoadRejectsSymlinksWithoutReadingOrChangingVictim(t *testing.T) if string(got) != content { t.Fatalf("victim content changed to %q", got) } - after := fileIdentity(t, victim) - if before != after { - t.Fatalf("victim metadata changed: before=%+v after=%+v", before, after) - } if _, statErr := os.Lstat(path + ".lock"); !os.IsNotExist(statErr) { t.Fatalf("ReadOnlyLoad created a lock: %v", statErr) } @@ -140,9 +144,10 @@ func TestReadOnlyLoadRejectsSymlinksWithoutReadingOrChangingVictim(t *testing.T) } type diagnosticFileIdentity struct { - mode os.FileMode - uid uint32 - gid uint32 + mode os.FileMode + uid uint32 + gid uint32 + atime syscall.Timespec } func fileIdentity(t *testing.T, path string) diagnosticFileIdentity { @@ -155,5 +160,5 @@ func fileIdentity(t *testing.T, path string) diagnosticFileIdentity { if !ok { t.Fatalf("stat data has type %T", info.Sys()) } - return diagnosticFileIdentity{mode: info.Mode(), uid: stat.Uid, gid: stat.Gid} + return diagnosticFileIdentity{mode: info.Mode(), uid: stat.Uid, gid: stat.Gid, atime: stat.Atim} }