fixed parsing /proc/$pid/stat starttime field

On systems that have been running for a long time (for example 552
days) we were failing parsing the starttime field:

```
Could not find or convert Starttime. This should never happen.
Please report this incident to the Opensnitch developers:
strconv.Atoi: parsing "4242026842": value out of range
```

- extra: fixed tests.
This commit is contained in:
Gustavo Iñiguez Goia 2021-04-20 16:31:49 +02:00
parent 80c9519d08
commit 0f7e93acdc
3 changed files with 17 additions and 17 deletions

View file

@ -15,11 +15,11 @@ type value struct {
Process *Process
//Starttime uniquely identifies a process, it is the 22nd value in /proc/<PID>/stat
//if another process starts with the same PID, it's Starttime will be unique
Starttime uint32
Starttime uint64
}
var (
activePids = make(map[uint32]value)
activePids = make(map[uint64]value)
activePidsLock = sync.RWMutex{}
)
@ -38,14 +38,14 @@ func MonitorActivePids() {
deleteProcEntry(int(k))
continue
}
startTime, err := strconv.Atoi(strings.Split(string(data), " ")[21])
startTime, err := strconv.ParseInt(strings.Split(string(data), " ")[21], 10, 64)
if err != nil {
log.Error("Could not find or convert Starttime. This should never happen. Please report this incident to the Opensnitch developers.")
log.Error("Could not find or convert Starttime. This should never happen. Please report this incident to the Opensnitch developers: %v", err)
delete(activePids, k)
deleteProcEntry(int(k))
continue
}
if uint32(startTime) != v.Starttime {
if uint64(startTime) != v.Starttime {
//extremely unlikely: the original process has quit and another process
//was started with the same PID - all this in less than 1 second
log.Error("Same PID but different Starttime. Please report this incident to the Opensnitch developers.")
@ -58,7 +58,7 @@ func MonitorActivePids() {
}
}
func findProcessInActivePidsCache(pid uint32) *Process {
func findProcessInActivePidsCache(pid uint64) *Process {
activePidsLock.Lock()
defer activePidsLock.Unlock()
if value, ok := activePids[pid]; ok {
@ -67,23 +67,23 @@ func findProcessInActivePidsCache(pid uint32) *Process {
return nil
}
func addToActivePidsCache(pid uint32, proc *Process) {
func addToActivePidsCache(pid uint64, proc *Process) {
data, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", pid))
if err != nil {
//most likely the process has quit by now
return
}
startTime, err2 := strconv.Atoi(strings.Split(string(data), " ")[21])
startTime, err2 := strconv.ParseInt(strings.Split(string(data), " ")[21], 10, 64)
if err2 != nil {
log.Error("Could not find or convert Starttime. This should never happen. Please report this incident to the Opensnitch developers.")
log.Error("Could not find or convert Starttime. This should never happen. Please report this incident to the Opensnitch developers: %v", err)
return
}
activePidsLock.Lock()
activePids[pid] = value{
Process: proc,
Starttime: uint32(startTime),
Starttime: uint64(startTime),
}
activePidsLock.Unlock()
}

View file

@ -28,7 +28,7 @@ func TestMonitorActivePids(t *testing.T) {
fmt.Println("tmp dir", tmpDir)
defer os.RemoveAll(tmpDir)
go monitorActivePids()
go MonitorActivePids()
//build a "helper binary" with "go test -c -o /tmp/path" and put it into a tmp dir
helperBinaryPath := tmpDir + "/helper1"
@ -58,7 +58,7 @@ func TestMonitorActivePids(t *testing.T) {
pid := helperCmd.Process.Pid
proc := NewProcess(pid, helperBinaryPath)
helperProcs = append(helperProcs, proc)
addToActivePidsCache(uint32(pid), proc)
addToActivePidsCache(uint64(pid), proc)
}
//sleep to make sure all processes started before we proceed
time.Sleep(time.Second * 1)
@ -66,7 +66,7 @@ func TestMonitorActivePids(t *testing.T) {
for i := 0; i < numberOfHelpers; i++ {
proc := helperProcs[i]
pid := proc.ID
foundProc := findProcessInActivePidsCache(uint32(pid))
foundProc := findProcessInActivePidsCache(uint64(pid))
if foundProc == nil {
t.Error("PID not found among active processes", pid)
}
@ -84,7 +84,7 @@ func TestMonitorActivePids(t *testing.T) {
time.Sleep(time.Second * 1)
//make sure only the alive process is in the cache
foundProc := findProcessInActivePidsCache(uint32(helperProcs[numberOfHelpers-1].ID))
foundProc := findProcessInActivePidsCache(uint64(helperProcs[numberOfHelpers-1].ID))
if foundProc == nil {
t.Error("last alive PID is not found among active processes", foundProc)
}

View file

@ -92,7 +92,7 @@ func FindProcess(pid int, interceptUnknown bool) *Process {
return NewProcess(0, "")
}
if proc := findProcessInActivePidsCache(uint32(pid)); proc != nil {
if proc := findProcessInActivePidsCache(uint64(pid)); proc != nil {
return proc
}
@ -110,7 +110,7 @@ func FindProcess(pid int, interceptUnknown bool) *Process {
proc.readEnv()
proc.cleanPath()
addToActivePidsCache(uint32(pid), proc)
addToActivePidsCache(uint64(pid), proc)
return proc
}
}
@ -128,7 +128,7 @@ func FindProcess(pid int, interceptUnknown bool) *Process {
proc.readEnv()
proc.cleanPath()
addToActivePidsCache(uint32(pid), proc)
addToActivePidsCache(uint64(pid), proc)
return proc
}
return nil