diff --git a/bpf/lib/common.h b/bpf/lib/common.h index d4712c78091..ad8a3355ae5 100644 --- a/bpf/lib/common.h +++ b/bpf/lib/common.h @@ -8,6 +8,7 @@ #define MSG_COMMON_FLAG_KERNEL_STACKTRACE BIT(1) #define MSG_COMMON_FLAG_USER_STACKTRACE BIT(2) #define MSG_COMMON_FLAG_IMA_HASH BIT(3) +#define MSG_COMMON_FLAG_PROCESS_NOT_FOUND BIT(4) /* Msg Layout */ struct msg_common { diff --git a/bpf/lib/generic.h b/bpf/lib/generic.h index bf785b11bdb..27a36dbfbdb 100644 --- a/bpf/lib/generic.h +++ b/bpf/lib/generic.h @@ -62,6 +62,8 @@ struct msg_generic_kprobe { bool post; // true if event needs to be posted } lsm; }; + struct execve_map_value curr; + struct heap_exe exe; }; FUNC_INLINE size_t generic_kprobe_common_size(void) diff --git a/bpf/process/bpf_process_event.h b/bpf/process/bpf_process_event.h index 5bbf8633506..4f7348d8e14 100644 --- a/bpf/process/bpf_process_event.h +++ b/bpf/process/bpf_process_event.h @@ -288,4 +288,25 @@ set_in_init_tree(struct execve_map_value *curr, struct execve_map_value *parent) DEBUG("%s: nspid=1", __func__); } } + +FUNC_INLINE struct execve_map_value* +event_find_curr_probe(struct msg_generic_kprobe *msg) +{ + struct task_struct *task = (struct task_struct *)get_current_task(); + struct execve_map_value *curr; + + curr = &msg->curr; + curr->key.pid = BPF_CORE_READ(task, tgid); + curr->key.ktime = ktime_get_ns(); + curr->nspid = get_task_pid_vnr_by_task(task); + + get_current_subj_caps(&curr->caps, task); + get_namespaces(&curr->ns, task); + set_in_init_tree(curr, NULL); + +#ifdef __LARGE_BPF_PROG + read_exe((struct task_struct *)get_current_task(), &msg->exe); +#endif + return curr; +} #endif diff --git a/bpf/process/generic_calls.h b/bpf/process/generic_calls.h index f1e5b46be3f..5ca08bae37b 100644 --- a/bpf/process/generic_calls.h +++ b/bpf/process/generic_calls.h @@ -583,8 +583,12 @@ FUNC_INLINE int generic_process_filter(void) return 0; enter = event_find_curr(&ppid, &walker); - if (!enter) - return PFILTER_CURR_NOT_FOUND; + if (!enter) { + enter = event_find_curr_probe(msg); + if (!enter) + return PFILTER_CURR_NOT_FOUND; + msg->common.flags |= MSG_COMMON_FLAG_PROCESS_NOT_FOUND; + } f = map_lookup_elem(&filter_map, &msg->idx); if (!f) diff --git a/pkg/api/processapi/processapi.go b/pkg/api/processapi/processapi.go index 4d35ef5d026..13cb611ee1a 100644 --- a/pkg/api/processapi/processapi.go +++ b/pkg/api/processapi/processapi.go @@ -44,6 +44,7 @@ const ( MSG_COMMON_FLAG_KERNEL_STACKTRACE = 0x2 MSG_COMMON_FLAG_USER_STACKTRACE = 0x4 MSG_COMMON_FLAG_IMA_HASH = 0x8 + MSG_COMMON_FLAG_PROCESS_NOT_FOUND = 0x16 BINARY_PATH_MAX_LEN = 256 MAX_ARG_LENGTH = 256 diff --git a/pkg/eventcache/eventcache.go b/pkg/eventcache/eventcache.go index 685dc91cf47..cf34df33221 100644 --- a/pkg/eventcache/eventcache.go +++ b/pkg/eventcache/eventcache.go @@ -54,7 +54,7 @@ var ( // this event was handled before an exec event so it wasn't able to populate // the process info yet. func HandleGenericInternal(ev notify.Event, pid uint32, tid *uint32, timestamp uint64) (*process.ProcessInternal, error) { - internal, parent := process.GetParentProcessInternal(pid, timestamp) + internal, parent := process.GetParentProcessInternal(pid, timestamp, 0) var err error if parent != nil { @@ -195,6 +195,9 @@ func (ec *Cache) Needed(proc *tetragon.Process) bool { if proc == nil { return true } + if process.IsUnknown(proc) { + return false + } if option.Config.EnableK8s { if proc.Docker != "" && proc.Pod == nil { return true diff --git a/pkg/grpc/exec/exec.go b/pkg/grpc/exec/exec.go index 8778c2430c5..88f0e041e38 100644 --- a/pkg/grpc/exec/exec.go +++ b/pkg/grpc/exec/exec.go @@ -334,7 +334,7 @@ func (msg *MsgCloneEventUnix) Cast(o interface{}) notify.Message { func GetProcessExit(event *MsgExitEventUnix) *tetragon.ProcessExit { var tetragonProcess, tetragonParent *tetragon.Process - proc, parent := process.GetParentProcessInternal(event.ProcessKey.Pid, event.ProcessKey.Ktime) + proc, parent := process.GetParentProcessInternal(event.ProcessKey.Pid, event.ProcessKey.Ktime, event.Common.Flags) if proc != nil { tetragonProcess = proc.UnsafeGetProcess() } else { @@ -423,7 +423,7 @@ func (msg *MsgExitEventUnix) Notify() bool { } func (msg *MsgExitEventUnix) RetryInternal(ev notify.Event, timestamp uint64) (*process.ProcessInternal, error) { - internal, parent := process.GetParentProcessInternal(msg.ProcessKey.Pid, timestamp) + internal, parent := process.GetParentProcessInternal(msg.ProcessKey.Pid, timestamp, msg.Common.Flags) var err error if parent != nil { @@ -489,7 +489,7 @@ func (msg *MsgProcessCleanupEventUnix) Notify() bool { } func (msg *MsgProcessCleanupEventUnix) RetryInternal(_ notify.Event, timestamp uint64) (*process.ProcessInternal, error) { - internal, parent := process.GetParentProcessInternal(msg.PID, timestamp) + internal, parent := process.GetParentProcessInternal(msg.PID, timestamp, 0) var err error if parent != nil { @@ -524,7 +524,7 @@ func (msg *MsgProcessCleanupEventUnix) Retry(_ *process.ProcessInternal, _ notif func (msg *MsgProcessCleanupEventUnix) HandleMessage() *tetragon.GetEventsResponse { msg.RefCntDone = [2]bool{false, false} - if process, parent := process.GetParentProcessInternal(msg.PID, msg.Ktime); process != nil && parent != nil { + if process, parent := process.GetParentProcessInternal(msg.PID, msg.Ktime, 0); process != nil && parent != nil { parent.RefDec("parent") process.RefDec("process") } else { diff --git a/pkg/grpc/tracing/tracing.go b/pkg/grpc/tracing/tracing.go index d5aef59730c..e7e03dc4a88 100644 --- a/pkg/grpc/tracing/tracing.go +++ b/pkg/grpc/tracing/tracing.go @@ -283,7 +283,7 @@ func GetProcessKprobe(event *MsgGenericKprobeUnix) *tetragon.ProcessKprobe { var tetragonArgs []*tetragon.KprobeArgument var tetragonReturnArg *tetragon.KprobeArgument - proc, parent := process.GetParentProcessInternal(event.Msg.ProcessKey.Pid, event.Msg.ProcessKey.Ktime) + proc, parent := process.GetParentProcessInternal(event.Msg.ProcessKey.Pid, event.Msg.ProcessKey.Ktime, event.Msg.Common.Flags) if proc == nil { tetragonProcess = &tetragon.Process{ Pid: &wrapperspb.UInt32Value{Value: event.Msg.ProcessKey.Pid}, @@ -374,19 +374,19 @@ func GetProcessKprobe(event *MsgGenericKprobeUnix) *tetragon.ProcessKprobe { Tags: event.Tags, } - if tetragonProcess.Pid == nil { + if !process.IsUnknown(tetragonProcess) && tetragonProcess.Pid == nil { eventcache.CacheErrors(eventcache.NilProcessPid, notify.EventType(tetragonEvent)).Inc() return nil } if ec := eventcache.Get(); ec != nil && (ec.Needed(tetragonProcess) || - (tetragonProcess.Pid.Value > 1 && ec.Needed(tetragonParent))) { + (tetragonProcess.Pid != nil && tetragonProcess.Pid.Value > 1 && ec.Needed(tetragonParent))) { ec.Add(nil, tetragonEvent, event.Msg.Common.Ktime, event.Msg.ProcessKey.Ktime, event) return nil } - if proc != nil { + if !process.IsUnknown(tetragonProcess) && proc != nil { // At kprobes we report the per thread fields, so take a copy // of the thread leader from the cache then update the corresponding // per thread fields. @@ -439,7 +439,7 @@ func familyString(family uint16) string { func (msg *MsgGenericTracepointUnix) HandleMessage() *tetragon.GetEventsResponse { var tetragonParent, tetragonProcess *tetragon.Process - proc, parent := process.GetParentProcessInternal(msg.Msg.ProcessKey.Pid, msg.Msg.ProcessKey.Ktime) + proc, parent := process.GetParentProcessInternal(msg.Msg.ProcessKey.Pid, msg.Msg.ProcessKey.Ktime, msg.Msg.Common.Flags) if proc == nil { tetragonProcess = &tetragon.Process{ Pid: &wrapperspb.UInt32Value{Value: msg.Msg.ProcessKey.Pid}, @@ -655,7 +655,7 @@ func (event *ProcessLoaderNotify) SetParent(*tetragon.Process) { func GetProcessLoader(msg *MsgProcessLoaderUnix) *tetragon.ProcessLoader { var tetragonProcess *tetragon.Process - process, _ := process.GetParentProcessInternal(msg.Msg.ProcessKey.Pid, msg.Msg.ProcessKey.Ktime) + process, _ := process.GetParentProcessInternal(msg.Msg.ProcessKey.Pid, msg.Msg.ProcessKey.Ktime, msg.Msg.Common.Flags) if process == nil { tetragonProcess = &tetragon.Process{ Pid: &wrapperspb.UInt32Value{Value: msg.Msg.ProcessKey.Pid}, @@ -750,7 +750,7 @@ func GetProcessUprobe(event *MsgGenericUprobeUnix) *tetragon.ProcessUprobe { var tetragonParent, tetragonProcess *tetragon.Process var tetragonArgs []*tetragon.KprobeArgument - proc, parent := process.GetParentProcessInternal(event.Msg.ProcessKey.Pid, event.Msg.ProcessKey.Ktime) + proc, parent := process.GetParentProcessInternal(event.Msg.ProcessKey.Pid, event.Msg.ProcessKey.Ktime, event.Msg.Common.Flags) if proc == nil { tetragonProcess = &tetragon.Process{ Pid: &wrapperspb.UInt32Value{Value: event.Msg.ProcessKey.Pid}, @@ -879,7 +879,7 @@ func GetProcessLsm(event *MsgGenericLsmUnix) *tetragon.ProcessLsm { var tetragonParent, tetragonProcess *tetragon.Process var tetragonArgs []*tetragon.KprobeArgument - proc, parent := process.GetParentProcessInternal(event.Msg.ProcessKey.Pid, event.Msg.ProcessKey.Ktime) + proc, parent := process.GetParentProcessInternal(event.Msg.ProcessKey.Pid, event.Msg.ProcessKey.Ktime, event.Msg.Common.Flags) if proc == nil { tetragonProcess = &tetragon.Process{ Pid: &wrapperspb.UInt32Value{Value: event.Msg.ProcessKey.Pid}, diff --git a/pkg/process/process.go b/pkg/process/process.go index 0740f6ae78a..454bcdedbf4 100644 --- a/pkg/process/process.go +++ b/pkg/process/process.go @@ -18,6 +18,7 @@ import ( "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/api" + "github.com/cilium/tetragon/pkg/api/processapi" tetragonAPI "github.com/cilium/tetragon/pkg/api/processapi" "github.com/cilium/tetragon/pkg/ktime" "github.com/cilium/tetragon/pkg/logger" @@ -463,10 +464,27 @@ func GetPodInfo(containerID, bin, args string, nspid uint32) *tetragon.Pod { return getPodInfo(k8s, containerID, bin, args, nspid) } -func GetParentProcessInternal(pid uint32, ktime uint64) (*ProcessInternal, *ProcessInternal) { +var ( + unknownProcess = tetragon.Process{ + Binary: "unknown", + } + unknownInternal = ProcessInternal{ + process: &unknownProcess, + } +) + +func IsUnknown(proc *tetragon.Process) bool { + return proc == &unknownProcess +} + +func GetParentProcessInternal(pid uint32, ktime uint64, flags uint8) (*ProcessInternal, *ProcessInternal) { var parent, process *ProcessInternal var err error + if flags&processapi.MSG_COMMON_FLAG_PROCESS_NOT_FOUND != 0 { + return &unknownInternal, &unknownInternal + } + processID := GetProcessID(pid, ktime) if process, err = procCache.get(processID); err != nil {