Improve process creation and cleaning

This commit is contained in:
Daniel 2019-05-06 10:51:19 +02:00
parent 0fd44c8011
commit 4f275a8029
6 changed files with 88 additions and 17 deletions

View file

@ -90,30 +90,40 @@ func (p *Process) Delete() {
// CleanProcessStorage cleans the storage from old processes. // CleanProcessStorage cleans the storage from old processes.
func CleanProcessStorage(thresholdDuration time.Duration) { func CleanProcessStorage(thresholdDuration time.Duration) {
processesLock.Lock() processesCopy := All()
defer processesLock.Unlock()
threshold := time.Now().Add(-thresholdDuration).Unix() threshold := time.Now().Add(-thresholdDuration).Unix()
delete := false
// clean primary processes // clean primary processes
for _, p := range processes { for _, p := range processesCopy {
p.Lock() p.Lock()
if !p.Virtual && p.LastCommEstablished < threshold && p.CommCount == 0 { if !p.Virtual && p.LastCommEstablished < threshold && p.CommCount == 0 {
go p.Delete() delete = true
} }
p.Unlock() p.Unlock()
if delete {
p.Delete()
delete = false
}
} }
// clean virtual processes // clean virtual processes
for _, p := range processes { for _, p := range processesCopy {
p.Lock() p.Lock()
if p.Virtual { if p.Virtual {
_, parentIsAlive := processes[p.ParentPid] _, parentIsAlive := processes[p.ParentPid]
if !parentIsAlive { if !parentIsAlive {
go p.Delete() delete = true
} }
} }
p.Unlock() p.Unlock()
if delete {
p.Delete()
delete = false
}
} }
} }

View file

@ -199,7 +199,7 @@ func getListeningSocket(localIP net.IP, localPort uint16, protocol uint8) (uid,
return data[0], data[1], true return data[0], data[1], true
} }
return 0, 0, false return -1, -1, false
} }
func procDelimiter(c rune) bool { func procDelimiter(c rune) bool {

View file

@ -91,12 +91,22 @@ func (p *Process) RemoveCommunication() {
// GetOrFindPrimaryProcess returns the highest process in the tree that matches the given PID. // GetOrFindPrimaryProcess returns the highest process in the tree that matches the given PID.
func GetOrFindPrimaryProcess(pid int) (*Process, error) { func GetOrFindPrimaryProcess(pid int) (*Process, error) {
if pid == -1 {
return UnknownProcess, nil
}
if pid == 0 {
return OSProcess, nil
}
process, err := loadProcess(pid) process, err := loadProcess(pid)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for { for {
if process.ParentPid == 0 {
return OSProcess, nil
}
parentProcess, err := loadProcess(process.ParentPid) parentProcess, err := loadProcess(process.ParentPid)
if err != nil { if err != nil {
log.Tracef("process: could not get parent (%d): %s", process.Pid, err) log.Tracef("process: could not get parent (%d): %s", process.Pid, err)
@ -126,6 +136,13 @@ func GetOrFindPrimaryProcess(pid int) (*Process, error) {
// GetOrFindProcess returns the process for the given PID. // GetOrFindProcess returns the process for the given PID.
func GetOrFindProcess(pid int) (*Process, error) { func GetOrFindProcess(pid int) (*Process, error) {
if pid == -1 {
return UnknownProcess, nil
}
if pid == 0 {
return OSProcess, nil
}
p, err := loadProcess(pid) p, err := loadProcess(pid)
if err != nil { if err != nil {
return nil, err return nil, err
@ -137,6 +154,13 @@ func GetOrFindProcess(pid int) (*Process, error) {
} }
func loadProcess(pid int) (*Process, error) { func loadProcess(pid int) (*Process, error) {
if pid == -1 {
return UnknownProcess, nil
}
if pid == 0 {
return OSProcess, nil
}
process, ok := GetProcessFromStorage(pid) process, ok := GetProcessFromStorage(pid)
if ok { if ok {
return process, nil return process, nil

View file

@ -19,3 +19,8 @@ func (m *Process) IsSystem() bool {
func (m *Process) IsKernel() bool { func (m *Process) IsKernel() bool {
return m.Pid == 0 return m.Pid == 0
} }
// specialOSInit does special OS specific Process initialization.
func (m *Process) specialOSInit() {
}

View file

@ -1,24 +1,46 @@
package process package process
import "strings" import (
"fmt"
"strings"
"github.com/Safing/portbase/log"
"github.com/Safing/portbase/utils/osdetail"
)
// IsUser returns whether the process is run by a normal user. // IsUser returns whether the process is run by a normal user.
func (m *Process) IsUser() bool { func (p *Process) IsUser() bool {
return m.Pid != 4 && // Kernel return p.Pid != 4 && // Kernel
!strings.HasPrefix(m.UserName, "NT") // NT-Authority (localized!) !strings.HasPrefix(p.UserName, "NT") // NT-Authority (localized!)
} }
// IsAdmin returns whether the process is run by an admin user. // IsAdmin returns whether the process is run by an admin user.
func (m *Process) IsAdmin() bool { func (p *Process) IsAdmin() bool {
return strings.HasPrefix(m.UserName, "NT") // NT-Authority (localized!) return strings.HasPrefix(p.UserName, "NT") // NT-Authority (localized!)
} }
// IsSystem returns whether the process is run by the operating system. // IsSystem returns whether the process is run by the operating system.
func (m *Process) IsSystem() bool { func (p *Process) IsSystem() bool {
return m.Pid == 4 return p.Pid == 4
} }
// IsKernel returns whether the process is the Kernel. // IsKernel returns whether the process is the Kernel.
func (m *Process) IsKernel() bool { func (p *Process) IsKernel() bool {
return m.Pid == 4 return p.Pid == 4
}
// specialOSInit does special OS specific Process initialization.
func (p *Process) specialOSInit() {
// add svchost.exe service names to Name
if p.ExecName == "svchost.exe" {
svcNames, err := osdetail.GetServiceNames(int32(p.Pid))
switch err {
case nil:
p.Name += fmt.Sprintf(" (%s)", svcNames)
case osdetail.ErrServiceNotFound:
log.Tracef("process: failed to get service name for svchost.exe (pid %d): %s", p.Pid, err)
default:
log.Warningf("process: failed to get service name for svchost.exe (pid %d): %s", p.Pid, err)
}
}
} }

View file

@ -9,8 +9,18 @@ var (
ParentPid: -1, ParentPid: -1,
Name: "Unknown Processes", Name: "Unknown Processes",
} }
// OSProcess is used to represent the Kernel.
OSProcess = &Process{
UserID: 0,
UserName: "Kernel",
Pid: 0,
ParentPid: 0,
Name: "Operating System",
}
) )
func init() { func init() {
UnknownProcess.Save() UnknownProcess.Save()
OSProcess.Save()
} }