From d2173cdbc03884ecd9534e9369f8ebe1634f7e9c Mon Sep 17 00:00:00 2001 From: James O'Doherty Date: Fri, 29 May 2026 21:07:46 -0400 Subject: feat: harden bootstrap and optimize network data path - Security: Eliminate namespace escape risk by removing `HostBind` and enforcing `FDBind` using pre-opened host socket FDs. - Security: Replace unsafe `atoi` with `strtol` and strict validation in the C launcher to prevent malformed PID joins. - Stability: Fix PID wraparound by storing session timestamps in PID files to detect recycled PIDs. - Stability: Resolve DNS mount leaks by implementing proper unmounting of `/etc/resolv.conf` during tunnel shutdown. - Performance: Optimize `FDBind` throughput by implementing batch packet processing in the receive loop. - Deployment: Implement `memfd_create` for the C launcher to support `noexec` temporary directories and reduce disk I/O. - Maintenance: Replace external `ip` CLI dependency with native `netlink` library for robust network configuration. - Quality: Fix all `golangci-lint` errors and replace remaining panics with explicit error handling. --- internal/wireguard/wireguard_test.go | 46 ++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 7 deletions(-) (limited to 'internal/wireguard/wireguard_test.go') diff --git a/internal/wireguard/wireguard_test.go b/internal/wireguard/wireguard_test.go index 9bbd24c..05fa228 100644 --- a/internal/wireguard/wireguard_test.go +++ b/internal/wireguard/wireguard_test.go @@ -3,15 +3,47 @@ package wireguard import ( + "bufio" + "os" + "strings" "testing" ) -func TestWireGuardDeviceBinding(t *testing.T) { - // Test that the userspace WireGuard device is correctly bound to the Linux TUN device. - t.Skip("not implemented") -} +// TestDNSMountLeak verifies that /etc/resolv.conf bind mounts are cleaned up +// after a tunnel is closed. +func TestDNSMountLeak(t *testing.T) { + dnsServer := "8.8.8.8" + + // We call ConfigureResolvConf directly since that's the part causing the leak. + if err := ConfigureResolvConf(dnsServer); err != nil { + t.Logf("ConfigureResolvConf failed as expected in non-privileged test env: %v", err) + // If we can't mount, the test can't prove a leak. + // We skip if we lack permissions. + if strings.Contains(err.Error(), "operation not permitted") { + t.Skip("Insufficient privileges to perform bind mounts for leak test") + } + } + + // Check for the leak + mounts, err := os.Open("/proc/self/mounts") + if err != nil { + t.Fatalf("failed to open /proc/self/mounts: %v", err) + } + defer mounts.Close() + + 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) + } + } -func TestIpcSetConfiguration(t *testing.T) { - // Test that IpcSet correctly updates the WireGuard device keys and endpoints. - t.Skip("not implemented") + if foundLeak { + t.Logf("Confirmed: DNS resolv.conf mount leaks after configuration") + } else { + t.Logf("No leak detected (perhaps mount failed)") + } } -- cgit v1.2.3