aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/golang-runtime-dll-injection.patch
diff options
context:
space:
mode:
authorSimon Rozman <simon@rozman.si>2019-04-25 11:29:46 +0200
committerSimon Rozman <simon@rozman.si>2019-04-25 11:29:46 +0200
commitdc4cf0b608239844cac5387c54876950f2a0fd36 (patch)
treef73b22be7771a21f6e8f40b0226e12d939da04d9 /golang-runtime-dll-injection.patch
parentinstaller: Use more clever shortcut installation and dirtier upgrades (diff)
downloadwireguard-windows-dc4cf0b608239844cac5387c54876950f2a0fd36.tar.xz
wireguard-windows-dc4cf0b608239844cac5387c54876950f2a0fd36.zip
build: clean golang-runtime-dll-injection.patch
Signed-off-by: Simon Rozman <simon@rozman.si>
Diffstat (limited to '')
-rw-r--r--golang-runtime-dll-injection.patch316
1 files changed, 0 insertions, 316 deletions
diff --git a/golang-runtime-dll-injection.patch b/golang-runtime-dll-injection.patch
deleted file mode 100644
index af0fc87b..00000000
--- a/golang-runtime-dll-injection.patch
+++ /dev/null
@@ -1,316 +0,0 @@
-From a5dacf9b3b54bc24733776a42e7907964f23cd3b Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Wed, 6 Mar 2019 19:26:29 +0100
-Subject: [PATCH] runtime: safely load DLLs
-
-While many other call sites have been moved to using the proper
-higher-level system loading, these areas were left out. This prevents
-DLL directory injection attacks. This includes both the runtime load
-calls (using LoadLibrary prior) and the implicitly linked ones via
-cgo_import_dynamic, which we move to our LoadLibraryEx. The goal is to
-only loosely load kernel32.dll and strictly load all others.
-
-Meanwhile we make sure that we never fallback to insecure loading on
-older or unpatched systems.
-
-This is CVE-2019-9634.
-
-Fixes #14959
-Fixes #28978
-Fixes #30642
-
-Change-Id: I401a13ed8db248ab1bb5039bf2d31915cac72b93
----
- src/runtime/os_windows.go | 64 +++++++++++++++++++++++++++------
- src/runtime/syscall_windows.go | 14 ++++----
- src/syscall/dll_windows.go | 28 +++++++++++++--
- src/syscall/security_windows.go | 1 +
- src/syscall/zsyscall_windows.go | 14 ++++++++
- 5 files changed, 101 insertions(+), 20 deletions(-)
-
-diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
-index 2e1ec58a0d..d3e84fe3dc 100644
---- a/src/runtime/os_windows.go
-+++ b/src/runtime/os_windows.go
-@@ -29,6 +29,7 @@ const (
- //go:cgo_import_dynamic runtime._GetProcessAffinityMask GetProcessAffinityMask%3 "kernel32.dll"
- //go:cgo_import_dynamic runtime._GetQueuedCompletionStatus GetQueuedCompletionStatus%5 "kernel32.dll"
- //go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle%1 "kernel32.dll"
-+//go:cgo_import_dynamic runtime._GetSystemDirectoryA GetSystemDirectoryA%2 "kernel32.dll"
- //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll"
- //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll"
- //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
-@@ -47,12 +48,9 @@ const (
- //go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc%4 "kernel32.dll"
- //go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll"
- //go:cgo_import_dynamic runtime._VirtualQuery VirtualQuery%3 "kernel32.dll"
--//go:cgo_import_dynamic runtime._WSAGetOverlappedResult WSAGetOverlappedResult%5 "ws2_32.dll"
- //go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll"
- //go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
- //go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll"
--//go:cgo_import_dynamic runtime._timeBeginPeriod timeBeginPeriod%1 "winmm.dll"
--//go:cgo_import_dynamic runtime._timeEndPeriod timeEndPeriod%1 "winmm.dll"
-
- type stdFunction unsafe.Pointer
-
-@@ -75,6 +73,7 @@ var (
- _GetProcessAffinityMask,
- _GetQueuedCompletionStatus,
- _GetStdHandle,
-+ _GetSystemDirectoryA,
- _GetSystemInfo,
- _GetSystemTimeAsFileTime,
- _GetThreadContext,
-@@ -96,12 +95,9 @@ var (
- _VirtualAlloc,
- _VirtualFree,
- _VirtualQuery,
-- _WSAGetOverlappedResult,
- _WaitForSingleObject,
- _WriteConsoleW,
- _WriteFile,
-- _timeBeginPeriod,
-- _timeEndPeriod,
- _ stdFunction
-
- // Following syscalls are only available on some Windows PCs.
-@@ -109,6 +105,7 @@ var (
- _AddDllDirectory,
- _AddVectoredContinueHandler,
- _GetQueuedCompletionStatusEx,
-+ _LoadLibraryExA,
- _LoadLibraryExW,
- _ stdFunction
-
-@@ -126,6 +123,12 @@ var (
- // links wrong printf function to cgo executable (see issue
- // 12030 for details).
- _NtWaitForSingleObject stdFunction
-+
-+ // These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
-+ _timeBeginPeriod,
-+ _timeEndPeriod,
-+ _WSAGetOverlappedResult,
-+ _ stdFunction
- )
-
- // Function to be called by windows CreateThread
-@@ -173,6 +176,26 @@ func windowsFindfunc(lib uintptr, name []byte) stdFunction {
- return stdFunction(unsafe.Pointer(f))
- }
-
-+var sysDirectory [521]byte
-+var sysDirectoryLen uintptr
-+
-+func windowsLoadSystemLib(name []byte) uintptr {
-+ if useLoadLibraryEx {
-+ return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32)
-+ } else {
-+ if sysDirectoryLen == 0 {
-+ l := stdcall2(_GetSystemDirectoryA, uintptr(unsafe.Pointer(&sysDirectory[0])), uintptr(len(sysDirectory)-1))
-+ if l == 0 || l > uintptr(len(sysDirectory)-1) {
-+ throw("Unable to determine system directory")
-+ }
-+ sysDirectory[l] = '\\'
-+ sysDirectoryLen = l + 1
-+ }
-+ absName := append(sysDirectory[:sysDirectoryLen], name...)
-+ return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0])))
-+ }
-+}
-+
- func loadOptionalSyscalls() {
- var kernel32dll = []byte("kernel32.dll\000")
- k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0])))
-@@ -182,17 +205,19 @@ func loadOptionalSyscalls() {
- _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000"))
- _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000"))
- _GetQueuedCompletionStatusEx = windowsFindfunc(k32, []byte("GetQueuedCompletionStatusEx\000"))
-+ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000"))
- _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000"))
-+ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil)
-
- var advapi32dll = []byte("advapi32.dll\000")
-- a32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&advapi32dll[0])))
-+ a32 := windowsLoadSystemLib(advapi32dll)
- if a32 == 0 {
- throw("advapi32.dll not found")
- }
- _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
-
- var ntdll = []byte("ntdll.dll\000")
-- n32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&ntdll[0])))
-+ n32 := windowsLoadSystemLib(ntdll)
- if n32 == 0 {
- throw("ntdll.dll not found")
- }
-@@ -205,6 +230,27 @@ func loadOptionalSyscalls() {
- }
- }
-
-+ var winmmdll = []byte("winmm.dll\000")
-+ m32 := windowsLoadSystemLib(winmmdll)
-+ if m32 == 0 {
-+ throw("winmm.dll not found")
-+ }
-+ _timeBeginPeriod = windowsFindfunc(m32, []byte("timeBeginPeriod\000"))
-+ _timeEndPeriod = windowsFindfunc(m32, []byte("timeEndPeriod\000"))
-+ if _timeBeginPeriod == nil || _timeEndPeriod == nil {
-+ throw("timeBegin/EndPeriod not found")
-+ }
-+
-+ var ws232dll = []byte("ws2_32.dll\000")
-+ ws232 := windowsLoadSystemLib(ws232dll)
-+ if ws232 == 0 {
-+ throw("ws2_32.dll not found")
-+ }
-+ _WSAGetOverlappedResult = windowsFindfunc(ws232, []byte("WSAGetOverlappedResult\000"))
-+ if _WSAGetOverlappedResult == nil {
-+ throw("WSAGetOverlappedResult not found")
-+ }
-+
- if windowsFindfunc(n32, []byte("wine_get_version\000")) != nil {
- // running on Wine
- initWine(k32)
-@@ -311,8 +357,6 @@ func osinit() {
-
- loadOptionalSyscalls()
-
-- useLoadLibraryEx = (_LoadLibraryExW != nil && _AddDllDirectory != nil)
--
- disableWER()
-
- initExceptionHandler()
-diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
-index 8cfc71124a..36ad7511af 100644
---- a/src/runtime/syscall_windows.go
-+++ b/src/runtime/syscall_windows.go
-@@ -104,9 +104,13 @@ func compileCallback(fn eface, cleanstack bool) (code uintptr) {
-
- const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
-
-+// When available, this function will use LoadLibraryEx with the filename
-+// parameter and the important SEARCH_SYSTEM32 argument. But on systems that
-+// do not have that option, absoluteFilepath should contain a fallback
-+// to the full path inside of system32 for use with vanilla LoadLibrary.
- //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary
- //go:nosplit
--func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) {
-+func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) {
- lockOSThread()
- defer unlockOSThread()
- c := &getg().m.syscall
-@@ -121,15 +125,9 @@ func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) {
- }{filename, 0, _LOAD_LIBRARY_SEARCH_SYSTEM32}
- c.args = uintptr(noescape(unsafe.Pointer(&args)))
- } else {
-- // User doesn't have KB2533623 installed. The caller
-- // wanted to only load the filename DLL from the
-- // System32 directory but that facility doesn't exist,
-- // so just load it the normal way. This is a potential
-- // security risk, but so is not installing security
-- // updates.
- c.fn = getLoadLibrary()
- c.n = 1
-- c.args = uintptr(noescape(unsafe.Pointer(&filename)))
-+ c.args = uintptr(noescape(unsafe.Pointer(&absoluteFilepath)))
- }
-
- cgocall(asmstdcallAddr, unsafe.Pointer(c))
-diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go
-index c57cd34f82..34925f74a4 100644
---- a/src/syscall/dll_windows.go
-+++ b/src/syscall/dll_windows.go
-@@ -28,7 +28,7 @@ func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 ui
- func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno)
- func Syscall18(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2 uintptr, err Errno)
- func loadlibrary(filename *uint16) (handle uintptr, err Errno)
--func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno)
-+func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno)
- func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno)
-
- // A DLL implements access to a single DLL.
-@@ -37,6 +37,26 @@ type DLL struct {
- Handle Handle
- }
-
-+// We use this for computing the absolute path for system DLLs on systems
-+// where SEARCH_SYSTEM32 is not available.
-+var systemDirectoryPrefix string
-+
-+func init() {
-+ n := uint32(MAX_PATH)
-+ for {
-+ b := make([]uint16, n)
-+ l, e := getSystemDirectory(&b[0], n)
-+ if e != nil {
-+ panic("Unable to determine system directory: " + e.Error())
-+ }
-+ if l <= n {
-+ systemDirectoryPrefix = UTF16ToString(b[:l]) + "\\"
-+ break
-+ }
-+ n = l
-+ }
-+}
-+
- // LoadDLL loads the named DLL file into memory.
- //
- // If name is not an absolute path and is not a known system DLL used by
-@@ -53,7 +73,11 @@ func LoadDLL(name string) (*DLL, error) {
- var h uintptr
- var e Errno
- if sysdll.IsSystemDLL[name] {
-- h, e = loadsystemlibrary(namep)
-+ absoluteFilepathp, err := UTF16PtrFromString(systemDirectoryPrefix + name)
-+ if err != nil {
-+ return nil, err
-+ }
-+ h, e = loadsystemlibrary(namep, absoluteFilepathp)
- } else {
- h, e = loadlibrary(namep)
- }
-diff --git a/src/syscall/security_windows.go b/src/syscall/security_windows.go
-index ae8b3a17bf..db80d98a08 100644
---- a/src/syscall/security_windows.go
-+++ b/src/syscall/security_windows.go
-@@ -290,6 +290,7 @@ type Tokenprimarygroup struct {
- //sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
- //sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
- //sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
-+//sys getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
-
- // An access token contains the security information for a logon session.
- // The system creates an access token when a user logs on, and every
-diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go
-index de2d4f3adb..2348f6534f 100644
---- a/src/syscall/zsyscall_windows.go
-+++ b/src/syscall/zsyscall_windows.go
-@@ -190,6 +190,7 @@ var (
- procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken")
- procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation")
- procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW")
-+ procGetSystemDirectoryW = modkernel32.NewProc("GetSystemDirectoryW")
- )
-
- func GetLastError() (lasterr error) {
-@@ -1916,3 +1917,16 @@ func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
- }
- return
- }
-+
-+func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) {
-+ r0, _, e1 := Syscall(procGetSystemDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0)
-+ len = uint32(r0)
-+ if len == 0 {
-+ if e1 != 0 {
-+ err = errnoErr(e1)
-+ } else {
-+ err = EINVAL
-+ }
-+ }
-+ return
-+}
---
-2.20.1
-