1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
package procmon
import (
"io/ioutil"
"strconv"
"strings"
"sync"
"time"
"github.com/evilsocket/opensnitch/daemon/core"
"github.com/evilsocket/opensnitch/daemon/log"
)
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 uint64
}
var (
activePids = make(map[uint64]value)
activePidsLock = sync.RWMutex{}
)
//MonitorActivePids checks that each process in activePids
//is still running and if not running (or another process with the same pid is running),
//removes the pid from activePids
func MonitorActivePids() {
for {
time.Sleep(time.Second)
activePidsLock.Lock()
for k, v := range activePids {
data, err := ioutil.ReadFile(core.ConcatStrings("/proc/", strconv.FormatUint(k, 10), "/stat"))
if err != nil {
//file does not exists, pid has quit
delete(activePids, k)
pidsCache.delete(int(k))
continue
}
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: %v", err)
delete(activePids, k)
pidsCache.delete(int(k))
continue
}
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.")
delete(activePids, k)
pidsCache.delete(int(k))
continue
}
}
activePidsLock.Unlock()
}
}
func findProcessInActivePidsCache(pid uint64) *Process {
activePidsLock.Lock()
defer activePidsLock.Unlock()
if value, ok := activePids[pid]; ok {
return value.Process
}
return nil
}
// AddToActivePidsCache adds the given pid to a list of known processes.
func AddToActivePidsCache(pid uint64, proc *Process) {
data, err := ioutil.ReadFile(core.ConcatStrings("/proc/", strconv.FormatUint(pid, 10), "/stat"))
if err != nil {
//most likely the process has quit by now
return
}
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: %v", err)
return
}
activePidsLock.Lock()
activePids[pid] = value{
Process: proc,
Starttime: uint64(startTime),
}
activePidsLock.Unlock()
}
|