diff --git a/pkg/ebpf/events_pipeline.go b/pkg/ebpf/events_pipeline.go index fa1eb2b16887..db325a6daf5d 100644 --- a/pkg/ebpf/events_pipeline.go +++ b/pkg/ebpf/events_pipeline.go @@ -614,8 +614,8 @@ func (t *Tracee) sinkEvents(ctx context.Context, in <-chan *trace.Event) <-chan // Populate the event with the names of the matched policies. event.MatchedPolicies = t.policyManager.MatchedNames(event.MatchedPoliciesUser) - // Parse args here if the rule engine is not enabled (parsed there if it is). - if !t.config.EngineConfig.Enabled { + // Parse args here if the rule engine is NOT enabled (parsed there if it is). + if t.config.Output.ParseArguments && !t.config.EngineConfig.Enabled { err := t.parseArguments(event) if err != nil { t.handleError(err) @@ -727,15 +727,13 @@ func (t *Tracee) handleError(err error) { // cmd/tracee-rules), it happens on the "sink" stage of the pipeline (close to the // printers). func (t *Tracee) parseArguments(e *trace.Event) error { - if t.config.Output.ParseArguments { - err := events.ParseArgs(e) - if err != nil { - return errfmt.WrapError(err) - } + err := events.ParseArgs(e) + if err != nil { + return errfmt.WrapError(err) + } - if t.config.Output.ParseArgumentsFDs { - return events.ParseArgsFDs(e, uint64(e.Timestamp), t.FDArgPathMap) - } + if t.config.Output.ParseArgumentsFDs { + return events.ParseArgsFDs(e, uint64(e.Timestamp), t.FDArgPathMap) } return nil diff --git a/pkg/ebpf/signature_engine.go b/pkg/ebpf/signature_engine.go index 32376c9420b3..a0d66ef83799 100644 --- a/pkg/ebpf/signature_engine.go +++ b/pkg/ebpf/signature_engine.go @@ -2,6 +2,7 @@ package ebpf import ( "context" + "slices" "github.com/aquasecurity/tracee/pkg/containers" "github.com/aquasecurity/tracee/pkg/dnscache" @@ -52,51 +53,60 @@ func (t *Tracee) engineEvents(ctx context.Context, in <-chan *trace.Event) (<-ch go t.sigEngine.Start(ctx) - // Create a function for feeding the engine with an event - feedFunc := func(event *trace.Event) { - if event == nil { - return // might happen during initialization (ctrl+c seg faults) - } + // TODO: in the upcoming releases, the rule engine should be changed to receive trace.Event, + // and return a trace.Event, which should remove the necessity of converting trace.Event to protocol.Event, + // and converting detect.Finding into trace.Event - id := events.ID(event.EventID) + go func() { + defer close(out) + defer close(errc) + defer close(engineInput) + defer close(engineOutput) + + // feedEngine feeds an event to the rules engine + feedEngine := func(event *trace.Event) { + if event == nil { + return // might happen during initialization (ctrl+c seg faults) + } + + id := events.ID(event.EventID) - // if the event is marked as submit, we pass it to the engine - if t.policyManager.IsEventToSubmit(id) { - err := t.parseArguments(event) - if err != nil { - t.handleError(err) + // if the event is NOT marked as submit, it is not sent to the rules engine + if !t.policyManager.IsEventToSubmit(id) { return } - // Get a copy of our event before sending it down the pipeline. - // This is needed because a later modification of the event (in - // particular of the matched policies) can affect engine stage. + // Get a copy of event before parsing it or sending it down the pipeline. + // This is needed because a later modification of the event (matched policies or + // arguments parsing) can affect engine stage. eventCopy := *event + + if t.config.Output.ParseArguments { + // shallow clone the event arguments before parsing them (new slice is created), + // to keep the eventCopy with raw arguments. + eventCopy.Args = slices.Clone(event.Args) + + err := t.parseArguments(event) + if err != nil { + t.handleError(err) + return + } + } + // pass the event to the sink stage, if the event is also marked as emit // it will be sent to print by the sink stage out <- event - // send the event to the rule event + // send the copied event to the rules engine engineInput <- eventCopy.ToProtocol() } - } - - // TODO: in the upcoming releases, the rule engine should be changed to receive trace.Event, - // and return a trace.Event, which should remove the necessity of converting trace.Event to protocol.Event, - // and converting detect.Finding into trace.Event - - go func() { - defer close(out) - defer close(errc) - defer close(engineInput) - defer close(engineOutput) for { select { case event := <-in: - feedFunc(event) + feedEngine(event) case event := <-engineOutputEvents: - feedFunc(event) + feedEngine(event) case <-ctx.Done(): return }