Files
sing-box-extended-mirror/common/windivert/driver_asset_windows_test.go
T

62 lines
1.7 KiB
Go

//go:build windows && !with_external_windivert
package windivert
import (
"bytes"
"errors"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"golang.org/x/sys/windows"
)
// The image lock on a loaded .sys can outlive SERVICE_STOPPED by tens of
// seconds (observed on GitHub-hosted runners), and on current runner images
// it blocks renames as well as writes and deletes.
func setTempDriverCache(t *testing.T) {
t.Helper()
dir, err := os.MkdirTemp("", "sing-box-windivert-test-")
require.NoError(t, err)
t.Cleanup(func() { os.RemoveAll(dir) })
t.Setenv("LocalAppData", dir)
}
func TestIntegrationTamperedCacheRepaired(t *testing.T) {
setTempDriverCache(t)
stopDriver(t)
target, err := driverFilePath()
require.NoError(t, err)
require.NoError(t, os.MkdirAll(filepath.Dir(target), 0o755))
require.NoError(t, os.WriteFile(target, []byte("planted payload, not the WinDivert driver"), 0o644))
h := openHandle(t, nil, FlagSendOnly)
require.NoError(t, h.Close())
content, err := os.ReadFile(target)
require.NoError(t, err)
require.True(t, bytes.Equal(content, sysBytes), "cached driver was not repaired to the embedded asset")
}
func TestIntegrationDriverFileLockedWhileHeld(t *testing.T) {
setTempDriverCache(t)
sysPath, sysFile, err := openVerifiedDriver()
require.NoError(t, err)
defer sysFile.Close()
writeErr := os.WriteFile(sysPath, []byte("overwrite attempt"), 0o644)
require.Error(t, writeErr)
require.True(t, errors.Is(writeErr, windows.ERROR_SHARING_VIOLATION),
"expected sharing violation, got %v", writeErr)
evil := sysPath + ".evil"
require.NoError(t, os.WriteFile(evil, []byte("replacement attempt"), 0o644))
defer os.Remove(evil)
renameErr := os.Rename(evil, sysPath)
require.Error(t, renameErr)
}