From dc4cf0b608239844cac5387c54876950f2a0fd36 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Thu, 25 Apr 2019 11:29:46 +0200 Subject: build: clean golang-runtime-dll-injection.patch Signed-off-by: Simon Rozman --- golang-runtime-dll-injection.patch | 316 ------------------------------------- 1 file changed, 316 deletions(-) delete mode 100644 golang-runtime-dll-injection.patch (limited to 'golang-runtime-dll-injection.patch') 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" -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 - -- cgit v1.2.3-59-g8ed1b