diff options
| author | Jason A. Donenfeld <Jason@zx2c4.com> | 2026-03-19 00:28:04 +0100 |
|---|---|---|
| committer | Jason Donenfeld <Jason@zx2c4.com> | 2026-03-24 09:00:02 -0700 |
| commit | 341b5e2c0261cc059b157f1c7a2a2c4d1f417f0d (patch) | |
| tree | f10166b18211864ae4f94cd17b72daeb77c91639 /src/runtime/syscall_windows_test.go | |
| parent | abd44cbe615ecea5e4bd8e6d1bb7be63d1f4b2d6 (diff) | |
| download | go-341b5e2c0261cc059b157f1c7a2a2c4d1f417f0d.tar.xz | |
cmd/link: raise minimum windows version to 10
The minimum Windows version has been 10 for a few releases, but the PE
headers weren't updated. Windows sometimes can use these in determining
what kind of subsystem compatibility hacks to apply, which of course we
don't want now, since Go targets Windows 10. This also causes older OSes
to refuse to run the executables, rather than having them crash in some
undefined way.
This isn't trivial to do, because subsystem ≥ 10.0 means that the
Windows loader expects to see either _load_config_used.SecurityCookie
set to the initial magic value, or for IMAGE_GUARD_SECURITY_COOKIE_UNUSED
to be set. Go obviously isn't making use of these features, and neither
does clang/gcc for that matter; libssp doesn't even use SecurityCookie.
Rather, it's exclusively for MSVC's /GS protection. So it seems like the
proper thing to do is signal to the OS that it doesn't need to
initialize SecurityCookie. This check lives in ntdll!LdrInitSecurityCookie.
So, add the _load_config_used structure to the right PE section and give
it the right flag. This lets the Windows 10-marked binaries actually
run.
Change-Id: I91887073c7ad01aeb0237906aafa4ea5574ac8fa
Reviewed-on: https://go-review.googlesource.com/c/go/+/756680
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Jason Donenfeld <Jason@zx2c4.com>
Reviewed-by: Jason Donenfeld <Jason@zx2c4.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/runtime/syscall_windows_test.go')
| -rw-r--r-- | src/runtime/syscall_windows_test.go | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go index 77092d8fbf..437c723d51 100644 --- a/src/runtime/syscall_windows_test.go +++ b/src/runtime/syscall_windows_test.go @@ -8,6 +8,7 @@ import ( "fmt" "internal/abi" "internal/race" + "internal/syscall/windows" "internal/syscall/windows/sysdll" "internal/testenv" "io" @@ -1226,6 +1227,20 @@ var ( procSetEvent = modkernel32.NewProc("SetEvent") ) +func TestTrueVersion(t *testing.T) { + ver, err := syscall.GetVersion() + if err != nil { + t.Fatalf("GetVersion failed: %v", err) + } + wantMajor, wantMinor, wantBuild := windows.Version() + major := uint32(byte(ver)) + minor := uint32(uint8(ver >> 8)) + build := uint32(uint16(ver >> 16)) + if major != wantMajor || minor != wantMinor || build != wantBuild { + t.Errorf("GetVersion = %d.%d (Build %d), want %d.%d (Build %d)", major, minor, build, wantMajor, wantMinor, wantBuild) + } +} + func createEvent() (syscall.Handle, error) { r0, _, e0 := syscall.Syscall6(procCreateEvent.Addr(), 4, 0, 0, 0, 0, 0, 0) if r0 == 0 { |
