Skip to content

Commit

Permalink
fix: possible overwrite of Args on Derive stage
Browse files Browse the repository at this point in the history
  • Loading branch information
geyslan committed Oct 9, 2024
1 parent 3cfe5c5 commit cb48e1f
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 3 deletions.
6 changes: 5 additions & 1 deletion pkg/ebpf/events_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/binary"
"slices"
"strconv"
"sync"
"unsafe"
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 6 additions & 1 deletion pkg/events/derive/derive.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package derive

import (
"slices"

"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/types/trace"
)
Expand Down Expand Up @@ -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))
Expand Down
4 changes: 3 additions & 1 deletion pkg/events/derive/derive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package derive

import (
"fmt"
"slices"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -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)
})
Expand Down

0 comments on commit cb48e1f

Please sign in to comment.