Skip to content

Commit

Permalink
fix(monitor): Missing Source in Telemetry
Browse files Browse the repository at this point in the history
We did not have fallback logic to read from procfs in case of operation File/Network

Enabled the fallback logic for file/network telemetry

Signed-off-by: daemon1024 <[email protected]>
  • Loading branch information
daemon1024 committed Jan 22, 2024
1 parent 70289a0 commit c5e150e
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 32 deletions.
2 changes: 1 addition & 1 deletion KubeArmor/enforcer/bpflsm/enforcer.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ func (be *BPFEnforcer) TraceEvents() {
HostPID: event.HostPID,
HostPPID: event.HostPPID,
},
})
}, false)

switch event.EventID {

Expand Down
30 changes: 13 additions & 17 deletions KubeArmor/monitor/logUpdate.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (mon *SystemMonitor) UpdateContainerInfoByContainerID(log tp.Log) tp.Log {
}

// BuildLogBase Function
func (mon *SystemMonitor) BuildLogBase(eventID int32, msg ContextCombined) tp.Log {
func (mon *SystemMonitor) BuildLogBase(eventID int32, msg ContextCombined, readlink bool) tp.Log {
log := tp.Log{}

timestamp, updatedTime := kl.GetDateTimeNow()
Expand Down Expand Up @@ -78,41 +78,37 @@ func (mon *SystemMonitor) BuildLogBase(eventID int32, msg ContextCombined) tp.Lo
log.PID = int32(msg.ContextSys.PID)
log.UID = int32(msg.ContextSys.UID)

log.ProcessName = mon.GetExecPath(msg.ContainerID, msg.ContextSys, readlink)
log.ParentProcessName = mon.GetParentExecPath(msg.ContainerID, msg.ContextSys, readlink)

if msg.ContextSys.EventID == SysExecve || msg.ContextSys.EventID == SysExecveAt {
log.Source = mon.GetParentExecPath(msg.ContainerID, msg.ContextSys.HostPID, false)
log.Source = mon.GetParentExecPath(msg.ContainerID, msg.ContextSys, readlink)
} else {
log.Source = mon.GetCommand(msg.ContainerID, msg.ContextSys.HostPID, false)
log.Source = mon.GetCommand(msg.ContainerID, msg.ContextSys, readlink)
}

log.Cwd = strings.TrimRight(string(msg.ContextSys.Cwd[:]), "\x00") + "/"
log.OID = int32(msg.ContextSys.OID)

log.ParentProcessName = mon.GetExecPath(msg.ContainerID, msg.ContextSys.HostPPID, false)
log.ProcessName = mon.GetExecPath(msg.ContainerID, msg.ContextSys.HostPID, false)

return log
}

// UpdateLogBase Function (SYS_EXECVE, SYS_EXECVEAT)
func (mon *SystemMonitor) UpdateLogBase(eventID int32, log tp.Log) tp.Log {
func (mon *SystemMonitor) UpdateLogBase(ctx SyscallContext, log tp.Log) tp.Log {

// update the process paths, since we would have received actual exec paths from bprm hook
// in case bprm hook has not populated the map with full path, we will fallback to reading from procfs
// else we will send out relative path

parentProcessName := mon.GetParentExecPath(log.ContainerID, uint32(log.HostPID), true)
if parentProcessName != "" {
log.ParentProcessName = parentProcessName
}

processName := mon.GetExecPath(log.ContainerID, uint32(log.HostPID), true)
processName := mon.GetExecPath(log.ContainerID, ctx, true)
if processName != "" {
log.ProcessName = processName
}

source := mon.GetExecPath(log.ContainerID, uint32(log.HostPPID), true)
if source != "" {
log.Source = source
parentProcessName := mon.GetParentExecPath(log.ContainerID, ctx, true)
if parentProcessName != "" {
log.ParentProcessName = parentProcessName
log.Source = parentProcessName
}

return log
Expand All @@ -131,7 +127,7 @@ func (mon *SystemMonitor) UpdateLogs() {
}

// generate a log
log := mon.BuildLogBase(msg.ContextSys.EventID, msg)
log := mon.BuildLogBase(msg.ContextSys.EventID, msg, true)

switch msg.ContextSys.EventID {
case SysOpen:
Expand Down
48 changes: 38 additions & 10 deletions KubeArmor/monitor/processTree.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func (mon *SystemMonitor) BuildPidNode(containerID string, ctx SyscallContext, e
node.PID = ctx.PID
node.UID = ctx.UID

node.ParentExecPath = mon.GetExecPath(containerID, ctx.HostPPID, false)
node.ParentExecPath = mon.GetParentExecPath(containerID, ctx, false)
node.ExecPath = execPath

node.Source = execPath
Expand Down Expand Up @@ -204,7 +204,7 @@ func (mon *SystemMonitor) UpdateExecPath(containerID string, hostPid uint32, exe
}

// GetParentExecPath Function
func (mon *SystemMonitor) GetParentExecPath(containerID string, hostPid uint32, readlink bool) string {
func (mon *SystemMonitor) GetParentExecPath(containerID string, ctx SyscallContext, readlink bool) string {
ActiveHostPidMap := *(mon.ActiveHostPidMap)
ActivePidMapLock := *(mon.ActivePidMapLock)

Expand All @@ -214,17 +214,35 @@ func (mon *SystemMonitor) GetParentExecPath(containerID string, hostPid uint32,
path := ""

if pidMap, ok := ActiveHostPidMap[containerID]; ok {
if node, ok := pidMap[hostPid]; ok {
if node, ok := pidMap[ctx.HostPID]; ok {
path = node.ParentExecPath
if path != "/" && strings.HasPrefix(path, "/") {
return path
}
}
// check if parent pid node exists
if node, ok := pidMap[ctx.HostPPID]; ok {
path = node.ExecPath
if path != "/" && strings.HasPrefix(path, "/") {
return path
}
}
}

if readlink {
// just in case that it couldn't still get the full path
if data, err := os.Readlink("/proc/" + strconv.FormatUint(uint64(hostPid), 10) + "/exe"); err == nil && data != "" && data != "/" {
if data, err := os.Readlink("/proc/" + strconv.FormatUint(uint64(ctx.HostPPID), 10) + "/exe"); err == nil && data != "" && data != "/" {
// // Store it in the ActiveHostPidMap so we don't need to read procfs again
// // We don't call BuildPidNode Here cause that will put this into a cyclic function call loop
// if pidMap, ok := ActiveHostPidMap[containerID]; ok {
// if node, ok := pidMap[ctx.HostPPID]; ok {
// node.ExecPath = data
// pidMap[ctx.HostPPID] = node
// } else if node, ok := pidMap[ctx.HostPID]; ok {
// node.ExecPath = data
// pidMap[ctx.HostPID] = node
// }
// }
return data
} else if err != nil {
mon.Logger.Debugf("Could not read path from procfs due to %s", err.Error())
Expand All @@ -238,7 +256,7 @@ func (mon *SystemMonitor) GetParentExecPath(containerID string, hostPid uint32,
}

// GetExecPath Function
func (mon *SystemMonitor) GetExecPath(containerID string, hostPid uint32, readlink bool) string {
func (mon *SystemMonitor) GetExecPath(containerID string, ctx SyscallContext, readlink bool) string {
ActiveHostPidMap := *(mon.ActiveHostPidMap)
ActivePidMapLock := *(mon.ActivePidMapLock)

Expand All @@ -248,7 +266,7 @@ func (mon *SystemMonitor) GetExecPath(containerID string, hostPid uint32, readli
path := ""

if pidMap, ok := ActiveHostPidMap[containerID]; ok {
if node, ok := pidMap[hostPid]; ok {
if node, ok := pidMap[ctx.HostPID]; ok {
path = node.ExecPath
if path != "/" && strings.HasPrefix(path, "/") {
return path
Expand All @@ -258,7 +276,17 @@ func (mon *SystemMonitor) GetExecPath(containerID string, hostPid uint32, readli

if readlink {
// just in case that it couldn't still get the full path
if data, err := os.Readlink("/proc/" + strconv.FormatUint(uint64(hostPid), 10) + "/exe"); err == nil && data != "" && data != "/" {
if data, err := os.Readlink("/proc/" + strconv.FormatUint(uint64(ctx.HostPID), 10) + "/exe"); err == nil && data != "" && data != "/" {
// // Store it in the ActiveHostPidMap so we don't need to read procfs again
// if pidMap, ok := ActiveHostPidMap[containerID]; ok {
// if node, ok := pidMap[ctx.HostPID]; ok {
// node.ExecPath = data
// pidMap[ctx.HostPID] = node
// } else {
// newPidNode := mon.BuildPidNode(containerID, ctx, data, []string{})
// pidMap[ctx.HostPID] = newPidNode
// }
// }
return data
} else if err != nil {
mon.Logger.Debugf("Could not read path from procfs due to %s", err.Error())
Expand All @@ -272,15 +300,15 @@ func (mon *SystemMonitor) GetExecPath(containerID string, hostPid uint32, readli
}

// GetCommand Function
func (mon *SystemMonitor) GetCommand(containerID string, hostPid uint32, readlink bool) string {
func (mon *SystemMonitor) GetCommand(containerID string, ctx SyscallContext, readlink bool) string {
ActiveHostPidMap := *(mon.ActiveHostPidMap)
ActivePidMapLock := *(mon.ActivePidMapLock)

ActivePidMapLock.Lock()
defer ActivePidMapLock.Unlock()

if pidMap, ok := ActiveHostPidMap[containerID]; ok {
if node, ok := pidMap[hostPid]; ok {
if node, ok := pidMap[ctx.HostPID]; ok {
if node.Args != "" {
return node.Source + " " + node.Args
}
Expand All @@ -290,7 +318,7 @@ func (mon *SystemMonitor) GetCommand(containerID string, hostPid uint32, readlin

if readlink {
// just in case that it couldn't still get the full path
if data, err := os.Readlink("/proc/" + strconv.FormatUint(uint64(hostPid), 10) + "/exe"); err == nil && data != "" && data != "/" {
if data, err := os.Readlink("/proc/" + strconv.FormatUint(uint64(ctx.HostPID), 10) + "/exe"); err == nil && data != "" && data != "/" {
return data
} else if err != nil {
mon.Logger.Debugf("Could not read path from procfs due to %s", err.Error())
Expand Down
8 changes: 4 additions & 4 deletions KubeArmor/monitor/systemMonitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ func (mon *SystemMonitor) TraceSyscall() {
mon.AddActivePid(containerID, pidNode)

// generate a log with the base information
log := mon.BuildLogBase(ctx.EventID, ContextCombined{ContainerID: containerID, ContextSys: ctx})
log := mon.BuildLogBase(ctx.EventID, ContextCombined{ContainerID: containerID, ContextSys: ctx}, false)

// add arguments
log.Resource = execPath
Expand All @@ -789,7 +789,7 @@ func (mon *SystemMonitor) TraceSyscall() {
mon.execLogMapLock.Unlock()

// update the log again
log = mon.UpdateLogBase(ctx.EventID, log)
log = mon.UpdateLogBase(ctx, log)

// get error message
if ctx.Retval < 0 {
Expand Down Expand Up @@ -817,7 +817,7 @@ func (mon *SystemMonitor) TraceSyscall() {
mon.AddActivePid(containerID, pidNode)

// generate a log with the base information
log := mon.BuildLogBase(ctx.EventID, ContextCombined{ContainerID: containerID, ContextSys: ctx})
log := mon.BuildLogBase(ctx.EventID, ContextCombined{ContainerID: containerID, ContextSys: ctx}, false)

fd := ""
procExecFlag := ""
Expand Down Expand Up @@ -861,7 +861,7 @@ func (mon *SystemMonitor) TraceSyscall() {
mon.execLogMapLock.Unlock()

// update the log again
log = mon.UpdateLogBase(ctx.EventID, log)
log = mon.UpdateLogBase(ctx, log)

// get error message
if ctx.Retval < 0 {
Expand Down

0 comments on commit c5e150e

Please sign in to comment.