From 9e18e2c723585c9a9bc710f889ad890e7cfcc3f3 Mon Sep 17 00:00:00 2001 From: t0x01 Date: Wed, 16 Apr 2025 16:32:23 +0400 Subject: [PATCH 1/4] tetragon: Deprecate enable-process-ancestors boolean flags Deprecate tetragon enable-process-ancestors boolean flags added in PR 2938 (e.g., see fd57a14) and introduce a new '--enable-ancestors' flag to replace them for better UX. Aforementioned flags are now marked as deprecated, but still usable. Signed-off-by: t0x01 --- pkg/eventcache/eventcache.go | 18 +----- pkg/filters/binary_regex.go | 2 +- pkg/filters/filters.go | 32 +--------- pkg/filters/filters_test.go | 2 +- pkg/grpc/exec/exec.go | 36 +++++------ pkg/grpc/exec/exec_test_helper.go | 4 +- pkg/grpc/tracing/tracing.go | 24 ++++---- pkg/option/ancestors_event_filter.go | 74 +++++++++++++++++++++++ pkg/option/ancestors_event_filter_test.go | 52 ++++++++++++++++ pkg/option/config.go | 7 +-- pkg/option/flags.go | 43 +++++++++---- 11 files changed, 197 insertions(+), 97 deletions(-) create mode 100644 pkg/option/ancestors_event_filter.go create mode 100644 pkg/option/ancestors_event_filter_test.go diff --git a/pkg/eventcache/eventcache.go b/pkg/eventcache/eventcache.go index 6baa4f9b43f..bfbf323ca45 100644 --- a/pkg/eventcache/eventcache.go +++ b/pkg/eventcache/eventcache.go @@ -51,21 +51,6 @@ var ( ErrFailedToGetAncestorsInfo = errors.New("failed to get ancestors info from event cache") ) -func enabledAncestors(ev notify.Event) bool { - switch ev.(type) { - case *tetragon.ProcessKprobe: - return option.Config.EnableProcessKprobeAncestors - case *tetragon.ProcessTracepoint: - return option.Config.EnableProcessTracepointAncestors - case *tetragon.ProcessUprobe: - return option.Config.EnableProcessUprobeAncestors - case *tetragon.ProcessLsm: - return option.Config.EnableProcessLsmAncestors - default: - return false - } -} - // Generic internal lookup happens when events are received out of order and // this event was handled before an exec event so it wasn't able to populate // the process info yet. @@ -73,7 +58,8 @@ func HandleGenericInternal(ev notify.Event, pid uint32, tid *uint32, timestamp u internal, parent := process.GetParentProcessInternal(pid, timestamp) var err error - if enabledAncestors(ev) && internal.NeededAncestors() { + eventType := notify.EventType(ev) + if option.Config.EnableAncestors[option.AncestorsEventTypeMap[eventType]] && internal.NeededAncestors() { // We do not need to try to recollect all ancestors starting from the immediate parent here, // if we already collected some of them in previous attempts. So, if we already have a number // of ancestors collected, we just need to try to resume the collection process from the last diff --git a/pkg/filters/binary_regex.go b/pkg/filters/binary_regex.go index 5d2c4ee87d0..13be5753797 100644 --- a/pkg/filters/binary_regex.go +++ b/pkg/filters/binary_regex.go @@ -38,7 +38,7 @@ func filterByBinaryRegex(binaryPatterns []string, level int) (hubbleFilters.Filt case ancestorBinary: processes = GetAncestors(ev) } - if processes == nil || processes[0] == nil { + if len(processes) == 0 || processes[0] == nil { return false } for _, process := range processes { diff --git a/pkg/filters/filters.go b/pkg/filters/filters.go index 0bfc12db595..52cf7cd66b2 100644 --- a/pkg/filters/filters.go +++ b/pkg/filters/filters.go @@ -161,39 +161,13 @@ func GetPolicyName(event *v1.Event) string { } } -var AncestorsEventSet = []tetragon.EventType{ - tetragon.EventType_PROCESS_EXEC, - tetragon.EventType_PROCESS_EXIT, - tetragon.EventType_PROCESS_KPROBE, - tetragon.EventType_PROCESS_TRACEPOINT, - tetragon.EventType_PROCESS_UPROBE, - tetragon.EventType_PROCESS_LSM, -} - -func enabledAncestors(eventType tetragon.EventType) bool { - switch eventType { - case tetragon.EventType_PROCESS_EXEC, tetragon.EventType_PROCESS_EXIT: - return option.Config.EnableProcessAncestors - case tetragon.EventType_PROCESS_KPROBE: - return option.Config.EnableProcessKprobeAncestors - case tetragon.EventType_PROCESS_TRACEPOINT: - return option.Config.EnableProcessTracepointAncestors - case tetragon.EventType_PROCESS_UPROBE: - return option.Config.EnableProcessUprobeAncestors - case tetragon.EventType_PROCESS_LSM: - return option.Config.EnableProcessLsmAncestors - default: - return false - } -} - func CheckAncestorsEnabled(types []tetragon.EventType) error { - if types == nil { - types = AncestorsEventSet + if len(types) == 0 { + types = option.GetAncestorsEventTypes() } for _, eventType := range types { - if !enabledAncestors(eventType) { + if !option.Config.EnableAncestors[option.AncestorsEventTypeMap[eventType]] { return fmt.Errorf("ancestors are not enabled for %s event type, cannot configure ancestor filter", eventType) } } diff --git a/pkg/filters/filters_test.go b/pkg/filters/filters_test.go index a8542fee575..340a708b41a 100644 --- a/pkg/filters/filters_test.go +++ b/pkg/filters/filters_test.go @@ -20,7 +20,7 @@ import ( func TestMain(m *testing.M) { // Needed for cap filters option.Config.EnableProcessCred = true - option.Config.EnableProcessAncestors = true + option.Config.EnableAncestors = option.AncestorsEventFilter{"base": true} code := m.Run() os.Exit(code) diff --git a/pkg/grpc/exec/exec.go b/pkg/grpc/exec/exec.go index 7830de45427..af824e36969 100644 --- a/pkg/grpc/exec/exec.go +++ b/pkg/grpc/exec/exec.go @@ -55,8 +55,8 @@ func GetProcessExec(event *MsgExecveEventUnix, useCache bool) *tetragon.ProcessE tetragonParent = parent.UnsafeGetProcess() } - // Set the ancestors only if --enable-process-ancestors flag is set. - if option.Config.EnableProcessAncestors && proc.NeededAncestors() { + // Set the ancestors only if --enable-ancestors flag includes 'base'. + if option.Config.EnableAncestors["base"] && proc.NeededAncestors() { // We don't care about an error here, because later we call ec.NeededAncestors, // that will determine if we were successful in collecting all ancestors and, // if we were not, the event will be added to the event cache for reprocessing. @@ -89,13 +89,13 @@ func GetProcessExec(event *MsgExecveEventUnix, useCache bool) *tetragon.ProcessE if ec := eventcache.Get(); ec != nil && (ec.Needed(tetragonProcess) || (tetragonProcess.Pid.Value > 1 && ec.Needed(tetragonParent)) || - (option.Config.EnableProcessAncestors && ec.NeededAncestors(parent, ancestors))) { + (option.Config.EnableAncestors["base"] && ec.NeededAncestors(parent, ancestors))) { ec.Add(proc, tetragonEvent, event.Unix.Msg.Common.Ktime, event.Unix.Process.Ktime, event) return nil } } - if option.Config.EnableProcessAncestors { + if option.Config.EnableAncestors["base"] { for _, ancestor := range ancestors { ancestor.RefInc("ancestor") } @@ -239,7 +239,7 @@ func (msg *MsgExecveEventUnix) Retry(internal *process.ProcessInternal, ev notif // ancestors of the given process, including the immediate parent. So in order for us // to collect ancestors beyond immediate parent, we need to pass immediate parent to // GetAncestorProcessesInternal. - if option.Config.EnableProcessAncestors && internal.NeededAncestors() && !msg.RefCntDone[AncestorsRefCnt] { + if option.Config.EnableAncestors["base"] && internal.NeededAncestors() && !msg.RefCntDone[AncestorsRefCnt] { if ancestors, err := process.GetAncestorProcessesInternal(tetragonProcess.ParentExecId); err == nil { var tetragonAncestors []*tetragon.Process for _, ancestor := range ancestors { @@ -354,7 +354,7 @@ func (msg *MsgCloneEventUnix) Retry(internal *process.ProcessInternal, _ notify. internal.AddPodInfo(podInfo) } - if option.Config.EnableProcessAncestors && internal.NeededAncestors() { + if option.Config.EnableAncestors["base"] && internal.NeededAncestors() { if ancestors, err := process.GetAncestorProcessesInternal(tetragonProcess.ParentExecId); err == nil { for _, ancestor := range ancestors { ancestor.RefInc("ancestor") @@ -372,7 +372,7 @@ func (msg *MsgCloneEventUnix) HandleMessage() *tetragon.GetEventsResponse { var ancestors []*process.ProcessInternal proc, _ := process.AddCloneEvent(&msg.MsgCloneEvent) - if option.Config.EnableProcessAncestors && proc.NeededAncestors() { + if option.Config.EnableAncestors["base"] && proc.NeededAncestors() { ancestors, _ = process.GetAncestorProcessesInternal(proc.UnsafeGetProcess().ParentExecId) } @@ -386,14 +386,14 @@ func (msg *MsgCloneEventUnix) HandleMessage() *tetragon.GetEventsResponse { parent, _ := process.Get(proc.UnsafeGetProcess().ParentExecId) if ec.Needed(proc.UnsafeGetProcess()) || - option.Config.EnableProcessAncestors && ec.NeededAncestors(parent, ancestors) { + option.Config.EnableAncestors["base"] && ec.NeededAncestors(parent, ancestors) { // adding to the cache due to missing pod info or ancestors ec.Add(proc, nil, msg.Common.Ktime, msg.Ktime, msg) return nil } } - if option.Config.EnableProcessAncestors { + if option.Config.EnableAncestors["base"] { for _, ancestor := range ancestors { ancestor.RefInc("ancestor") } @@ -425,8 +425,8 @@ func GetProcessExit(event *MsgExitEventUnix) *tetragon.ProcessExit { tetragonParent = parent.UnsafeGetProcess() } - // Set the ancestors only if --enable-process-ancestors flag is set. - if option.Config.EnableProcessAncestors && proc.NeededAncestors() { + // Set the ancestors only if --enable-ancestors flag includes 'base'. + if option.Config.EnableAncestors["base"] && proc.NeededAncestors() { // We don't care about an error here, because later we call ec.NeededAncestors, // that will determine if we were successful in collecting all ancestors and, // if we were not, the event will be added to the event cache for reprocessing. @@ -492,12 +492,12 @@ func GetProcessExit(event *MsgExitEventUnix) *tetragon.ProcessExit { if ec := eventcache.Get(); ec != nil && (ec.Needed(tetragonProcess) || (tetragonProcess.Pid.Value > 1 && ec.Needed(tetragonParent)) || - (option.Config.EnableProcessAncestors && ec.NeededAncestors(parent, ancestors))) { + (option.Config.EnableAncestors["base"] && ec.NeededAncestors(parent, ancestors))) { ec.Add(nil, tetragonEvent, event.Common.Ktime, event.ProcessKey.Ktime, event) return nil } - if option.Config.EnableProcessAncestors { + if option.Config.EnableAncestors["base"] { for _, ancestor := range ancestors { ancestor.RefDec("ancestor") } @@ -524,7 +524,7 @@ func (msg *MsgExitEventUnix) RetryInternal(ev notify.Event, timestamp uint64) (* proc, parent := process.GetParentProcessInternal(msg.ProcessKey.Pid, timestamp) var err error - if option.Config.EnableProcessAncestors && proc.NeededAncestors() && !msg.RefCntDone[AncestorsRefCnt] { + if option.Config.EnableAncestors["base"] && proc.NeededAncestors() && !msg.RefCntDone[AncestorsRefCnt] { if ancestors, perr := process.GetAncestorProcessesInternal(proc.UnsafeGetProcess().ParentExecId); perr == nil { var tetragonAncestors []*tetragon.Process for _, ancestor := range ancestors { @@ -605,7 +605,7 @@ func (msg *MsgProcessCleanupEventUnix) RetryInternal(_ notify.Event, timestamp u proc, parent := process.GetParentProcessInternal(msg.PID, timestamp) var err error - if option.Config.EnableProcessAncestors && proc.NeededAncestors() && !msg.RefCntDone[AncestorsRefCnt] { + if option.Config.EnableAncestors["base"] && proc.NeededAncestors() && !msg.RefCntDone[AncestorsRefCnt] { if ancestors, perr := process.GetAncestorProcessesInternal(proc.UnsafeGetProcess().ParentExecId); perr == nil { for _, ancestor := range ancestors { ancestor.RefDec("ancestor") @@ -652,19 +652,19 @@ func (msg *MsgProcessCleanupEventUnix) HandleMessage() *tetragon.GetEventsRespon msg.RefCntDone = [3]bool{false, false, false} proc, parent := process.GetParentProcessInternal(msg.PID, msg.Ktime) - if option.Config.EnableProcessAncestors && proc.NeededAncestors() { + if option.Config.EnableAncestors["base"] && proc.NeededAncestors() { ancestors, _ = process.GetAncestorProcessesInternal(proc.UnsafeGetProcess().ParentExecId) } if ec := eventcache.Get(); ec != nil && (proc == nil || parent == nil || - option.Config.EnableProcessAncestors && ec.NeededAncestors(parent, ancestors)) { + option.Config.EnableAncestors["base"] && ec.NeededAncestors(parent, ancestors)) { ec.Add(nil, nil, msg.Ktime, msg.Ktime, msg) return nil } - if option.Config.EnableProcessAncestors { + if option.Config.EnableAncestors["base"] { for _, ancestor := range ancestors { ancestor.RefDec("ancestor") } diff --git a/pkg/grpc/exec/exec_test_helper.go b/pkg/grpc/exec/exec_test_helper.go index 29cdf34fce1..78da177e0e1 100644 --- a/pkg/grpc/exec/exec_test_helper.go +++ b/pkg/grpc/exec/exec_test_helper.go @@ -1107,7 +1107,7 @@ func GrpcDelayedExecK8sOutOfOrder[EXEC notify.Message, EXIT notify.Message](t *t } func GrpcExecAncestorsInOrder[EXEC notify.Message, CLONE notify.Message, EXIT notify.Message](t *testing.T) { - option.Config.EnableProcessAncestors = true // enable Ancestors + option.Config.EnableAncestors = option.AncestorsEventFilter{"base": true} // enable Ancestors AllEvents = nil watcher := watcher.NewFakeK8sWatcher(nil) dn := InitEnv[EXEC, EXIT](t, watcher) @@ -1280,7 +1280,7 @@ func GrpcExecAncestorsInOrder[EXEC notify.Message, CLONE notify.Message, EXIT no } func GrpcExecAncestorsOutOfOrder[EXEC notify.Message, CLONE notify.Message, EXIT notify.Message](t *testing.T) { - option.Config.EnableProcessAncestors = true // enable Ancestors + option.Config.EnableAncestors = option.AncestorsEventFilter{"base": true} // enable Ancestors AllEvents = nil watcher := watcher.NewFakeK8sWatcher(nil) dn := InitEnv[EXEC, EXIT](t, watcher) diff --git a/pkg/grpc/tracing/tracing.go b/pkg/grpc/tracing/tracing.go index 4ae809ef418..084f010f3ec 100644 --- a/pkg/grpc/tracing/tracing.go +++ b/pkg/grpc/tracing/tracing.go @@ -327,8 +327,8 @@ func GetProcessKprobe(event *MsgGenericKprobeUnix) *tetragon.ProcessKprobe { proc, parent, tetragonProcess, tetragonParent := getProcessParent(&event.Msg.ProcessKey, event.Msg.Common.Flags) - // Set the ancestors only if --enable-process-kprobe-ancestors flag is set. - if option.Config.EnableProcessKprobeAncestors && proc.NeededAncestors() { + // Set the ancestors only if --enable-ancestors flag includes 'kprobe'. + if option.Config.EnableAncestors["kprobe"] && proc.NeededAncestors() { ancestors, _ = process.GetAncestorProcessesInternal(tetragonProcess.ParentExecId) for _, ancestor := range ancestors { tetragonAncestors = append(tetragonAncestors, ancestor.UnsafeGetProcess()) @@ -419,7 +419,7 @@ func GetProcessKprobe(event *MsgGenericKprobeUnix) *tetragon.ProcessKprobe { if ec := eventcache.Get(); ec != nil && !isUnknown(tetragonProcess) && (ec.Needed(tetragonProcess) || (tetragonProcess.Pid.Value > 1 && ec.Needed(tetragonParent)) || - (option.Config.EnableProcessKprobeAncestors && ec.NeededAncestors(parent, ancestors))) { + (option.Config.EnableAncestors["kprobe"] && ec.NeededAncestors(parent, ancestors))) { ec.Add(nil, tetragonEvent, event.Msg.Common.Ktime, event.Msg.ProcessKey.Ktime, event) return nil } @@ -480,8 +480,8 @@ func (msg *MsgGenericTracepointUnix) HandleMessage() *tetragon.GetEventsResponse proc, parent, tetragonProcess, tetragonParent := getProcessParent(&msg.Msg.ProcessKey, msg.Msg.Common.Flags) - // Set the ancestors only if --enable-process-tracepoint-ancestors flag is set. - if option.Config.EnableProcessTracepointAncestors && proc.NeededAncestors() { + // Set the ancestors only if --enable-ancestors flag includes 'tracepoint'. + if option.Config.EnableAncestors["tracepoint"] && proc.NeededAncestors() { ancestors, _ = process.GetAncestorProcessesInternal(tetragonProcess.ParentExecId) for _, ancestor := range ancestors { tetragonAncestors = append(tetragonAncestors, ancestor.UnsafeGetProcess()) @@ -622,7 +622,7 @@ func (msg *MsgGenericTracepointUnix) HandleMessage() *tetragon.GetEventsResponse if ec := eventcache.Get(); ec != nil && !isUnknown(tetragonProcess) && (ec.Needed(tetragonProcess) || (tetragonProcess.Pid.Value > 1 && ec.Needed(tetragonParent)) || - (option.Config.EnableProcessTracepointAncestors && ec.NeededAncestors(parent, ancestors))) { + (option.Config.EnableAncestors["tracepoint"] && ec.NeededAncestors(parent, ancestors))) { ec.Add(nil, tetragonEvent, msg.Msg.Common.Ktime, msg.Msg.ProcessKey.Ktime, msg) return nil } @@ -819,8 +819,8 @@ func GetProcessUprobe(event *MsgGenericUprobeUnix) *tetragon.ProcessUprobe { proc, parent, tetragonProcess, tetragonParent := getProcessParent(&event.Msg.ProcessKey, event.Msg.Common.Flags) - // Set the ancestors only if --enable-process-uprobe-ancestors flag is set. - if option.Config.EnableProcessUprobeAncestors && proc.NeededAncestors() { + // Set the ancestors only if --enable-ancestors flag includes 'uprobe'. + if option.Config.EnableAncestors["uprobe"] && proc.NeededAncestors() { ancestors, _ = process.GetAncestorProcessesInternal(tetragonProcess.ParentExecId) for _, ancestor := range ancestors { tetragonAncestors = append(tetragonAncestors, ancestor.UnsafeGetProcess()) @@ -851,7 +851,7 @@ func GetProcessUprobe(event *MsgGenericUprobeUnix) *tetragon.ProcessUprobe { if ec := eventcache.Get(); ec != nil && !isUnknown(tetragonProcess) && (ec.Needed(tetragonProcess) || (tetragonProcess.Pid.Value > 1 && ec.Needed(tetragonParent)) || - (option.Config.EnableProcessUprobeAncestors && ec.NeededAncestors(parent, ancestors))) { + (option.Config.EnableAncestors["uprobe"] && ec.NeededAncestors(parent, ancestors))) { ec.Add(nil, tetragonEvent, event.Msg.Common.Ktime, event.Msg.ProcessKey.Ktime, event) return nil } @@ -943,8 +943,8 @@ func GetProcessLsm(event *MsgGenericLsmUnix) *tetragon.ProcessLsm { proc, parent, tetragonProcess, tetragonParent := getProcessParent(&event.Msg.ProcessKey, event.Msg.Common.Flags) - // Set the ancestors only if --enable-process-lsm-ancestors flag is set. - if option.Config.EnableProcessLsmAncestors && proc.NeededAncestors() { + // Set the ancestors only if --enable-ancestors flag includes 'lsm'. + if option.Config.EnableAncestors["lsm"] && proc.NeededAncestors() { ancestors, _ = process.GetAncestorProcessesInternal(tetragonProcess.ParentExecId) for _, ancestor := range ancestors { tetragonAncestors = append(tetragonAncestors, ancestor.UnsafeGetProcess()) @@ -994,7 +994,7 @@ func GetProcessLsm(event *MsgGenericLsmUnix) *tetragon.ProcessLsm { if ec := eventcache.Get(); ec != nil && !isUnknown(tetragonProcess) && (ec.Needed(tetragonProcess) || (tetragonProcess.Pid.Value > 1 && ec.Needed(tetragonParent)) || - (option.Config.EnableProcessLsmAncestors && ec.NeededAncestors(parent, ancestors))) { + (option.Config.EnableAncestors["lsm"] && ec.NeededAncestors(parent, ancestors))) { ec.Add(nil, tetragonEvent, event.Msg.Common.Ktime, event.Msg.ProcessKey.Ktime, event) return nil } diff --git a/pkg/option/ancestors_event_filter.go b/pkg/option/ancestors_event_filter.go new file mode 100644 index 00000000000..f1528b3dbfb --- /dev/null +++ b/pkg/option/ancestors_event_filter.go @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package option + +import ( + "maps" + "slices" + "strings" + + "github.com/cilium/tetragon/api/v1/tetragon" +) + +var AncestorsEventTypeMap = map[tetragon.EventType]string{ + tetragon.EventType_PROCESS_EXEC: "base", + tetragon.EventType_PROCESS_EXIT: "base", + tetragon.EventType_PROCESS_KPROBE: "kprobe", + tetragon.EventType_PROCESS_TRACEPOINT: "tracepoint", + tetragon.EventType_PROCESS_UPROBE: "uprobe", + tetragon.EventType_PROCESS_LSM: "lsm", +} + +func GetAncestorsEventTypes() []tetragon.EventType { + return slices.Collect(maps.Keys(AncestorsEventTypeMap)) +} + +type AncestorsEventFilter map[string]bool + +func DefaultEnableAncestors() AncestorsEventFilter { + return AncestorsEventFilter{ + "base": false, + "kprobe": false, + "tracepoint": false, + "uprobe": false, + "lsm": false, + } +} + +func ParseEnableAncestors(eventTypesString string) []string { + eventTypes := []string{} + for _, t := range strings.Split(eventTypesString, ",") { + t = strings.TrimSpace(t) + eventTypes = append(eventTypes, t) + } + return eventTypes +} + +// WithEnabledAncestors returns a new AncestorsEventFilter with only the event types in eventTypes enabled. +// If eventTypes is nil, a copy of the original AncestorsEventFilter is returned. +// If eventTypes is empty, all event types are disabled. +// If eventTypes contains event types that are not in the original AncestorsEventFilter, they are ignored. +func (f AncestorsEventFilter) WithEnabledAncestors(eventTypes []string) AncestorsEventFilter { + ancestorsEventFilter := maps.Clone(f) + if eventTypes == nil { + return ancestorsEventFilter + } + + // disable all configurable event types + for t := range f { + ancestorsEventFilter[t] = false + } + + if slices.Contains(eventTypes, "base") { + // enable configured event types + for _, t := range eventTypes { + // quietly ignore unknown event types + if _, ok := ancestorsEventFilter[t]; ok { + ancestorsEventFilter[t] = true + } + } + } + + return ancestorsEventFilter +} diff --git a/pkg/option/ancestors_event_filter_test.go b/pkg/option/ancestors_event_filter_test.go new file mode 100644 index 00000000000..614db61a422 --- /dev/null +++ b/pkg/option/ancestors_event_filter_test.go @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package option + +import ( + "maps" + "testing" +) + +func TestParseEnableAncestors(t *testing.T) { + tests := []struct { + name string + input string + expected map[string]bool + }{ + { + name: "no event types (default)", + input: "", + expected: DefaultEnableAncestors(), + }, + { + name: "all event types", + input: "base,kprobe,tracepoint,uprobe,lsm", + expected: map[string]bool{"base": true, "kprobe": true, "tracepoint": true, "uprobe": true, "lsm": true}, + }, + { + name: "without base", + input: "kprobe,tracepoint,uprobe,lsm", + expected: map[string]bool{"base": false, "kprobe": false, "tracepoint": false, "uprobe": false, "lsm": false}, + }, + { + name: "spaces + empty", + input: "base , kprobe , ,, lsm", + expected: map[string]bool{"base": true, "kprobe": true, "tracepoint": false, "uprobe": false, "lsm": true}, + }, + { + name: "unknown + misspelled", + input: "base,kprobe,unknown,ttracepoint,uprobee,lssm", + expected: map[string]bool{"base": true, "kprobe": true, "tracepoint": false, "uprobe": false, "lsm": false}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := DefaultEnableAncestors().WithEnabledAncestors(ParseEnableAncestors(tt.input)) + if !maps.Equal(actual, tt.expected) { + t.Errorf("%q got parsed as %v, want %v", tt.input, actual, tt.expected) + } + }) + } +} diff --git a/pkg/option/config.go b/pkg/option/config.go index e0a9dd69ced..77b22ac1e13 100644 --- a/pkg/option/config.go +++ b/pkg/option/config.go @@ -29,12 +29,7 @@ type config struct { EnablePodAnnotations bool - EnableProcessAncestors bool - EnableProcessKprobeAncestors bool - EnableProcessTracepointAncestors bool - EnableProcessUprobeAncestors bool - EnableProcessLsmAncestors bool - + EnableAncestors AncestorsEventFilter EnableProcessNs bool EnableProcessCred bool EnableK8s bool diff --git a/pkg/option/flags.go b/pkg/option/flags.go index 47bd0d1df23..96999d0b6a1 100644 --- a/pkg/option/flags.go +++ b/pkg/option/flags.go @@ -45,12 +45,15 @@ const ( KeyServerAddress = "server-address" KeyGopsAddr = "gops-address" + // NOTE: enable-process-ancestors flags are marked as deprecated and + // planned to be removed in version 1.6 KeyEnableProcessAncestors = "enable-process-ancestors" KeyEnableProcessKprobeAncestors = "enable-process-kprobe-ancestors" KeyEnableProcessTracepointAncestors = "enable-process-tracepoint-ancestors" KeyEnableProcessUprobeAncestors = "enable-process-uprobe-ancestors" KeyEnableProcessLsmAncestors = "enable-process-lsm-ancestors" + KeyEnableAncestors = "enable-ancestors" KeyEnableProcessCred = "enable-process-cred" KeyEnableProcessNs = "enable-process-ns" KeyTracingPolicy = "tracing-policy" @@ -159,12 +162,20 @@ func ReadAndSetFlags() error { Config.Debug = viper.GetBool(KeyDebug) Config.ClusterName = viper.GetString(KeyClusterName) - Config.EnableProcessAncestors = viper.GetBool(KeyEnableProcessAncestors) - if Config.EnableProcessAncestors { - Config.EnableProcessKprobeAncestors = viper.GetBool(KeyEnableProcessKprobeAncestors) - Config.EnableProcessTracepointAncestors = viper.GetBool(KeyEnableProcessTracepointAncestors) - Config.EnableProcessUprobeAncestors = viper.GetBool(KeyEnableProcessUprobeAncestors) - Config.EnableProcessLsmAncestors = viper.GetBool(KeyEnableProcessLsmAncestors) + Config.EnableAncestors = DefaultEnableAncestors() + // NOTE: enable-process-ancestors flags are marked as deprecated and + // planned to be removed in version 1.6 + if viper.GetBool(KeyEnableProcessAncestors) { + Config.EnableAncestors["base"] = true + Config.EnableAncestors["kprobe"] = viper.GetBool(KeyEnableProcessKprobeAncestors) + Config.EnableAncestors["tracepoint"] = viper.GetBool(KeyEnableProcessTracepointAncestors) + Config.EnableAncestors["uprobe"] = viper.GetBool(KeyEnableProcessUprobeAncestors) + Config.EnableAncestors["lsm"] = viper.GetBool(KeyEnableProcessLsmAncestors) + } + + // Override deprecated flags, if new --enable-ancestors flag is used + if enableAncestors := viper.GetString(KeyEnableAncestors); enableAncestors != "" { + Config.EnableAncestors = Config.EnableAncestors.WithEnabledAncestors(ParseEnableAncestors(enableAncestors)) } Config.EnableProcessCred = viper.GetBool(KeyEnableProcessCred) @@ -357,12 +368,20 @@ func AddFlags(flags *pflag.FlagSet) { flags.Bool(KeyEnableProcessNs, false, "Enable namespace information in process_exec and process_kprobe events") flags.Uint(KeyEventQueueSize, 10000, "Set the size of the internal event queue.") flags.Bool(KeyEnablePodAnnotations, false, "Add pod annotations field to events.") - // Allow to include ancestor processes in events - flags.Bool(KeyEnableProcessAncestors, false, "Include ancestors in process_exec and process_exit events. Disabled by default. Required by other enable ancestors options for correct reference counting") - flags.Bool(KeyEnableProcessKprobeAncestors, false, fmt.Sprintf("Include ancestors in process_kprobe events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) - flags.Bool(KeyEnableProcessTracepointAncestors, false, fmt.Sprintf("Include ancestors in process_tracepoint events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) - flags.Bool(KeyEnableProcessUprobeAncestors, false, fmt.Sprintf("Include ancestors in process_uprobe events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) - flags.Bool(KeyEnableProcessLsmAncestors, false, fmt.Sprintf("Include ancestors in process_lsm events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) + flags.String(KeyEnableAncestors, "", "Comma-separated list of process event types to enable ancestors for. Supported event types are: base, kprobe, tracepoint, uprobe, lsm. Unknown event types will be ignored. Type 'base' enables ancestors for process_exec and process_exit events and is required by all other supported event types for correct reference counting. An empty string disables ancestors completely") + + // NOTE: enable-process-ancestors flags are marked as deprecated and + // planned to be removed in version 1.6 + flags.Bool(KeyEnableProcessAncestors, false, "Deprecated, please, use --enable-ancestors. Include ancestors in process_exec and process_exit events. Disabled by default. Required by other enable ancestors options for correct reference counting") + flags.Bool(KeyEnableProcessKprobeAncestors, false, fmt.Sprintf("Deprecated, please, use --enable-ancestors. Include ancestors in process_kprobe events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) + flags.Bool(KeyEnableProcessTracepointAncestors, false, fmt.Sprintf("Deprecated, please, use --enable-ancestors. Include ancestors in process_tracepoint events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) + flags.Bool(KeyEnableProcessUprobeAncestors, false, fmt.Sprintf("Deprecated, please, use --enable-ancestors. Include ancestors in process_uprobe events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) + flags.Bool(KeyEnableProcessLsmAncestors, false, fmt.Sprintf("Deprecated, please, use --enable-ancestors. Include ancestors in process_lsm events. Only used if '%s' is set to 'true'", KeyEnableProcessAncestors)) + flags.MarkDeprecated(KeyEnableProcessAncestors, "please use --enable-ancestors") + flags.MarkDeprecated(KeyEnableProcessKprobeAncestors, "please use --enable-ancestors") + flags.MarkDeprecated(KeyEnableProcessTracepointAncestors, "please use --enable-ancestors") + flags.MarkDeprecated(KeyEnableProcessUprobeAncestors, "please use --enable-ancestors") + flags.MarkDeprecated(KeyEnableProcessLsmAncestors, "please use --enable-ancestors") // Tracing policy file flags.String(KeyTracingPolicy, "", "Tracing policy file to load at startup") From e7e6ed47cf4554e570f6fbd564722c153b80cf36 Mon Sep 17 00:00:00 2001 From: t0x01 Date: Wed, 16 Apr 2025 16:36:29 +0400 Subject: [PATCH 2/4] examples: Replace deprecated enable-process-ancestors boolean flags Replace tetragon enable-process-ancestors boolean flags added in PR 2938 (e.g., see e2acd5b) with a new '--enable-ancestors' flag. Signed-off-by: t0x01 --- examples/configuration/tetragon.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/configuration/tetragon.yaml b/examples/configuration/tetragon.yaml index b63e75e3f22..eda4ea310b2 100644 --- a/examples/configuration/tetragon.yaml +++ b/examples/configuration/tetragon.yaml @@ -16,11 +16,7 @@ debug: false disable-kprobe-multi: false enable-export-aggregation: false enable-k8s-api: false -enable-process-ancestors: false -enable-process-kprobe-ancestors: false -enable-process-tracepoint-ancestors: false -enable-process-uprobe-ancestors: false -enable-process-lsm-ancestors: false +enable-ancestors: "base,kprobe,tracepoint,uprobe,lsm" enable-process-cred: false enable-process-ns: false event-queue-size: 10000 From 212566d42ee5e3ec9449ac5e2339a6eb9ebee4cb Mon Sep 17 00:00:00 2001 From: t0x01 Date: Wed, 16 Apr 2025 16:37:08 +0400 Subject: [PATCH 3/4] docs: Deprecate enable-process-ancestors boolean flags Deprecate tetragon enable-process-ancestors boolean flags added in PR 2938 (e.g., see dc9ba94) and introduce a new '--enable-ancestors' flag to replace them for better UX. Aforementioned flags are now marked as deprecated, but still usable. Signed-off-by: t0x01 --- contrib/upgrade-notes/latest.md | 8 +++++++- docs/data/tetragon_flags.yaml | 13 ++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/contrib/upgrade-notes/latest.md b/contrib/upgrade-notes/latest.md index 6781dd46772..9812381e1b8 100644 --- a/contrib/upgrade-notes/latest.md +++ b/contrib/upgrade-notes/latest.md @@ -3,7 +3,13 @@ Read the upgrade notes carefully before upgrading Tetragon. Depending on your setup, changes listed here might require a manual intervention. -* TBD +* Enabling ancestors for process events is now configured by a new `--enable-ancestors` flag. + The following flags are being deprecarted in this (1.5) and are scheduled for removal in the next (1.6): + * `--enable-process-ancestors` + * `--enable-process-kprobe-ancestors` + * `--enable-process-tracepoint-ancestors` + * `--enable-process-uprobe-ancestors` + * `--enable-process-lsm-ancestors` ### Agent Options diff --git a/docs/data/tetragon_flags.yaml b/docs/data/tetragon_flags.yaml index 882f5911969..c95950859c9 100644 --- a/docs/data/tetragon_flags.yaml +++ b/docs/data/tetragon_flags.yaml @@ -32,6 +32,9 @@ options: - name: disable-kprobe-multi default_value: "false" usage: Allow to disable kprobe multi interface + - name: enable-ancestors + usage: | + Comma-separated list of process event types to enable ancestors for. Supported event types are: base, kprobe, tracepoint, uprobe, lsm. Unknown event types will be ignored. Type 'base' enables ancestors for process_exec and process_exit events and is required by all other supported event types for correct reference counting. An empty string disables ancestors completely - name: enable-cgidmap default_value: "false" usage: enable pod resolution via cgroup ids @@ -81,18 +84,18 @@ options: - name: enable-process-ancestors default_value: "false" usage: | - Include ancestors in process_exec and process_exit events. Disabled by default. Required by other enable ancestors options for correct reference counting + Deprecated, please, use --enable-ancestors. Include ancestors in process_exec and process_exit events. Disabled by default. Required by other enable ancestors options for correct reference counting - name: enable-process-cred default_value: "false" usage: Enable process_cred events - name: enable-process-kprobe-ancestors default_value: "false" usage: | - Include ancestors in process_kprobe events. Only used if 'enable-process-ancestors' is set to 'true' + Deprecated, please, use --enable-ancestors. Include ancestors in process_kprobe events. Only used if 'enable-process-ancestors' is set to 'true' - name: enable-process-lsm-ancestors default_value: "false" usage: | - Include ancestors in process_lsm events. Only used if 'enable-process-ancestors' is set to 'true' + Deprecated, please, use --enable-ancestors. Include ancestors in process_lsm events. Only used if 'enable-process-ancestors' is set to 'true' - name: enable-process-ns default_value: "false" usage: | @@ -100,11 +103,11 @@ options: - name: enable-process-tracepoint-ancestors default_value: "false" usage: | - Include ancestors in process_tracepoint events. Only used if 'enable-process-ancestors' is set to 'true' + Deprecated, please, use --enable-ancestors. Include ancestors in process_tracepoint events. Only used if 'enable-process-ancestors' is set to 'true' - name: enable-process-uprobe-ancestors default_value: "false" usage: | - Include ancestors in process_uprobe events. Only used if 'enable-process-ancestors' is set to 'true' + Deprecated, please, use --enable-ancestors. Include ancestors in process_uprobe events. Only used if 'enable-process-ancestors' is set to 'true' - name: enable-tracing-policy-crd default_value: "true" usage: | From b4df3ae27e7ea358b6a9555c49f7ef384f7830f9 Mon Sep 17 00:00:00 2001 From: t0x01 Date: Wed, 16 Apr 2025 16:37:40 +0400 Subject: [PATCH 4/4] helm: Add tetragon.processAncestors.enabled value Add support for process ancestors introduced in PR 2938 (e.g., see fd57a14). Signed-off-by: t0x01 --- docs/content/en/docs/reference/helm-chart.md | 1 + install/kubernetes/tetragon/README.md | 1 + .../kubernetes/tetragon/templates/tetragon_configmap.yaml | 1 + install/kubernetes/tetragon/values.yaml | 6 ++++++ 4 files changed, 9 insertions(+) diff --git a/docs/content/en/docs/reference/helm-chart.md b/docs/content/en/docs/reference/helm-chart.md index d0455208e19..fd065e0ad1c 100644 --- a/docs/content/en/docs/reference/helm-chart.md +++ b/docs/content/en/docs/reference/helm-chart.md @@ -125,6 +125,7 @@ To use [the values available](#values), with `helm install` or `helm upgrade`, u | tetragon.pprof.address | string | `"localhost"` | The address at which to expose pprof. | | tetragon.pprof.enabled | bool | `false` | Whether to enable exposing pprof server. | | tetragon.pprof.port | int | `6060` | The port at which to expose pprof. | +| tetragon.processAncestors.enabled | string | `""` | Comma-separated list of process event types to enable ancestors for. Supported event types are: base, kprobe, tracepoint, uprobe, lsm. Unknown event types will be ignored. Type "base" is required by all other supported event types for correct reference counting. Set it to "" to disable ancestors completely. | | tetragon.processCacheGCInterval | string | `"30s"` | Configure the interval (suffixed with s for seconds, m for minutes, etc) for the process cache garbage collector. | | tetragon.processCacheSize | int | `65536` | Tetragon puts processes in an LRU cache. The cache is used to find ancestors for subsequently exec'ed processes. | | tetragon.prometheus.address | string | `""` | The address at which to expose metrics. Set it to "" to expose on all available interfaces. | diff --git a/install/kubernetes/tetragon/README.md b/install/kubernetes/tetragon/README.md index d646f266920..737e0230ec4 100644 --- a/install/kubernetes/tetragon/README.md +++ b/install/kubernetes/tetragon/README.md @@ -107,6 +107,7 @@ Helm chart for Tetragon | tetragon.pprof.address | string | `"localhost"` | The address at which to expose pprof. | | tetragon.pprof.enabled | bool | `false` | Whether to enable exposing pprof server. | | tetragon.pprof.port | int | `6060` | The port at which to expose pprof. | +| tetragon.processAncestors.enabled | string | `""` | Comma-separated list of process event types to enable ancestors for. Supported event types are: base, kprobe, tracepoint, uprobe, lsm. Unknown event types will be ignored. Type "base" is required by all other supported event types for correct reference counting. Set it to "" to disable ancestors completely. | | tetragon.processCacheGCInterval | string | `"30s"` | Configure the interval (suffixed with s for seconds, m for minutes, etc) for the process cache garbage collector. | | tetragon.processCacheSize | int | `65536` | Tetragon puts processes in an LRU cache. The cache is used to find ancestors for subsequently exec'ed processes. | | tetragon.prometheus.address | string | `""` | The address at which to expose metrics. Set it to "" to expose on all available interfaces. | diff --git a/install/kubernetes/tetragon/templates/tetragon_configmap.yaml b/install/kubernetes/tetragon/templates/tetragon_configmap.yaml index 96fea3df942..0fe402bed17 100644 --- a/install/kubernetes/tetragon/templates/tetragon_configmap.yaml +++ b/install/kubernetes/tetragon/templates/tetragon_configmap.yaml @@ -14,6 +14,7 @@ data: debug: {{ .Values.tetragon.debug | quote }} enable-process-cred: {{ .Values.tetragon.enableProcessCred | quote }} enable-process-ns: {{ .Values.tetragon.enableProcessNs | quote }} + enable-ancestors: {{ .Values.tetragon.processAncestors.enabled }} process-cache-size: {{ .Values.tetragon.processCacheSize | quote }} {{- if .Values.tetragon.exportFilename }} export-filename: {{ .Values.exportDirectory}}/{{ .Values.tetragon.exportFilename }} diff --git a/install/kubernetes/tetragon/values.yaml b/install/kubernetes/tetragon/values.yaml index ae51bacfd2e..e56743c9ddd 100644 --- a/install/kubernetes/tetragon/values.yaml +++ b/install/kubernetes/tetragon/values.yaml @@ -148,6 +148,12 @@ tetragon: enableProcessCred: false # -- Enable Namespaces visibility in exec and kprobe events. enableProcessNs: false + processAncestors: + # -- Comma-separated list of process event types to enable ancestors for. + # Supported event types are: base, kprobe, tracepoint, uprobe, lsm. Unknown event types will be ignored. + # Type "base" is required by all other supported event types for correct reference counting. + # Set it to "" to disable ancestors completely. + enabled: "" # -- Set --btf option to explicitly specify an absolute path to a btf file. For advanced users only. btf: "" # -- Override the command. For advanced users only.