cmd/tailscaled: pre-load wintun.dll using a fully-qualified path
In corp PR #14970 I updated the installer to set a security mitigation that always forces system32 to the front of the Windows dynamic linker's search path. Unfortunately there are other products out there that, partying like it's 1995, drop their own, older version of wintun.dll into system32. Since we look there first, we end up loading that old version. We can fix this by preloading wintun using a fully-qualified path. When wintun-go then loads wintun, the dynamic linker will hand it the module that was previously loaded by us. Fixes #10023, #10025, #10052 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This commit is contained in:
parent
af49bcaa52
commit
47019ce1f1
|
@ -30,6 +30,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
@ -299,6 +300,14 @@ func beWindowsSubprocess() bool {
|
|||
}
|
||||
}()
|
||||
|
||||
// Pre-load wintun.dll using a fully-qualified path so that wintun-go
|
||||
// loads our copy and not some (possibly outdated) copy dropped in system32.
|
||||
// (OSS Issue #10023)
|
||||
fqWintunPath := fullyQualifiedWintunPath(log.Printf)
|
||||
if _, err := windows.LoadDLL(fqWintunPath); err != nil {
|
||||
log.Printf("Error pre-loading \"%s\": %v", fqWintunPath, err)
|
||||
}
|
||||
|
||||
sys := new(tsd.System)
|
||||
netMon, err := netmon.New(log.Printf)
|
||||
if err != nil {
|
||||
|
@ -507,7 +516,7 @@ func babysitProc(ctx context.Context, args []string, logf logger.Logf) {
|
|||
}
|
||||
|
||||
func uninstallWinTun(logf logger.Logf) {
|
||||
dll := windows.NewLazyDLL("wintun.dll")
|
||||
dll := windows.NewLazyDLL(fullyQualifiedWintunPath(logf))
|
||||
if err := dll.Load(); err != nil {
|
||||
logf("Cannot load wintun.dll for uninstall: %v", err)
|
||||
return
|
||||
|
@ -517,3 +526,16 @@ func uninstallWinTun(logf logger.Logf) {
|
|||
err := wintun.Uninstall()
|
||||
logf("Uninstall: %v", err)
|
||||
}
|
||||
|
||||
func fullyQualifiedWintunPath(logf logger.Logf) string {
|
||||
var dir string
|
||||
var buf [windows.MAX_PATH]uint16
|
||||
length := uint32(len(buf))
|
||||
if err := windows.QueryFullProcessImageName(windows.CurrentProcess(), 0, &buf[0], &length); err != nil {
|
||||
logf("QueryFullProcessImageName failed: %v", err)
|
||||
} else {
|
||||
dir = filepath.Dir(windows.UTF16ToString(buf[:length]))
|
||||
}
|
||||
|
||||
return filepath.Join(dir, "wintun.dll")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue