diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-03-06 19:26:29 +0100 |
---|---|---|
committer | Alex Brainman <alex.brainman@gmail.com> | 2019-03-10 05:40:13 +0000 |
commit | 9b6e9f0c8c66355c0f0575d808b32f52c8c6d21c (patch) | |
tree | 4b143b84ee9ad075e6342094ee262e7dcc748a42 /src/runtime/syscall_windows.go | |
parent | 243c8eb8c290ebbf2e2811da2dd7538200dde6b3 (diff) | |
download | go-9b6e9f0c8c66355c0f0575d808b32f52c8c6d21c.tar.gz go-9b6e9f0c8c66355c0f0575d808b32f52c8c6d21c.zip |
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
Reviewed-on: https://go-review.googlesource.com/c/go/+/165798
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Diffstat (limited to 'src/runtime/syscall_windows.go')
-rw-r--r-- | src/runtime/syscall_windows.go | 14 |
1 files changed, 6 insertions, 8 deletions
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)) |