From 113ed24b18728121f8cf0598ebd18de5844a4478 Mon Sep 17 00:00:00 2001 From: Christoph Wurm Date: Mon, 7 Jan 2019 13:29:48 +0000 Subject: [PATCH 1/2] Update go-sysinfo --- .../providers/darwin/host_darwin_amd64.go | 6 +- .../darwin/machineid_darwin_amd64.go | 61 +++++++++++++++++++ .../providers/darwin/process_darwin_amd64.go | 60 +++++++++++++++++- .../providers/linux/process_linux.go | 41 ++++++++++++- .../providers/windows/arch_windows.go | 2 +- .../providers/windows/boottime_windows.go | 2 +- .../providers/windows/host_windows.go | 2 +- .../providers/windows/kernel_windows.go | 2 +- .../providers/windows/machineid_windows.go | 1 + .../providers/windows/os_windows.go | 1 + .../providers/windows/process_windows.go | 52 +++++++++++++++- .../elastic/go-sysinfo/types/process.go | 34 +++++++++++ vendor/vendor.json | 36 +++++------ 13 files changed, 270 insertions(+), 30 deletions(-) create mode 100644 vendor/github.com/elastic/go-sysinfo/providers/darwin/machineid_darwin_amd64.go diff --git a/vendor/github.com/elastic/go-sysinfo/providers/darwin/host_darwin_amd64.go b/vendor/github.com/elastic/go-sysinfo/providers/darwin/host_darwin_amd64.go index 0523e0202b8..9ea1708d708 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/darwin/host_darwin_amd64.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/darwin/host_darwin_amd64.go @@ -218,5 +218,9 @@ func (r *reader) time(h *host) { } func (r *reader) uniqueID(h *host) { - // TODO: call gethostuuid(uuid [16]byte, timespec) + v, err := MachineID() + if r.addErr(err) { + return + } + h.info.UniqueID = v } diff --git a/vendor/github.com/elastic/go-sysinfo/providers/darwin/machineid_darwin_amd64.go b/vendor/github.com/elastic/go-sysinfo/providers/darwin/machineid_darwin_amd64.go new file mode 100644 index 00000000000..3b3e6adae76 --- /dev/null +++ b/vendor/github.com/elastic/go-sysinfo/providers/darwin/machineid_darwin_amd64.go @@ -0,0 +1,61 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +// +build darwin,amd64,cgo + +package darwin + +// #include +// #include +import "C" + +import ( + "unsafe" + + "github.com/pkg/errors" +) + +// MachineID returns the Hardware UUID also accessible via +// About this Mac -> System Report and as the field +// IOPlatformUUID in the output of "ioreg -d2 -c IOPlatformExpertDevice". +func MachineID() (string, error) { + return getHostUUID() +} + +func getHostUUID() (string, error) { + var uuidC C.uuid_t + var id [unsafe.Sizeof(uuidC)]C.uchar + wait := C.struct_timespec{5, 0} // 5 seconds + + ret, err := C.gethostuuid(&id[0], &wait) + if ret != 0 { + if err != nil { + return "", errors.Wrapf(err, "gethostuuid failed with %v", ret) + } + + return "", errors.Errorf("gethostuuid failed with %v", ret) + } + + var uuidStringC C.uuid_string_t + var uuid [unsafe.Sizeof(uuidStringC)]C.char + _, err = C.uuid_unparse_upper(&id[0], &uuid[0]) + if err != nil { + return "", errors.Wrap(err, "uuid_unparse_upper failed") + } + + return C.GoString(&uuid[0]), nil +} diff --git a/vendor/github.com/elastic/go-sysinfo/providers/darwin/process_darwin_amd64.go b/vendor/github.com/elastic/go-sysinfo/providers/darwin/process_darwin_amd64.go index 24e3c32f2ba..ad1864dfc03 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/darwin/process_darwin_amd64.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/darwin/process_darwin_amd64.go @@ -28,6 +28,7 @@ import ( "bytes" "encoding/binary" "os" + "strconv" "time" "unsafe" @@ -39,7 +40,38 @@ import ( //go:generate sh -c "go tool cgo -godefs defs_darwin.go > ztypes_darwin_amd64.go" func (s darwinSystem) Processes() ([]types.Process, error) { - return nil, nil + n, err := C.proc_listallpids(nil, 0) + if err != nil { + return nil, errors.Wrapf(err, "error getting process count from proc_listallpids (n = %v)", n) + } else if n <= 0 { + return nil, errors.Errorf("proc_listallpids returned %v", n) + } + + var pid C.int + bufsize := n * C.int(unsafe.Sizeof(pid)) + buf := make([]byte, bufsize) + n, err = C.proc_listallpids(unsafe.Pointer(&buf[0]), bufsize) + if err != nil { + return nil, errors.Wrapf(err, "error getting processes from proc_listallpids (n = %v)", n) + } else if n <= 0 { + return nil, errors.Errorf("proc_listallpids returned %v", n) + } + + bbuf := bytes.NewBuffer(buf) + processes := make([]types.Process, 0, n) + for i := 0; i < int(n); i++ { + err = binary.Read(bbuf, binary.LittleEndian, &pid) + if err != nil { + return nil, errors.Wrap(err, "error reading binary list of PIDs") + } + + if pid == 0 { + continue + } + + processes = append(processes, &process{pid: int(pid)}) + } + return processes, nil } func (s darwinSystem) Process(pid int) (types.Process, error) { @@ -60,6 +92,10 @@ type process struct { env map[string]string } +func (p *process) PID() int { + return p.pid +} + func (p *process) Info() (types.ProcessInfo, error) { var task procTaskAllInfo if err := getProcTaskAllInfo(p.pid, &task); err != nil { @@ -87,6 +123,22 @@ func (p *process) Info() (types.ProcessInfo, error) { }, nil } +func (p *process) User() (types.UserInfo, error) { + var task procTaskAllInfo + if err := getProcTaskAllInfo(p.pid, &task); err != nil { + return types.UserInfo{}, err + } + + return types.UserInfo{ + UID: strconv.Itoa(int(task.Pbsd.Pbi_ruid)), + EUID: strconv.Itoa(int(task.Pbsd.Pbi_uid)), + SUID: strconv.Itoa(int(task.Pbsd.Pbi_svuid)), + GID: strconv.Itoa(int(task.Pbsd.Pbi_rgid)), + EGID: strconv.Itoa(int(task.Pbsd.Pbi_gid)), + SGID: strconv.Itoa(int(task.Pbsd.Pbi_svgid)), + }, nil +} + func (p *process) Environment() (map[string]string, error) { return p.env, nil } @@ -121,8 +173,10 @@ func getProcTaskAllInfo(pid int, info *procTaskAllInfo) error { size := C.int(unsafe.Sizeof(*info)) ptr := unsafe.Pointer(info) - n := C.proc_pidinfo(C.int(pid), C.PROC_PIDTASKALLINFO, 0, ptr, size) - if n != size { + n, err := C.proc_pidinfo(C.int(pid), C.PROC_PIDTASKALLINFO, 0, ptr, size) + if err != nil { + return err + } else if n != size { return errors.New("failed to read process info with proc_pidinfo") } diff --git a/vendor/github.com/elastic/go-sysinfo/providers/linux/process_linux.go b/vendor/github.com/elastic/go-sysinfo/providers/linux/process_linux.go index 4c6c713b583..4f5425e8b47 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/linux/process_linux.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/linux/process_linux.go @@ -22,6 +22,7 @@ import ( "io/ioutil" "os" "strconv" + "strings" "time" "github.com/prometheus/procfs" @@ -36,7 +37,6 @@ func (s linuxSystem) Processes() ([]types.Process, error) { if err != nil { return nil, err } - s.procFS.Path() processes := make([]types.Process, 0, len(procs)) for _, proc := range procs { @@ -69,8 +69,12 @@ type process struct { info *types.ProcessInfo } +func (p *process) PID() int { + return p.Proc.PID +} + func (p *process) path(pa ...string) string { - return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...) + return p.fs.Path(append([]string{strconv.Itoa(p.PID())}, pa...)...) } func (p *process) CWD() (string, error) { @@ -115,7 +119,7 @@ func (p *process) Info() (types.ProcessInfo, error) { p.info = &types.ProcessInfo{ Name: stat.Comm, - PID: p.PID, + PID: p.PID(), PPID: stat.PPID, CWD: cwd, Exe: exe, @@ -204,6 +208,37 @@ func (p *process) Capabilities() (*types.CapabilityInfo, error) { return readCapabilities(content) } +func (p *process) User() (types.UserInfo, error) { + content, err := ioutil.ReadFile(p.path("status")) + if err != nil { + return types.UserInfo{}, err + } + + var user types.UserInfo + err = parseKeyValue(content, ":", func(key, value []byte) error { + // See proc(5) for the format of /proc/[pid]/status + switch string(key) { + case "Uid": + ids := strings.Split(string(value), "\t") + if len(ids) >= 3 { + user.UID = ids[0] + user.EUID = ids[1] + user.SUID = ids[2] + } + case "Gid": + ids := strings.Split(string(value), "\t") + if len(ids) >= 3 { + user.GID = ids[0] + user.EGID = ids[1] + user.SGID = ids[2] + } + } + return nil + }) + + return user, nil +} + func ticksToDuration(ticks uint64) time.Duration { seconds := float64(ticks) / float64(userHz) * float64(time.Second) return time.Duration(int64(seconds)) diff --git a/vendor/github.com/elastic/go-sysinfo/providers/windows/arch_windows.go b/vendor/github.com/elastic/go-sysinfo/providers/windows/arch_windows.go index 4259ba427fd..0edfc4d765e 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/windows/arch_windows.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/windows/arch_windows.go @@ -18,7 +18,7 @@ package windows import ( - "github.com/elastic/go-windows" + windows "github.com/elastic/go-windows" ) func Architecture() (string, error) { diff --git a/vendor/github.com/elastic/go-sysinfo/providers/windows/boottime_windows.go b/vendor/github.com/elastic/go-sysinfo/providers/windows/boottime_windows.go index 11db527b99b..fbac5879847 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/windows/boottime_windows.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/windows/boottime_windows.go @@ -20,7 +20,7 @@ package windows import ( "time" - "github.com/elastic/go-windows" + windows "github.com/elastic/go-windows" "github.com/pkg/errors" ) diff --git a/vendor/github.com/elastic/go-sysinfo/providers/windows/host_windows.go b/vendor/github.com/elastic/go-sysinfo/providers/windows/host_windows.go index d523d177f2f..0bc99e4696a 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/windows/host_windows.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/windows/host_windows.go @@ -21,7 +21,7 @@ import ( "os" "time" - "github.com/elastic/go-windows" + windows "github.com/elastic/go-windows" "github.com/joeshaw/multierror" "github.com/pkg/errors" diff --git a/vendor/github.com/elastic/go-sysinfo/providers/windows/kernel_windows.go b/vendor/github.com/elastic/go-sysinfo/providers/windows/kernel_windows.go index 0d2ae188bcb..c295c799646 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/windows/kernel_windows.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/windows/kernel_windows.go @@ -18,7 +18,7 @@ package windows import ( - "github.com/elastic/go-windows" + windows "github.com/elastic/go-windows" ) const windowsKernelExe = `C:\Windows\System32\ntoskrnl.exe` diff --git a/vendor/github.com/elastic/go-sysinfo/providers/windows/machineid_windows.go b/vendor/github.com/elastic/go-sysinfo/providers/windows/machineid_windows.go index 4a113f07e58..ea814f4cadf 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/windows/machineid_windows.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/windows/machineid_windows.go @@ -35,6 +35,7 @@ func getMachineGUID() (string, error) { if err != nil { return "", errors.Wrapf(err, `failed to open HKLM\%v`, path) } + defer k.Close() guid, _, err := k.GetStringValue(name) if err != nil { diff --git a/vendor/github.com/elastic/go-sysinfo/providers/windows/os_windows.go b/vendor/github.com/elastic/go-sysinfo/providers/windows/os_windows.go index 41962e52261..7a4d899f5d9 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/windows/os_windows.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/windows/os_windows.go @@ -37,6 +37,7 @@ func OperatingSystem() (*types.OSInfo, error) { if err != nil { return nil, errors.Wrapf(err, `failed to open HKLM\%v`, path) } + defer k.Close() osInfo := &types.OSInfo{ Family: "windows", diff --git a/vendor/github.com/elastic/go-sysinfo/providers/windows/process_windows.go b/vendor/github.com/elastic/go-sysinfo/providers/windows/process_windows.go index 7229da5a7c1..8a19e43e8af 100644 --- a/vendor/github.com/elastic/go-sysinfo/providers/windows/process_windows.go +++ b/vendor/github.com/elastic/go-sysinfo/providers/windows/process_windows.go @@ -26,8 +26,9 @@ import ( "unsafe" "github.com/pkg/errors" + syswin "golang.org/x/sys/windows" - "github.com/elastic/go-windows" + windows "github.com/elastic/go-windows" "github.com/elastic/go-sysinfo/types" ) @@ -45,6 +46,12 @@ func (s windowsSystem) Processes() (procs []types.Process, err error) { procs = make([]types.Process, 0, len(pids)) var proc types.Process for _, pid := range pids { + if pid == 0 || pid == 4 { + // The Idle and System processes (PIDs 0 and 4) can never be + // opened by user-level code (see documentation for OpenProcess). + continue + } + if proc, err = s.Process(int(pid)); err == nil { procs = append(procs, proc) } @@ -68,6 +75,10 @@ type process struct { info types.ProcessInfo } +func (p *process) PID() int { + return p.pid +} + func newProcess(pid int) (*process, error) { p := &process{pid: pid} if err := p.init(); err != nil { @@ -241,6 +252,45 @@ func (p *process) Info() (types.ProcessInfo, error) { return p.info, nil } +func (p *process) User() (types.UserInfo, error) { + handle, err := p.open() + if err != nil { + return types.UserInfo{}, errors.Wrap(err, "OpenProcess failed") + } + defer syscall.CloseHandle(handle) + + var accessToken syswin.Token + err = syswin.OpenProcessToken(syswin.Handle(handle), syscall.TOKEN_QUERY, &accessToken) + if err != nil { + return types.UserInfo{}, errors.Wrap(err, "OpenProcessToken failed") + } + defer accessToken.Close() + + tokenUser, err := accessToken.GetTokenUser() + if err != nil { + return types.UserInfo{}, errors.Wrap(err, "GetTokenUser failed") + } + + sid, err := tokenUser.User.Sid.String() + if err != nil { + return types.UserInfo{}, errors.Wrap(err, "failed to look up user SID") + } + + tokenGroup, err := accessToken.GetTokenPrimaryGroup() + if err != nil { + return types.UserInfo{}, errors.Wrap(err, "GetTokenPrimaryGroup failed") + } + gsid, err := tokenGroup.PrimaryGroup.String() + if err != nil { + return types.UserInfo{}, errors.Wrap(err, "failed to look up primary group SID") + } + + return types.UserInfo{ + UID: sid, + GID: gsid, + }, nil +} + func (p *process) Memory() (types.MemoryInfo, error) { handle, err := p.open() if err != nil { diff --git a/vendor/github.com/elastic/go-sysinfo/types/process.go b/vendor/github.com/elastic/go-sysinfo/types/process.go index fce67badc3b..ade433f8c95 100644 --- a/vendor/github.com/elastic/go-sysinfo/types/process.go +++ b/vendor/github.com/elastic/go-sysinfo/types/process.go @@ -23,6 +23,8 @@ type Process interface { CPUTimer Info() (ProcessInfo, error) Memory() (MemoryInfo, error) + User() (UserInfo, error) + PID() int } type ProcessInfo struct { @@ -35,6 +37,38 @@ type ProcessInfo struct { StartTime time.Time `json:"start_time"` } +// UserInfo contains information about the UID and GID +// values of a process. +type UserInfo struct { + // UID is the user ID. + // On Linux and Darwin (macOS) this is the real user ID. + // On Windows, this is the security identifier (SID) of the + // user account of the process access token. + UID string `json:"uid"` + + // On Linux and Darwin (macOS) this is the effective user ID. + // On Windows, this is empty. + EUID string `json:"euid"` + + // On Linux and Darwin (macOS) this is the saved user ID. + // On Windows, this is empty. + SUID string `json:"suid"` + + // GID is the primary group ID. + // On Linux and Darwin (macOS) this is the real group ID. + // On Windows, this is the security identifier (SID) of the + // primary group of the process access token. + GID string `json:"gid"` + + // On Linux and Darwin (macOS) this is the effective group ID. + // On Windows, this is empty. + EGID string `json:"egid"` + + // On Linux and Darwin (macOS) this is the saved group ID. + // On Windows, this is empty. + SGID string `json:"sgid"` +} + type Environment interface { Environment() (map[string]string, error) } diff --git a/vendor/vendor.json b/vendor/vendor.json index 50618b2cf56..3f920d6075e 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -898,44 +898,44 @@ { "checksumSHA1": "QhFIpuHPaV6hKejKcc2wm6y4MSQ=", "path": "github.com/elastic/go-sysinfo", - "revision": "7b021494a9562d0c3f0422d49b9980709c5650e9", - "revisionTime": "2018-09-11T17:37:16Z" + "revision": "59ef8c0eae46c0929e3b219ac86368d4b5934f91", + "revisionTime": "2019-01-07T12:18:35Z" }, { "checksumSHA1": "GiZCjX17K265TtamGZZw4R2Jwbk=", "path": "github.com/elastic/go-sysinfo/internal/registry", - "revision": "7b021494a9562d0c3f0422d49b9980709c5650e9", - "revisionTime": "2018-09-11T17:37:16Z" + "revision": "59ef8c0eae46c0929e3b219ac86368d4b5934f91", + "revisionTime": "2019-01-07T12:18:35Z" }, { - "checksumSHA1": "432ecsMRmLpy5OvXMhQE/k9KWLQ=", + "checksumSHA1": "ovafihHzpBx9Y7+lZh9X5KwNCvE=", "path": "github.com/elastic/go-sysinfo/providers/darwin", - "revision": "7b021494a9562d0c3f0422d49b9980709c5650e9", - "revisionTime": "2018-09-11T17:37:16Z" + "revision": "59ef8c0eae46c0929e3b219ac86368d4b5934f91", + "revisionTime": "2019-01-07T12:18:35Z" }, { - "checksumSHA1": "1eCL0MsvmiyjNvh0tcnnR4rmcWk=", + "checksumSHA1": "AK76ZxnuvK02Dfpmj7b2TD/aiSI=", "path": "github.com/elastic/go-sysinfo/providers/linux", - "revision": "7b021494a9562d0c3f0422d49b9980709c5650e9", - "revisionTime": "2018-09-11T17:37:16Z" + "revision": "59ef8c0eae46c0929e3b219ac86368d4b5934f91", + "revisionTime": "2019-01-07T12:18:35Z" }, { "checksumSHA1": "RWLvcP1w9ynKbuCqiW6prwd+EDU=", "path": "github.com/elastic/go-sysinfo/providers/shared", - "revision": "7b021494a9562d0c3f0422d49b9980709c5650e9", - "revisionTime": "2018-09-11T17:37:16Z" + "revision": "59ef8c0eae46c0929e3b219ac86368d4b5934f91", + "revisionTime": "2019-01-07T12:18:35Z" }, { - "checksumSHA1": "lWVD4w1xiAkFZgQPZAYz+fTZsrU=", + "checksumSHA1": "aF05MEkMjbRekzHlwFxmd5WBpeY=", "path": "github.com/elastic/go-sysinfo/providers/windows", - "revision": "7b021494a9562d0c3f0422d49b9980709c5650e9", - "revisionTime": "2018-09-11T17:37:16Z" + "revision": "59ef8c0eae46c0929e3b219ac86368d4b5934f91", + "revisionTime": "2019-01-07T12:18:35Z" }, { - "checksumSHA1": "tIqFxnZi9XvC70dMoZDSoUtEVQY=", + "checksumSHA1": "MLQioPEjULYbNqqCjfB1/cux08E=", "path": "github.com/elastic/go-sysinfo/types", - "revision": "7b021494a9562d0c3f0422d49b9980709c5650e9", - "revisionTime": "2018-09-11T17:37:16Z" + "revision": "59ef8c0eae46c0929e3b219ac86368d4b5934f91", + "revisionTime": "2019-01-07T12:18:35Z" }, { "checksumSHA1": "tNszmkpuJYZMX8l8rlnvBDtoc1M=", From 9214b0513b6d200868fb1143d22b9668181247c5 Mon Sep 17 00:00:00 2001 From: Christoph Wurm Date: Mon, 7 Jan 2019 13:47:47 +0000 Subject: [PATCH 2/2] Update NOTICE --- NOTICE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NOTICE.txt b/NOTICE.txt index edfb7897d78..17030eedb06 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -584,7 +584,7 @@ Apache License 2.0 -------------------------------------------------------------------- Dependency: github.com/elastic/go-sysinfo -Revision: 7b021494a9562d0c3f0422d49b9980709c5650e9 +Revision: 59ef8c0eae46c0929e3b219ac86368d4b5934f91 License type (autodetected): Apache-2.0 ./vendor/github.com/elastic/go-sysinfo/LICENSE.txt: --------------------------------------------------------------------