From cb48e1fca523c9e983382f20d21bb8351cebda6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Geyslan=20Greg=C3=B3rio?= Date: Wed, 9 Oct 2024 13:56:06 -0300 Subject: [PATCH] fix: possible overwrite of Args on Derive stage --- pkg/ebpf/events_pipeline.go | 6 +++++- pkg/events/derive/derive.go | 7 ++++++- pkg/events/derive/derive_test.go | 4 +++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pkg/ebpf/events_pipeline.go b/pkg/ebpf/events_pipeline.go index db325a6daf5d..edfb72416627 100644 --- a/pkg/ebpf/events_pipeline.go +++ b/pkg/ebpf/events_pipeline.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/binary" + "slices" "strconv" "sync" "unsafe" @@ -536,10 +537,13 @@ func (t *Tracee) deriveEvents(ctx context.Context, in <-chan *trace.Event) ( // acting on the derived event. eventCopy := *event + // shallow clone the event arguments (new slice is created) before deriving the copy, + // to ensure the original event arguments are not modified by the derivation stage. + argsCopy := slices.Clone(event.Args) out <- event // Note: event is being derived before any of its args are parsed. - derivatives, errors := t.eventDerivations.DeriveEvent(eventCopy) + derivatives, errors := t.eventDerivations.DeriveEvent(eventCopy, argsCopy) for _, err := range errors { t.handleError(err) diff --git a/pkg/events/derive/derive.go b/pkg/events/derive/derive.go index af7000b3737e..1ecfd11e2c53 100644 --- a/pkg/events/derive/derive.go +++ b/pkg/events/derive/derive.go @@ -1,6 +1,8 @@ package derive import ( + "slices" + "github.com/aquasecurity/tracee/pkg/events" "github.com/aquasecurity/tracee/types/trace" ) @@ -41,12 +43,15 @@ func (t Table) Register(deriveFrom, deriveTo events.ID, deriveCondition func() b } // DeriveEvent takes a trace.Event and checks if it can derive additional events from it as defined by a derivationTable. -func (t Table) DeriveEvent(event trace.Event) ([]trace.Event, []error) { +func (t Table) DeriveEvent(event trace.Event, origArgs []trace.Argument) ([]trace.Event, []error) { derivatives := []trace.Event{} errors := []error{} deriveFns := t[events.ID(event.EventID)] for id, deriveFn := range deriveFns { if deriveFn.Enabled() { + // at each derivation, we need use a copy of the original arguments, + // since they might be modified by a previous derivation. + event.Args = slices.Clone(origArgs) derivative, errs := deriveFn.DeriveFunction(event) for _, err := range errs { errors = append(errors, deriveError(id, err)) diff --git a/pkg/events/derive/derive_test.go b/pkg/events/derive/derive_test.go index 4932b7418fc7..e69f1c6bf660 100644 --- a/pkg/events/derive/derive_test.go +++ b/pkg/events/derive/derive_test.go @@ -2,6 +2,7 @@ package derive import ( "fmt" + "slices" "testing" "github.com/stretchr/testify/assert" @@ -74,7 +75,8 @@ func Test_DeriveEvent(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() - derived, errors := mockDerivationTable.DeriveEvent(tc.event) + argsCopy := slices.Clone(tc.event.Args) + derived, errors := mockDerivationTable.DeriveEvent(tc.event, argsCopy) assert.Equal(t, tc.expectedDerived, derived) assert.Equal(t, tc.expectedErrors, errors) })