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>
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>
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>
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 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>
This fixes the name of a struct to match Microsoft's documentation.
It also reverts a change I made in the last patchset of CL 285714. The
idea there was that a Go bool would suffice for a win32 BOOL, because of
little endian. But in fact, a value of 0xff000000 would be treated as
false by Go but true by C, which is a problem. So this changes to using
a vanilla int32 type, which matches the C "int" used in the Microsoft
headers.
Change-Id: Id7cd306e916b3754e8dfe32bf11ec30cad3a13b4
Reviewed-on: https://go-review.googlesource.com/c/sys/+/285717
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 Windows compilers appear to align JOBOBJECT_BASIC_LIMIT_INFORMATION
to an 8-byte boundary, which on 32-bit systems means adding 32 bits of
padding. Unfortunately we can't always add a padding field, because
no padding is required on a 64-bit system. So use different versions
of the struct for different targets.
Fixesgolang/go#41001
Change-Id: I38d14edfd3f3a80da22825455f20e1f7de136638
Reviewed-on: https://go-review.googlesource.com/c/sys/+/251197
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Marc-Antoine Ruel <maruel@google.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit adds the following MUI functions:
- GetUserPreferredUILanguages
- GetSystemPreferredUILanguages
- GetThreadPreferredUILanguages
- GetProcessPreferredUILanguages
Change-Id: I44f1c07245ab814935778c6b910b224d24cc753c
Reviewed-on: https://go-review.googlesource.com/c/sys/+/207860
Reviewed-by: Simon Rozman <simon@rozman.si>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
The SECURITY_ATTRIBUTES struct always takes a SECURITY_DESCRIPTOR
pointer. Now that we've defined SECURITY_DESCRIPTOR, make
SECURITY_ATTRIBUTES properly specify the type. This eliminates the need
for terrible uintptr(unsafe.Pointer(...)) casts everywhere.
Change-Id: Ibbc85524cfe33589d43f963e10aa19d7f47686f2
Reviewed-on: https://go-review.googlesource.com/c/sys/+/196797
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This adds the basic foundation for dealing with security descriptors and
access control lists. The basic creators and getters are included in
this patch. These are some of the most fundamental security objects on NT,
and any work with the security API is fairly limited without it. These
are "core" NT structures.
Change-Id: I9a6399cb6ee41a825de30d5364ab69102d5f6d57
Reviewed-on: https://go-review.googlesource.com/c/sys/+/195498
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
There are a few functions to control the behavior of shutdown and
logout, both for what the current process does during shutdown, and also
whether or not the current process is running in an interactive session.
The below code is a port of the MSDN example code to Go using one of the
added new functions:
https://docs.microsoft.com/en-us/windows/win32/shutdown/how-to-shut-down-the-system
func shutdownLikeMSDNDoes() error {
seShutdownName, err := windows.UTF16PtrFromString("SeShutdownPrivilege")
if err != nil {
return err
}
var shutdownPriv windows.Tokenprivileges
err = windows.LookupPrivilegeValue(nil, seShutdownName, &shutdownPriv.Privileges[0].Luid)
if err != nil {
return err
}
shutdownPriv.Privileges[0].Attributes = windows.SE_PRIVILEGE_ENABLED
shutdownPriv.PrivilegeCount = 1
process, err := windows.GetCurrentProcess()
if err != nil {
return err
}
var token windows.Token
err = windows.OpenProcessToken(process, windows.TOKEN_ADJUST_PRIVILEGES | windows.TOKEN_QUERY, &token)
if err != nil {
return err
}
defer token.Close()
err = windows.AdjustTokenPrivileges(token, false, &shutdownPriv, 0, nil, nil)
if err != nil {
return err
}
err = windows.ExitWindowsEx(windows.EWX_SHUTDOWN | windows.EWX_FORCE,
windows.SHTDN_REASON_MAJOR_OPERATINGSYSTEM | windows.SHTDN_REASON_MINOR_UPGRADE | windows.SHTDN_REASON_FLAG_PLANNED)
if err != nil {
return err
}
return nil
}
Note, though, that this function doesn't set the token privs back to how
they were before, which isn't good. A more robust method than the MSDN
one above would be to duplicate&impersonate.
Fixes: golang/go#34271
Change-Id: Ibe55ddd35b709d9ab793cb9af47c39901c5e5c69
Reviewed-on: https://go-review.googlesource.com/c/sys/+/195497
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bruce Downs <bruceadowns@gmail.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Indeed Go has mutexes of its own, but these are considerably
different from the native Windows ones, that can work across processes
and be put in various namespaces. They're an essential part of Windows
systems programming and important for interfacing with various external
interfaces.
Change-Id: I03987800ed1c134442321678c2c7d7aa359ecb36
Reviewed-on: https://go-review.googlesource.com/c/sys/+/192497
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>