From 7bd8324e988f6fad3e6f9cb7bcdbbee212c53333 Mon Sep 17 00:00:00 2001 From: Ofek Shaked <32914127+oshaked1@users.noreply.github.com> Date: Thu, 30 Jan 2025 12:55:44 +0200 Subject: [PATCH] feat(events): convert syscall arg to name at processing stage (#4563) Since signatures now receive unparsed event arguments, conversion of syscall IDs to names became an issue since the signature has no way to know whether the event was generated on an x86_64 or ARM64 system. To solve this, we convert the syscall ID argument to its name at the event processing stage, so it happens regardless of argument parsing. This is applied to the `suspicious_syscall_source` and `stack_pivot` events. --- pkg/ebpf/processor.go | 2 ++ pkg/ebpf/processor_funcs.go | 22 +++++++++++++++++++ pkg/events/core.go | 4 ++-- pkg/events/parse_args.go | 10 --------- tests/e2e-inst-signatures/e2e-stack_pivot.go | 5 ++--- .../e2e-suspicious_syscall_source.go | 5 ++--- 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/pkg/ebpf/processor.go b/pkg/ebpf/processor.go index 5c36300509b4..88c92d1ed16e 100644 --- a/pkg/ebpf/processor.go +++ b/pkg/ebpf/processor.go @@ -131,6 +131,8 @@ func (t *Tracee) registerEventProcessors() { t.RegisterEventProcessor(events.PrintMemDump, t.processTriggeredEvent) t.RegisterEventProcessor(events.PrintMemDump, t.processPrintMemDump) t.RegisterEventProcessor(events.SharedObjectLoaded, t.processSharedObjectLoaded) + t.RegisterEventProcessor(events.SuspiciousSyscallSource, t.convertSyscallIDToName) + t.RegisterEventProcessor(events.StackPivot, t.convertSyscallIDToName) // // Uprobe based events processors diff --git a/pkg/ebpf/processor_funcs.go b/pkg/ebpf/processor_funcs.go index c5e817451df3..6feed480ea98 100644 --- a/pkg/ebpf/processor_funcs.go +++ b/pkg/ebpf/processor_funcs.go @@ -487,3 +487,25 @@ func (t *Tracee) removeIrrelevantContext(event *trace.Event) error { return nil } + +func (t *Tracee) convertSyscallIDToName(event *trace.Event) error { + syscallArg := events.GetArg(event, "syscall") + if syscallArg == nil { + return errfmt.Errorf("cannot find syscall argument") + } + + syscallID, ok := syscallArg.Value.(int32) + if !ok { + return errfmt.Errorf("cannot convert syscall arg to ID") + } + syscallDef := events.Core.GetDefinitionByID(events.ID(syscallID)) + // no need to check for NotValid() since it is syscall only if it's a valid event + if !syscallDef.IsSyscall() { + return errfmt.Errorf("invalid syscall ID %d", syscallID) + } + + syscallArg.Type = "string" + syscallArg.Value = syscallDef.GetName() + + return nil +} diff --git a/pkg/events/core.go b/pkg/events/core.go index 7cb67f000b3e..9ba2ab691400 100644 --- a/pkg/events/core.go +++ b/pkg/events/core.go @@ -13075,7 +13075,7 @@ var CoreEvents = map[ID]Definition{ }, sets: []string{}, fields: []trace.ArgMeta{ - {Type: "int", Name: "syscall"}, + {Type: "int", Name: "syscall"}, // converted to syscall name (string) at processing stage {Type: "void*", Name: "ip"}, {Type: "char*", Name: "vma_type"}, {Type: "void*", Name: "vma_start"}, @@ -13095,7 +13095,7 @@ var CoreEvents = map[ID]Definition{ }, sets: []string{}, fields: []trace.ArgMeta{ - {Type: "int", Name: "syscall"}, + {Type: "int", Name: "syscall"}, // converted to syscall name (string) at processing stage {Type: "void*", Name: "sp"}, {Type: "char*", Name: "vma_type"}, {Type: "void*", Name: "vma_start"}, diff --git a/pkg/events/parse_args.go b/pkg/events/parse_args.go index a899afe6e25a..ad4532d733d7 100644 --- a/pkg/events/parse_args.go +++ b/pkg/events/parse_args.go @@ -240,16 +240,6 @@ func ParseArgs(event *trace.Event) error { } } case SuspiciousSyscallSource, StackPivot: - if syscallArg := GetArg(event, "syscall"); syscallArg != nil { - if id, isInt32 := syscallArg.Value.(int32); isInt32 { - eventDefinition := Core.GetDefinitionByID(ID(id)) - // no need to check for NotValid() since it is syscall only if it's a valid event - if eventDefinition.IsSyscall() { - syscallArg.Value = eventDefinition.GetName() - syscallArg.Type = "string" - } - } - } if vmaFlagsArg := GetArg(event, "vma_flags"); vmaFlagsArg != nil { if flags, isUint64 := vmaFlagsArg.Value.(uint64); isUint64 { vmaFlagsArg.Type = "string" diff --git a/tests/e2e-inst-signatures/e2e-stack_pivot.go b/tests/e2e-inst-signatures/e2e-stack_pivot.go index b2ffd5f12303..50419d671921 100644 --- a/tests/e2e-inst-signatures/e2e-stack_pivot.go +++ b/tests/e2e-inst-signatures/e2e-stack_pivot.go @@ -3,7 +3,6 @@ package main import ( "fmt" - "github.com/aquasecurity/tracee/pkg/events" "github.com/aquasecurity/tracee/signatures/helpers" "github.com/aquasecurity/tracee/types/detect" "github.com/aquasecurity/tracee/types/protocol" @@ -46,7 +45,7 @@ func (sig *e2eStackPivot) OnEvent(event protocol.Event) error { switch eventObj.EventName { case "stack_pivot": - syscall, err := helpers.ArgVal[int32](eventObj.Args, "syscall") + syscall, err := helpers.ArgVal[string](eventObj.Args, "syscall") if err != nil { return err } @@ -56,7 +55,7 @@ func (sig *e2eStackPivot) OnEvent(event protocol.Event) error { } // Make sure this is the exact event we're looking for - if eventObj.ProcessName == "stack_pivot" && syscall == int32(events.ExitGroup) && vmaType == "heap" { + if eventObj.ProcessName == "stack_pivot" && syscall == "exit_group" && vmaType == "heap" { // Make sure there was no false positive if !sig.falsePositive { m, _ := sig.GetMetadata() diff --git a/tests/e2e-inst-signatures/e2e-suspicious_syscall_source.go b/tests/e2e-inst-signatures/e2e-suspicious_syscall_source.go index 5a67c3cf9f56..b3c1ea891ac2 100644 --- a/tests/e2e-inst-signatures/e2e-suspicious_syscall_source.go +++ b/tests/e2e-inst-signatures/e2e-suspicious_syscall_source.go @@ -3,7 +3,6 @@ package main import ( "fmt" - "github.com/aquasecurity/tracee/pkg/events" "github.com/aquasecurity/tracee/signatures/helpers" "github.com/aquasecurity/tracee/types/detect" "github.com/aquasecurity/tracee/types/protocol" @@ -49,7 +48,7 @@ func (sig *e2eSuspiciousSyscallSource) OnEvent(event protocol.Event) error { switch eventObj.EventName { case "suspicious_syscall_source": - syscall, err := helpers.ArgVal[int32](eventObj.Args, "syscall") + syscall, err := helpers.ArgVal[string](eventObj.Args, "syscall") if err != nil { return err } @@ -60,7 +59,7 @@ func (sig *e2eSuspiciousSyscallSource) OnEvent(event protocol.Event) error { // check expected values from test for detection - if syscall != int32(events.Exit) { + if syscall != "exit" { return nil }