Skip to content

Commit

Permalink
Windows: Fix crash due to unterminated string (#58) (1.0.2)
Browse files Browse the repository at this point in the history
This fixes a crash when fetching a process arguments. The command-line
string read from the target process memory sometimes is not terminated.
It can cause bogus characters appended to the command-line or a crash.
  • Loading branch information
adriansr authored Jul 9, 2019
1 parent 9a4be54 commit 06c1f46
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Fixed a leak when calling the CommandLineToArgv function. [#51](https://github.com/elastic/go-sysinfo/pull/51)

### Security

## [1.0.2] - 2019-07-09

### Fixed

- Fixed a leak when calling the CommandLineToArgv function. [#51](https://github.com/elastic/go-sysinfo/pull/51)
- Fixed a crash when calling the CommandLineToArgv function. [#58](https://github.com/elastic/go-sysinfo/pull/58)

## [1.0.1] - 2019-05-08

### Fixed
Expand Down
26 changes: 23 additions & 3 deletions providers/windows/process_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,14 @@ func getUserProcessParams(handle syscall.Handle, pbi windows.ProcessBasicInforma
// read an UTF-16 string from another process memory. Result is an []byte
// with the UTF-16 data.
func readProcessUnicodeString(handle syscall.Handle, s *windows.UnicodeString) ([]byte, error) {
buf := make([]byte, s.Size)
nRead, err := windows.ReadProcessMemory(handle, s.Buffer, buf)
// Allocate an extra UTF-16 null character at the end in case the read string
// is not terminated.
extra := 2
if s.Size&1 != 0 {
extra = 3 // If size is odd, need 3 nulls to terminate.
}
buf := make([]byte, int(s.Size)+extra)
nRead, err := windows.ReadProcessMemory(handle, s.Buffer, buf[:s.Size])
if err != nil {
return nil, err
}
Expand All @@ -221,9 +227,23 @@ func readProcessUnicodeString(handle syscall.Handle, s *windows.UnicodeString) (
// Use Windows' CommandLineToArgv API to split an UTF-16 command line string
// into a list of parameters.
func splitCommandline(utf16 []byte) ([]string, error) {
if len(utf16) == 0 {
n := len(utf16)
// Discard odd byte
if n&1 != 0 {
n--
utf16 = utf16[:n]
}
if n == 0 {
return nil, nil
}
terminated := false
for i := 0; i < n && !terminated; i += 2 {
terminated = utf16[i] == 0 && utf16[i+1] == 0
}
if !terminated {
// Append a null uint16 at the end if terminator is missing
utf16 = append(utf16, 0, 0)
}
var numArgs int32
argsWide, err := syscall.CommandLineToArgv((*uint16)(unsafe.Pointer(&utf16[0])), &numArgs)
if err != nil {
Expand Down

0 comments on commit 06c1f46

Please sign in to comment.