diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-05-13 09:01:49 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-05-13 13:28:00 +0200 |
commit | cdb3701c95cbe6379288c486231e71e42dca0601 (patch) | |
tree | 710f0442ce9e89bc7832c9db56bfa8cdef00bb64 /service | |
parent | ui: lock runtime thread as early as possible (diff) | |
download | wireguard-windows-cdb3701c95cbe6379288c486231e71e42dca0601.tar.xz wireguard-windows-cdb3701c95cbe6379288c486231e71e42dca0601.zip |
service: allow go to create correct environment block
Diffstat (limited to 'service')
-rw-r--r-- | service/ipc_server.go | 13 | ||||
-rw-r--r-- | service/securityapi.go | 29 | ||||
-rw-r--r-- | service/service_manager.go | 18 | ||||
-rw-r--r-- | service/zsyscall_windows.go | 33 |
4 files changed, 10 insertions, 83 deletions
diff --git a/service/ipc_server.go b/service/ipc_server.go index becad3ee..12e01ce2 100644 --- a/service/ipc_server.go +++ b/service/ipc_server.go @@ -29,14 +29,9 @@ var managerServicesLock sync.RWMutex var haveQuit uint32 var quitManagersChan = make(chan struct{}, 1) -type UserTokenInfo struct { - elevatedToken windows.Token - elevatedEnvironment []string -} - type ManagerService struct { events *os.File - userTokenInfo *UserTokenInfo + elevatedToken windows.Token } func (s *ManagerService) StoredConfig(tunnelName string, config *conf.Config) error { @@ -258,7 +253,7 @@ func (s *ManagerService) UpdateState(_ uintptr, state *UpdateState) error { } func (s *ManagerService) Update(_ uintptr, _ *uintptr) error { - progress := updater.DownloadVerifyAndExecute(uintptr(s.userTokenInfo.elevatedToken), s.userTokenInfo.elevatedEnvironment) + progress := updater.DownloadVerifyAndExecute(uintptr(s.elevatedToken)) go func() { for { dp := <-progress @@ -271,10 +266,10 @@ func (s *ManagerService) Update(_ uintptr, _ *uintptr) error { return nil } -func IPCServerListen(reader *os.File, writer *os.File, events *os.File, userTokenInfo *UserTokenInfo) error { +func IPCServerListen(reader *os.File, writer *os.File, events *os.File, elevatedToken windows.Token) error { service := &ManagerService{ events: events, - userTokenInfo: userTokenInfo, + elevatedToken: elevatedToken, } server := rpc.NewServer() diff --git a/service/securityapi.go b/service/securityapi.go index 37713b32..d89d9404 100644 --- a/service/securityapi.go +++ b/service/securityapi.go @@ -9,7 +9,6 @@ import ( "errors" "golang.org/x/sys/windows" "runtime" - "unicode/utf16" "unsafe" ) @@ -53,34 +52,6 @@ const ( SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010 ) -//sys createEnvironmentBlock(block *uintptr, token windows.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock -//sys destroyEnvironmentBlock(block uintptr) (err error) = userenv.DestroyEnvironmentBlock - -func userEnviron(token windows.Token) (env []string, err error) { - var block uintptr - err = createEnvironmentBlock(&block, token, false) - if err != nil { - return - } - offset := uintptr(0) - for { - entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(block + offset))[:] - for i, v := range entry { - if v == 0 { - entry = entry[:i] - break - } - } - if len(entry) == 0 { - break - } - env = append(env, string(utf16.Decode(entry))) - offset += 2 * (uintptr(len(entry)) + 1) - } - destroyEnvironmentBlock(block) - return -} - func tokenIsElevated(token windows.Token) bool { var isElevated uint32 var outLen uint32 diff --git a/service/service_manager.go b/service/service_manager.go index c61bd517..92508215 100644 --- a/service/service_manager.go +++ b/service/service_manager.go @@ -110,22 +110,17 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest userToken.Close() return } - userTokenInfo := &UserTokenInfo{} - userTokenInfo.elevatedToken, err = getElevatedToken(userToken) + //TODO: The environment that Go gets from CreateEnvironmentBlock seems to have the same PATH as the userToken. Aren't there attacks? + elevatedToken, err := getElevatedToken(userToken) if err != nil { log.Printf("Unable to elevate token: %v", err) return } - if userTokenInfo.elevatedToken != userToken { + if elevatedToken != userToken { userToken.Close() } - defer userTokenInfo.elevatedToken.Close() + defer elevatedToken.Close() userToken = 0 - userTokenInfo.elevatedEnvironment, err = userEnviron(userTokenInfo.elevatedToken) //TODO: This seems to have the same PATH as the userToken. Aren't there attacks? - if err != nil { - log.Printf("Unable to determine elevated environment: %v", err) - return - } first := true for { if stoppingManager { @@ -155,7 +150,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest return } ourEvents, theirEvents, theirEventStr, err := inheritableEvents() - err = IPCServerListen(ourReader, ourWriter, ourEvents, userTokenInfo) + err = IPCServerListen(ourReader, ourWriter, ourEvents, elevatedToken) if err != nil { log.Printf("Unable to listen on IPC pipes: %v", err) return @@ -169,10 +164,9 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest log.Printf("Starting UI process for user '%s@%s' for session %d", username, domain, session) attr := &os.ProcAttr{ Sys: &syscall.SysProcAttr{ - Token: syscall.Token(userTokenInfo.elevatedToken), + Token: syscall.Token(elevatedToken), }, Files: []*os.File{devNull, devNull, devNull}, - Env: userTokenInfo.elevatedEnvironment, } procsLock.Lock() var proc *os.Process diff --git a/service/zsyscall_windows.go b/service/zsyscall_windows.go index 20f9753b..bb8d89d4 100644 --- a/service/zsyscall_windows.go +++ b/service/zsyscall_windows.go @@ -38,15 +38,12 @@ func errnoErr(e syscall.Errno) error { var ( modwtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll") - moduserenv = windows.NewLazySystemDLL("userenv.dll") modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") modkernel32 = windows.NewLazySystemDLL("kernel32.dll") procWTSQueryUserToken = modwtsapi32.NewProc("WTSQueryUserToken") procWTSEnumerateSessionsW = modwtsapi32.NewProc("WTSEnumerateSessionsW") procWTSFreeMemory = modwtsapi32.NewProc("WTSFreeMemory") - procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") - procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") procNotifyServiceStatusChangeW = modadvapi32.NewProc("NotifyServiceStatusChangeW") procSleepEx = modkernel32.NewProc("SleepEx") ) @@ -80,36 +77,6 @@ func wtsFreeMemory(ptr uintptr) { return } -func createEnvironmentBlock(block *uintptr, token windows.Token, inheritExisting bool) (err error) { - var _p0 uint32 - if inheritExisting { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func destroyEnvironmentBlock(block uintptr) (err error) { - r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(block), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - func notifyServiceStatusChange(service windows.Handle, notifyMask uint32, notifyBuffer uintptr) (status uint32) { r0, _, _ := syscall.Syscall(procNotifyServiceStatusChangeW.Addr(), 3, uintptr(service), uintptr(notifyMask), uintptr(notifyBuffer)) status = uint32(r0) |