This brings the algorithm more exactly in line with what .NET does for
the identically named function. Specifically, instead of using
OpenProcess, which requires rights that restricted services might not
have, we use NtQuerySystemInformation(SYSTEM_PROCESS_INFORMATION) to
find the parent process image name and session ID.
Fixesgolang/go#44921.
Change-Id: Ie2ad7521cf4c530037d086e61dbc2413e4e7777c
Reviewed-on: https://go-review.googlesource.com/c/sys/+/372554
Trust: Jason Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Patrik Nyblom <pnyb@google.com>
Trust: Patrik Nyblom <pnyb@google.com>
Run-TryBot: Patrik Nyblom <pnyb@google.com>
Go 1.16 didn't create inheritable pipes yet, because we didn't have safe
process inheritance semantics worked out then. So, for this test,
explicitly mark the pipe as inheritable, in case this is running on Go
1.16.
Fixesgolang/go#50160.
Change-Id: I2e59cf430ff35e7f59315b11b73e79b9aaf3e6ce
Reviewed-on: https://go-review.googlesource.com/c/sys/+/371694
Trust: Jason Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
We didn't want to wind up with Go pointers mangled by win32, so we were
previously copying the contents into a LocalAlloc'd blob, and then
adding that to the attribute list. The problem is that recent changes to
the API broke this design convention, to the point where it expects 0x18
byte objects to be added using size 0x8. This seems like an unfortunate
oversight from Microsoft, but there's nothing we can do about it. So we
can work around it by instead LocalAlloc'ing the actual container, and
then using the exact pointer value that's passed into Update.
This commit also adds a test that both makes sure that these functions
actually work, and provokes a UaF that's successfully caught, were you
to comment out the line of this commit that reads `al.pointers =
append(al.pointers, value)`.
Fixesgolang/go#50134.
Change-Id: Ib73346d2d6ca3db601cd236596cefb564d9dc8f1
Reviewed-on: https://go-review.googlesource.com/c/sys/+/371276
Trust: Jason Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Patrik Nyblom <pnyb@google.com>
Trust: Patrik Nyblom <pnyb@google.com>
Run-TryBot: Patrik Nyblom <pnyb@google.com>
Simon and I have worked on these on and off for a number of projects
over the last 3 years and by now it's quite stable and mature. Rather
than carrying this around privately, these have now been updated to be
in the style of x/sys/windows, in this case matching how the
security_windows.go file does things. Specifically, because these APIs
are kind of hard to work with, and quite lengthy, we split them off into
a setupapi_windows.go file, just like security_windows.go. We already
had the setupapierrors_windows.go file, so that's been folded into the
new one that contains the additional definitions nad functions.
These APIs are among the most obtuse to work with in all of Win32, so
considerable attention has been spent trying to make these wrappers both
quite "raw" so that they match the win32, but also accessible from Go.
The fact that they're so old in Windows history makes for a few tricky
things, like struct padding that doesn't quite match Go's rules, but
we've been able to accommodate basically everything after quite a bit of
work.
Change-Id: I0c2dd85e4bb40eee10186ffc92558a858bdf8c6a
Reviewed-on: https://go-review.googlesource.com/c/sys/+/366654
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Patrik Nyblom <pnyb@google.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Simon Rozman <simon@rozman.si>
Reviewed-by: Patrik Nyblom <pnyb@google.com>
CL 361154 updated the standard syscall package to document that
successive calls to syscall.RegEnumKeyEx must occur on the same OS
thread (after that requirement was empirically discovered in
golang/go#49320).
This use in x/sys needs to be updated to comply with the
newly-discovered requirement.
Fixesgolang/go#49466.
Change-Id: Idc45d91f175e1db25c215213fcaa45982c2f5e6e
Reviewed-on: https://go-review.googlesource.com/c/sys/+/362576
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
The old service management code was written in assembly and communicated
over Windows events, which resulted in non-obvious control flow.
NewCallback makes it possible to rewrite all of this in vanilla Go. This
also enables the service test on the Go builders, as modifying system
services shouldn't be an issue there.
Change-Id: I8003b57d11d4469f762058c648a4b7733530eeb8
Reviewed-on: https://go-review.googlesource.com/c/sys/+/330010
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
It turns out that if you write Go pointers to Go memory, the Go compiler
must be involved so that it generates various calls to the GC in the
process. Letting Windows write Go pointers to Go memory violated this.
We fix this by having all the Windows-managed memory be just a boring
[]byte blob. Then, in order to prevent the GC from prematurely cleaning
up the pointers referenced by that []byte blob, or in the future moving
memory and attempting to fix up pointers, we copy the data to the
Windows heap and then maintain a little array of pointers that have been
used. Every time the Update function is called with a new pointer, we
make a copy and append it to the list. Then, on Delete, we free the
pointers from the Windows heap.
Updates golang/go#44900.
Change-Id: I42340a93fd9f6b8d10340634cf833fd4559a5f4f
Reviewed-on: https://go-review.googlesource.com/c/sys/+/300369
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
DecomposeCommandLine makes CommandLineToArgv usable in an ordinary way.
There's actually a pure-Go version of this available as the private
os.commandLineToArgv function, which we could copy, but given this is
x/sys/windows, it seems best to stick to the actual Windows primitives
which will always remain current. Then, ComposeCommandLine is just a
simple wrapper around EscapeArg (which has no native win32 substitute).
Change-Id: Ia2c7ca2ded9e5713b281dade34639dfeacf1171c
Reviewed-on: https://go-review.googlesource.com/c/sys/+/319229
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Self-relative security descriptors can sometimes be smaller than the
header size of the SECURITY_DESCRIPTOR struct, which is fine in C, but
checkptr complains about it, so instead, ensure that the allocation is
at least the size of the SECURITY_DESCRIPTOR struct.
This fixes this splat:
fatal error: checkptr: converted pointer straddles multiple allocations
goroutine 36 [running]:
runtime.throw(0x761c5f, 0x3a)
/usr/lib/go/src/runtime/panic.go:1117 +0x79 fp=0xc00005dd90 sp=0xc00005dd60 pc=0x5fb8d9
runtime.checkptrAlignment(0xc0001a4020, 0x741860, 0x1)
/usr/lib/go/src/runtime/checkptr.go:20 +0xc9 fp=0xc00005ddc0 sp=0xc00005dd90 pc=0x5c7729
golang.org/x/sys/windows.(*SECURITY_DESCRIPTOR).copySelfRelativeSecurityDescriptor(0x1b9ad638190, 0x2)
/home/zx2c4/Projects/golang-dev/sys/windows/security_windows.go:1359 +0x1b7 fp=0xc00005de50 sp=0xc00005ddc0 pc=0x6f0077
golang.org/x/sys/windows.SecurityDescriptorFromString(0x754f2b, 0x2, 0x0, 0x0, 0x0)
/home/zx2c4/Projects/golang-dev/sys/windows/security_windows.go:1371 +0xde fp=0xc00005deb8 sp=0xc00005de50 pc=0x6f019e
Change-Id: I552017a93d4ca6f6debc6f8f445dac5c6717fed1
Reviewed-on: https://go-review.googlesource.com/c/sys/+/307129
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This struct has pointers in it, which means checkptr expects for it to
be aligned properly. When we're copying a Windows-allocated struct to a
Go-allocated one, make sure that the Go allocation is aligned to the
pointer size.
This fixes the following checkptr splat:
goroutine 29 [running]:
runtime.throw(0x4f8dd9, 0x3a)
C:/hostedtoolcache/windows/go/1.16.2/x64/src/runtime/panic.go:1117 +0x79 fp=0xc000041c50 sp=0xc000041c20 pc=0x2f9879
runtime.checkptrAlignment(0xc00009c180, 0x4d8a00, 0x1)
C:/hostedtoolcache/windows/go/1.16.2/x64/src/runtime/checkptr.go:20 +0xc9 fp=0xc000041c80 sp=0xc000041c50 pc=0x2c4d09
golang.org/x/sys/windows.(*SECURITY_DESCRIPTOR).copySelfRelativeSecurityDescriptor(0x227284caa00, 0x2)
C:/Users/runneradmin/go/pkg/mod/golang.org/x/sys@v0.0.0-20210309040221-94ec62e08169/windows/security_windows.go:1347 +0x11f fp=0xc000041ce8 sp=0xc000041c80 pc=0x467f9f
golang.org/x/sys/windows.SecurityDescriptorFromString(0x4ebfb0, 0x2, 0x0, 0x0, 0x0)
Change-Id: I7eb9c07e7afb7f139473b660f82a23541663ec50
Reviewed-on: https://go-review.googlesource.com/c/sys/+/306889
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Alex copied this from a temporary thing I had written for the runtime
package. In runtime, you can't really access other packages like
syscall, so everything has to be very manual. But in x/sys, we can do
things properly. So this reimplements the function in a more straight
forward way.
Change-Id: I1634904bb1e10f33252954ce02d4b17ae56592e5
Reviewed-on: https://go-review.googlesource.com/c/sys/+/298830
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
In anticipation of the next commit which adds win32 pipe APIs, add some
of the foundational NT APIs for that, which will be required for making
a robust Go pipe library. Also add a simple test case.
Change-Id: I898bd6c5265a8939a7f05a24c4d9b22941dc56b7
Reviewed-on: https://go-review.googlesource.com/c/sys/+/298171
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
It turns out that the proc thread update function doesn't actually
allocate new memory for its arguments and instead just copies the
pointer values into the preallocated memory. Since we were allocating
that memory as []byte, the garbage collector didn't scan it for pointers
to Go allocations and freed them. We _could_ fix this by requiring that
all users of this use runtime.KeepAlive for everything they pass to the
update function, but that seems harder than necessary. Instead, we can
just do the allocation as []unsafe.Pointer, which means the GC can
operate as intended and not free these from beneath our feet. In order
to ensure this remains true, we also add a test for this.
Updates golang/go#44662.
Change-Id: Iaa8b694a6682cc1876879632c7ba068e47b8666d
Reviewed-on: https://go-review.googlesource.com/c/sys/+/297331
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
The prior function updated the TEB's LastStatus member, which is not
what we want to be doing here. It's also not consistent with Microsoft's
own Go code for their pipe library, which properly uses the "NoTeb"
variant like this commit.
For good measure, we add a simple test case to make sure these paths are
being exercised.
Change-Id: I4080898f704bdc93a6048001b06ffce516fb412d
Reviewed-on: https://go-review.googlesource.com/c/sys/+/298169
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
All references to "Errno" go through the syscalldot function, which
prepends "syscall." if the generation target is not in the syscall
package. Similarly so, we need a windowsdot function to prepend
"windows." to NTStatus.
Change-Id: I86affcf0155632ed5848ebabca97d175a041c6c3
Reviewed-on: https://go-review.googlesource.com/c/sys/+/298170
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
The same symbol name might be defined multiple times with different
function names or signatures. In that case, it's an error to redefine
the proc variable. So deduplicate these before printing.
Change-Id: I7a636cd44fb1ea6f51840ef3924d6316e266faa0
Reviewed-on: https://go-review.googlesource.com/c/sys/+/288332
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
The native NT API returns error values from a different namespace as the
usual Win32 one. This means it needs to be typed differently. This
commit adds broad support for using NTSTATUS values in a new type called
NTStatus.
First we add the type as a basic uint32. Then we add all of the
predefined constants from ntstatus.h, by augmenting mkerrors.bash to do
automatic extraction. There's a convenece way to convert an NT error to
a Win32 error, so we add the NTStatus.Errno() function. Since NTStatus
is an error type, we define an Error() function that returns a string by
asking ntdll.dll for its contents, in the exact same way that
syscall.Errno.Error() does, by calling FormatMessage. Since functions
need to actually use this, we add the rule that if a `//sys` declaration
returns an error value called "ntstatus", then the type underlying the
error interface is an NTStatus instead of an Errno. Finally we fix one
function that was returning an error interface of an Errno rather than
an NTStatus.
Change-Id: I06296b9563bbec526759d12a19f13ac6ad46dcc3
Reviewed-on: https://go-review.googlesource.com/c/sys/+/297330
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>