summaryrefslogtreecommitdiff
path: root/tests/e2e/mount_leak_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'tests/e2e/mount_leak_test.go')
-rw-r--r--tests/e2e/mount_leak_test.go70
1 files changed, 70 insertions, 0 deletions
diff --git a/tests/e2e/mount_leak_test.go b/tests/e2e/mount_leak_test.go
new file mode 100644
index 0000000..bdc9d75
--- /dev/null
+++ b/tests/e2e/mount_leak_test.go
@@ -0,0 +1,70 @@
+package e2e
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "os/exec"
+ "strings"
+ "testing"
+)
+
+// TestDNSMountLeak verifies that /etc/resolv.conf bind mounts are cleaned up
+// after a profile is stopped.
+func TestDNSMountLeak(t *testing.T) {
+ bin, err := GetBinaryPath()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ profile := "leak-test"
+ dnsServer := "8.8.8.8"
+
+ // Pre-create a dummy config for the profile
+ configDir := "/tmp/wg-wrap-test-configs"
+ if err := os.MkdirAll(configDir, 0755); err != nil {
+ t.Fatalf("failed to create config dir: %v", err)
+ }
+ configPath := fmt.Sprintf("%s/%s.conf", configDir, profile)
+ if err := os.WriteFile(configPath, []byte("[Interface]\nAddress = 10.0.0.1/24\nPrivateKey = aAAA\n"), 0644); err != nil {
+ t.Fatalf("failed to write config file: %v", err)
+ }
+
+ // Run the binary with the custom config dir override.
+ // We use a short-lived command ('true') to trigger the deferred cleanup.
+ fullCmd := fmt.Sprintf("WG_WRAP_CONFIG_DIR=%s %s -profile %s -dns-server %s -- true", configDir, bin, profile, dnsServer)
+
+ cmd := exec.Command("bash", "-c", fullCmd)
+ if err := cmd.Run(); err != nil {
+ t.Logf("Command exited with error (might be normal in some test envs): %v", err)
+ }
+
+ // 2. Inspect /proc/self/mounts for any remnants of "resolvconf"
+ // Note: In a real scenario, we might need to inspect mounts from a privileged
+ // perspective or check the target's namespace mounts if we had a way to keep it open.
+ // But since we are checking the host's mount table for leaked bind mounts
+ // that weren't unmounted, we check /proc/self/mounts.
+ mounts, err := os.Open("/proc/self/mounts")
+ if err != nil {
+ t.Fatalf("failed to open /proc/self/mounts: %v", err)
+ }
+ defer func() {
+ if err := mounts.Close(); err != nil {
+ t.Errorf("failed to close mounts file: %v", err)
+ }
+ }()
+
+ scanner := bufio.NewScanner(mounts)
+ foundLeak := false
+ for scanner.Scan() {
+ line := scanner.Text()
+ if strings.Contains(line, "resolvconf") && strings.Contains(line, "/etc/resolv.conf") {
+ foundLeak = true
+ t.Errorf("Found leaking bind mount in /proc/self/mounts: %s", line)
+ }
+ }
+
+ if foundLeak {
+ t.Errorf("Detected a DNS resolv.conf mount leak after profile exit")
+ }
+}