]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.21] runtime: ensure stack is aligned in _rt0_amd64_windows_lib
authorqmuntal <quimmuntal@gmail.com>
Tue, 18 Jul 2023 14:55:26 +0000 (16:55 +0200)
committerCherry Mui <cherryyz@google.com>
Thu, 20 Jul 2023 18:24:32 +0000 (18:24 +0000)
The Windows DLL loader may call a DLL entry point, in our case
_rt0_amd64_windows_lib, with a stack that is
not 16-byte aligned. In theory, it shouldn't, but under some
circumstances, it does (see below how to reproduce it).

Having an unaligned stack can, and probably will, cause problems
down the line, for example if a movaps instruction tries to store
a value in an unaligned address it throws an Access Violation exception
(code 0xc0000005).

I managed to consistently reproduce this issue by loading a Go DLL into
a C program that has the Page Heap Verification diagnostic enabled [1].

Updates #54187 (and potentially fixes)

[1] https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/example-12---using-page-heap-verification-to-find-a-bug

Change-Id: Id0fea7f407e024c9b8cdce10ce4802d7535e7542
Reviewed-on: https://go-review.googlesource.com/c/go/+/510755
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
(cherry picked from commit 5fe3f0a265c90a9c0346403742c6cafeb154503b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/511135
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
src/runtime/rt0_windows_amd64.s

index d5f0940540b0c72d2038d4f15d9b026e93d7584c..bd18bdd311e6dd4a92fa65c9db83fc6d285caacc 100644 (file)
@@ -16,12 +16,17 @@ TEXT _rt0_amd64_windows(SB),NOSPLIT|NOFRAME,$-8
 // phase.
 // Leave space for four pointers on the stack as required
 // by the Windows amd64 calling convention.
-TEXT _rt0_amd64_windows_lib(SB),NOSPLIT|NOFRAME,$0x20
+TEXT _rt0_amd64_windows_lib(SB),NOSPLIT|NOFRAME,$40
        // Create a new thread to do the runtime initialization and return.
+       MOVQ    BX, 32(SP) // callee-saved, preserved across the CALL
+       MOVQ    SP, BX
+       ANDQ    $~15, SP // alignment as per Windows requirement
        MOVQ    _cgo_sys_thread_create(SB), AX
        MOVQ    $_rt0_amd64_windows_lib_go(SB), CX
        MOVQ    $0, DX
        CALL    AX
+       MOVQ    BX, SP
+       MOVQ    32(SP), BX
        RET
 
 TEXT _rt0_amd64_windows_lib_go(SB),NOSPLIT|NOFRAME,$0