aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/go-patches/no-ctrlc-handler.patch
blob: 157ed88f8529ea7633b3f9a5390a48993ca43c1b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
From 8bc7bff3bff8f61312f8d2307cfe2e433d356c31 Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
Date: Fri, 11 Sep 2020 13:04:11 +0200
Subject: [PATCH 1/2] Revert "[release-branch.go1.15] runtime: detect services
 in signal handler"

This reverts commit b1253d24e159129c778377c3a2a0bde15904a417.
---
 src/runtime/os_windows.go | 73 +++------------------------------------
 1 file changed, 4 insertions(+), 69 deletions(-)

diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index 769197db46..a584ada702 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -36,10 +36,7 @@ const (
 //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll"
 //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
 //go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._OpenProcess OpenProcess%3 "kernel32.dll"
 //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll"
-//go:cgo_import_dynamic runtime._ProcessIdToSessionId ProcessIdToSessionId%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._QueryFullProcessImageNameA QueryFullProcessImageNameA%4 "kernel32.dll"
 //go:cgo_import_dynamic runtime._ResumeThread ResumeThread%1 "kernel32.dll"
 //go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler%2 "kernel32.dll"
 //go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode%1 "kernel32.dll"
@@ -87,10 +84,7 @@ var (
 	_SetThreadContext,
 	_LoadLibraryW,
 	_LoadLibraryA,
-	_OpenProcess,
 	_PostQueuedCompletionStatus,
-	_ProcessIdToSessionId,
-	_QueryFullProcessImageNameA,
 	_QueryPerformanceCounter,
 	_QueryPerformanceFrequency,
 	_ResumeThread,
@@ -134,8 +128,7 @@ var (
 	// Load ntdll.dll manually during startup, otherwise Mingw
 	// links wrong printf function to cgo executable (see issue
 	// 12030 for details).
-	_NtWaitForSingleObject     stdFunction
-	_NtQueryInformationProcess stdFunction
+	_NtWaitForSingleObject stdFunction
 
 	// These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
 	_timeBeginPeriod,
@@ -262,7 +255,6 @@ func loadOptionalSyscalls() {
 		throw("ntdll.dll not found")
 	}
 	_NtWaitForSingleObject = windowsFindfunc(n32, []byte("NtWaitForSingleObject\000"))
-	_NtQueryInformationProcess = windowsFindfunc(n32, []byte("NtQueryInformationProcess\000"))
 
 	if GOARCH == "arm" {
 		_QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
@@ -1003,63 +995,6 @@ func usleep(us uint32) {
 	onosstack(usleep2Addr, 10*us)
 }
 
-// isWindowsService returns whether the process is currently executing as a
-// Windows service. The below technique looks a bit hairy, but it's actually
-// exactly what the .NET framework does for the similarly named function:
-// https://github.com/dotnet/extensions/blob/f4066026ca06984b07e90e61a6390ac38152ba93/src/Hosting/WindowsServices/src/WindowsServiceHelpers.cs#L26-L31
-// Specifically, it looks up whether the parent process has session ID zero
-// and is called "services".
-func isWindowsService() bool {
-	const (
-		_CURRENT_PROCESS                   = ^uintptr(0)
-		_PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
-	)
-	// pbi is a PROCESS_BASIC_INFORMATION struct, where we just care about
-	// the 6th pointer inside of it, which contains the pid of the process
-	// parent:
-	// https://github.com/wine-mirror/wine/blob/42cb7d2ad1caba08de235e6319b9967296b5d554/include/winternl.h#L1294
-	var pbi [6]uintptr
-	var pbiLen uint32
-	err := stdcall5(_NtQueryInformationProcess, _CURRENT_PROCESS, 0, uintptr(unsafe.Pointer(&pbi[0])), uintptr(unsafe.Sizeof(pbi)), uintptr(unsafe.Pointer(&pbiLen)))
-	if err != 0 {
-		return false
-	}
-	var psid uint32
-	err = stdcall2(_ProcessIdToSessionId, pbi[5], uintptr(unsafe.Pointer(&psid)))
-	if err == 0 || psid != 0 {
-		return false
-	}
-	pproc := stdcall3(_OpenProcess, _PROCESS_QUERY_LIMITED_INFORMATION, 0, pbi[5])
-	if pproc == 0 {
-		return false
-	}
-	defer stdcall1(_CloseHandle, pproc)
-	// exeName gets the path to the executable image of the parent process
-	var exeName [261]byte
-	exeNameLen := uint32(len(exeName) - 1)
-	err = stdcall4(_QueryFullProcessImageNameA, pproc, 0, uintptr(unsafe.Pointer(&exeName[0])), uintptr(unsafe.Pointer(&exeNameLen)))
-	if err == 0 || exeNameLen == 0 {
-		return false
-	}
-	servicesLower := "services.exe"
-	servicesUpper := "SERVICES.EXE"
-	i := int(exeNameLen) - 1
-	j := len(servicesLower) - 1
-	if i < j {
-		return false
-	}
-	for {
-		if j == -1 {
-			return i == -1 || exeName[i] == '\\'
-		}
-		if exeName[i] != servicesLower[j] && exeName[i] != servicesUpper[j] {
-			return false
-		}
-		i--
-		j--
-	}
-}
-
 func ctrlhandler1(_type uint32) uint32 {
 	var s uint32
 
@@ -1075,9 +1010,9 @@ func ctrlhandler1(_type uint32) uint32 {
 	if sigsend(s) {
 		return 1
 	}
-	if !islibrary && !isarchive && !isWindowsService() {
-		// Only exit the program if we don't have a DLL or service.
-		// See https://golang.org/issues/35965 and https://golang.org/issues/40167
+	if !islibrary && !isarchive {
+		// Only exit the program if we don't have a DLL.
+		// See https://golang.org/issues/35965.
 		exit(2) // SIGINT, SIGTERM, etc
 	}
 	return 0
-- 
2.28.0

From 84cc2046962e754af08f99327561be2e979eaf16 Mon Sep 17 00:00:00 2001
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
Date: Tue, 14 Jul 2020 01:41:03 -0600
Subject: [PATCH 2/2] runtime: do not explicitly exit on ctrl handler

The default ctrl+c handler should process exits in situations where it
makes sense, like console apps, but not in situations where it doesn't,
like libraries or services. Therefore, we should remove the exit(2) so
that the default handler is used for this. This also uses the more
proper windows exit code of STATUS_CONTROL_C_EXIT, with the base case
handler installed by KernelBase.dll. In particular, this helps in the
case of services, which previously would terminate when receiving
shutdown signals, instead of passing them onward to the service program.
In this CL, contrary to CL 244959, we do not need to special case
services with expensive detection algorithms, or rely on hard-coded
library/archive flags.

Fixes #40167.
Fixes #40074.

Change-Id: I9bf6ed6f65cefeff754d270aa33fa4df8d0b451f
Reviewed-on: https://go-review.googlesource.com/c/go/+/243597
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 src/runtime/os_windows.go | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index a584ada702..a62e941229 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -1010,11 +1010,6 @@ func ctrlhandler1(_type uint32) uint32 {
 	if sigsend(s) {
 		return 1
 	}
-	if !islibrary && !isarchive {
-		// Only exit the program if we don't have a DLL.
-		// See https://golang.org/issues/35965.
-		exit(2) // SIGINT, SIGTERM, etc
-	}
 	return 0
 }
 
-- 
2.28.0