From 44fdaa40f4e1d3eb7e2fd92ddec969bac59ad9f8 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 19 Jan 2025 18:44:45 +0000 Subject: [PATCH] tetragon: Add event_find_curr_probe function Signed-off-by: Jiri Olsa --- bpf/lib/common.h | 1 + bpf/lib/generic.h | 2 ++ bpf/process/bpf_process_event.h | 21 +++++++++++++++++++++ bpf/process/generic_calls.h | 8 ++++++-- pkg/api/processapi/processapi.go | 1 + pkg/eventcache/eventcache.go | 3 +++ pkg/grpc/tracing/tracing.go | 10 ++++++---- pkg/process/process.go | 20 ++++++++++++++++++++ 8 files changed, 60 insertions(+), 6 deletions(-) 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 dc7aff35c2d..660f8355dbc 100644 --- a/bpf/process/bpf_process_event.h +++ b/bpf/process/bpf_process_event.h @@ -316,4 +316,25 @@ init_execve_map_value(struct execve_map_value *curr, struct execve_map_value *pa */ set_in_init_tree(curr, parent); } + +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 0a1166548db..29fd1cb5ab4 100644 --- a/bpf/process/generic_calls.h +++ b/bpf/process/generic_calls.h @@ -571,8 +571,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..2038a9c8b56 100644 --- a/pkg/eventcache/eventcache.go +++ b/pkg/eventcache/eventcache.go @@ -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/tracing/tracing.go b/pkg/grpc/tracing/tracing.go index d5aef59730c..433d0e49361 100644 --- a/pkg/grpc/tracing/tracing.go +++ b/pkg/grpc/tracing/tracing.go @@ -11,6 +11,7 @@ import ( "golang.org/x/sys/unix" "github.com/cilium/tetragon/api/v1/tetragon" + "github.com/cilium/tetragon/pkg/api/processapi" "github.com/cilium/tetragon/pkg/api/tracingapi" api "github.com/cilium/tetragon/pkg/api/tracingapi" "github.com/cilium/tetragon/pkg/eventcache" @@ -283,7 +284,8 @@ 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) + unknown := event.Msg.Common.Flags&processapi.MSG_COMMON_FLAG_PROCESS_NOT_FOUND != 0 + proc, parent := process.GetParentProcessInternalUnknown(event.Msg.ProcessKey.Pid, event.Msg.ProcessKey.Ktime, unknown) if proc == nil { tetragonProcess = &tetragon.Process{ Pid: &wrapperspb.UInt32Value{Value: event.Msg.ProcessKey.Pid}, @@ -374,19 +376,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. diff --git a/pkg/process/process.go b/pkg/process/process.go index 45d18f96131..faed96f94c5 100644 --- a/pkg/process/process.go +++ b/pkg/process/process.go @@ -463,6 +463,26 @@ func GetPodInfo(containerID, bin, args string, nspid uint32) *tetragon.Pod { return getPodInfo(k8s, containerID, bin, args, nspid) } +var ( + unknownProcess = tetragon.Process{ + Binary: "unknown", + } + unknownInternal = ProcessInternal{ + process: &unknownProcess, + } +) + +func IsUnknown(proc *tetragon.Process) bool { + return proc == &unknownProcess +} + +func GetParentProcessInternalUnknown(pid uint32, ktime uint64, unknown bool) (*ProcessInternal, *ProcessInternal) { + if unknown { + return &unknownInternal, &unknownInternal + } + return GetParentProcessInternal(pid, ktime) +} + func GetParentProcessInternal(pid uint32, ktime uint64) (*ProcessInternal, *ProcessInternal) { var parent, process *ProcessInternal var err error