Skip to content

Commit

Permalink
Request lowest access privilege required in Windows OpenProcess calls. (
Browse files Browse the repository at this point in the history
#50)

Gosigar requests PROCESS_ALL_ACCESS permission but the operation that it performs, GetProcessMemoryInfo, requires only PROCESS_QUERY_INFORMATION and PROCESS_VM_READ. gosigar should only request the permissions that it requires.

In other parts of gosigar it requests PROCESS_QUERY_INFORMATION, but in Windows Vista and newer there is a more limited privilege we can request called PROCESS_QUERY_LIMITED_INFORMATION. This can be used for GetProcessTimes, GetProcessImageFileName, and GetExitCodeProcess. It cannot be used for OpenProcessToken.
  • Loading branch information
andrewkroh authored and ruflin committed Oct 13, 2016
1 parent c476970 commit 15322f7
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 5 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added

### Changed
- Changed several `OpenProcess` calls on Windows to request the lowest possible access privilege. #50

### Deprecated

### Removed

### Fixed
- Fix value of `Mem.ActualFree` and `Mem.ActualUsed` on Windows. #49
45 changes: 40 additions & 5 deletions sigar_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ var (
)

const (
PROCESS_ALL_ACCESS = 0x001f0fff
TH32CS_SNAPPROCESS = 0x02
MAX_PATH = 260
)
Expand Down Expand Up @@ -79,7 +78,43 @@ type Win32_Process struct {
CommandLine string
}

// processQueryLimitedInfoAccess is set to PROCESS_QUERY_INFORMATION for Windows
// 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer
// OS versions it is set to PROCESS_QUERY_LIMITED_INFORMATION.
var processQueryLimitedInfoAccess = PROCESS_QUERY_LIMITED_INFORMATION

func init() {
major, minor, _ := GetWindowsVersion()

if !isWindowsVistaOrGreater(major, minor) {
// PROCESS_QUERY_LIMITED_INFORMATION cannot be used on 2003 or XP.
processQueryLimitedInfoAccess = syscall.PROCESS_QUERY_INFORMATION
}
}

func isWindowsVistaOrGreater(major, minor int) bool {
// Vista is 6.0.
return major >= 6 && minor >= 0
}

// GetWindowsVersion returns the Windows version information. Applications not
// manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version
// value (6.2).
//
// For a table of version numbers see:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx
func GetWindowsVersion() (major, minor, build int) {
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
ver, err := syscall.GetVersion()
if err != nil {
// GetVersion should never return an error.
panic(fmt.Errorf("GetVersion failed: %v", err))
}

major = int(ver & 0xFF)
minor = int(ver >> 8 & 0xFF)
build = int(ver >> 16)
return major, minor, build
}

func (self *LoadAverage) Get() error {
Expand Down Expand Up @@ -288,7 +323,7 @@ func (self *ProcState) Get(pid int) error {

func GetProcName(pid int) (string, error) {

handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid))
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))

defer syscall.CloseHandle(handle)

Expand Down Expand Up @@ -354,7 +389,7 @@ func GetProcCredName(pid int) (string, error) {

func GetProcStatus(pid int) (RunState, error) {

handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid))
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))

defer syscall.CloseHandle(handle)

Expand Down Expand Up @@ -396,7 +431,7 @@ func GetParentPid(pid int) (int, error) {
}

func (self *ProcMem) Get(pid int) error {
handle, err := syscall.OpenProcess(PROCESS_ALL_ACCESS, false, uint32(pid))
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|PROCESS_VM_READ, false, uint32(pid))

defer syscall.CloseHandle(handle)

Expand Down Expand Up @@ -428,7 +463,7 @@ func (self *ProcMem) Get(pid int) error {
}

func (self *ProcTime) Get(pid int) error {
handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid))
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))

defer syscall.CloseHandle(handle)

Expand Down
7 changes: 7 additions & 0 deletions syscall_windows.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package gosigar

// Process-specific access rights. Others are declared in the syscall package.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx
const (
PROCESS_QUERY_LIMITED_INFORMATION uint32 = 0x1000
PROCESS_VM_READ uint32 = 0x0010
)

// Use "GOOS=windows go generate -v -x ." to generate the source.

// Add -trace to enable debug prints around syscalls.
Expand Down

0 comments on commit 15322f7

Please sign in to comment.