Skip to content

Commit

Permalink
chore(ebpf): copy event before parsing it
Browse files Browse the repository at this point in the history
Refactor 'event feeding to engine' logic to copy the event before
parsing it, cloning its arguments.
  • Loading branch information
geyslan committed Sep 26, 2024
1 parent abad20b commit 3330712
Showing 1 changed file with 39 additions and 31 deletions.
70 changes: 39 additions & 31 deletions pkg/ebpf/signature_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ebpf

import (
"context"
"slices"

"github.com/aquasecurity/tracee/pkg/containers"
"github.com/aquasecurity/tracee/pkg/dnscache"
Expand Down Expand Up @@ -52,35 +53,6 @@ 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)
}

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)
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.
eventCopy := *event
// 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
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
Expand All @@ -91,12 +63,48 @@ func (t *Tracee) engineEvents(ctx context.Context, in <-chan *trace.Event) (<-ch
defer close(engineInput)
defer close(engineOutput)

// getEventCopy returns a shallow copy of the event with a deep copy of the arguments slice
getEventCopy := func(event *trace.Event) trace.Event {
eventCopy := *event
eventCopy.Args = slices.Clone(event.Args)
return eventCopy
}

// 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) {
// Get a copy of event before parsing it or 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.
eventCopy := getEventCopy(event)

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 copied event to the rules engine
engineInput <- eventCopy.ToProtocol()
}
}

for {
select {
case event := <-in:
feedFunc(event)
feedEngine(event)
case event := <-engineOutputEvents:
feedFunc(event)
feedEngine(event)
case <-ctx.Done():
return
}
Expand Down

0 comments on commit 3330712

Please sign in to comment.