Skip to content

Commit

Permalink
chore: rename args to data field
Browse files Browse the repository at this point in the history
Refactored the code in order to change the option args to name to be
consistent with the new event structure. Option args is also supported
but will be deprecated in future.
  • Loading branch information
rscampos committed May 28, 2024
1 parent e633860 commit f07388c
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 90 deletions.
2 changes: 1 addition & 1 deletion cmd/tracee/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func initCmd() error {
"events",
"e",
[]string{},
"[name|name.args.pathname...]\tSelect events to trace and event filters",
"[name|name.data.pathname...]\tSelect events to trace and event filters",
)

// policy is not bound to viper
Expand Down
8 changes: 4 additions & 4 deletions pkg/cmd/flags/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,15 @@ func parseEventFlag(flag string) ([]eventFlag, error) {

return []eventFlag{
{
full: flag, // "openat.args.pathname=/etc/*"
eventFilter: evtFilter, // "openat.args.pathname"
full: flag, // "openat.data.pathname=/etc/*"
eventFilter: evtFilter, // "openat.data.pathname"
eventName: evtParts.name, // "openat"
eventOptionType: evtParts.optType, // "args"
eventOptionType: evtParts.optType, // "data"
eventOptionName: evtParts.optName, // "pathname"
operator: opAndValParts.operator, // "="
values: opAndValParts.values, // "/etc/*"
operatorAndValues: opAndValParts.operatorAndValues, // "=/etc/*"
filter: filter, // "args.pathname=/etc/*"
filter: filter, // "data.pathname=/etc/*"
},
}, nil
}
Expand Down
12 changes: 6 additions & 6 deletions pkg/cmd/flags/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ Available boolean expressions: container.
Event flag selects events or sets of events to trace according to predefined sets, which can be listed by using the 'list' flag.
Event flag uses a dash prefix to filter out events: '-'.
Event arguments can be accessed using 'event_name.args.event_arg' and provide a way to filter an event by its arguments.
Event arguments allow the following operators: '=', '!='.
Event data can be accessed using 'event_name.data.event_arg' and provide a way to filter an event by its data.
Event data allow the following operators: '=', '!='.
Strings can be compared as a prefix if ending with '*' or as suffix if starting with '*'.
Event return value can be accessed using 'event_name.retval' and provide a way to filter an event by its return value.
Expand Down Expand Up @@ -77,10 +77,10 @@ Event examples:
--events '-open*,-dup*' | don't trace events prefixed by "open" or "dup"
--events fs | trace all file-system related events
--events fs --events -open,-openat | trace all file-system related events, but not open(at)
--events close.args.fd=5 | only trace 'close' events that have 'fd' equals 5
--events openat.args.pathname='/tmp*' | only trace 'openat' events that have 'pathname' prefixed by /tmp
--events openat.args.pathname='*shadow' | only trace 'openat' events that have 'pathname' suffixed by shadow
--events openat.args.pathname!=/tmp/1,/bin/ls | don't trace 'openat' events that have 'pathname' equals /tmp/1 or /bin/ls
--events close.data.fd=5 | only trace 'close' events that have 'fd' equals 5
--events openat.data.pathname='/tmp*' | only trace 'openat' events that have 'pathname' prefixed by /tmp
--events openat.data.pathname='*shadow' | only trace 'openat' events that have 'pathname' suffixed by shadow
--events openat.data.pathname!=/tmp/1,/bin/ls | don't trace 'openat' events that have 'pathname' equals /tmp/1 or /bin/ls
--events openat.scope.processName=ls | only trace 'openat' events that have 'processName' equal to 'ls'
--events security_file_open.scope.container | only trace 'security_file_open' events coming from a container
Expand Down
10 changes: 6 additions & 4 deletions pkg/cmd/flags/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ func PrepareFilterMapsFromPolicies(policies []k8s.PolicyInterface) (PolicyScopeM
eventFlags = append(eventFlags, evtFlags...)

for _, f := range r.Filters {
// event argument or return value filter
if strings.HasPrefix(f, "args.") || strings.HasPrefix(f, "retval") {
// event data or return value filter
// option "args." will be deprecate in future
if strings.HasPrefix(f, "data.") || strings.HasPrefix(f, "args.") ||
strings.HasPrefix(f, "retval") {
evtFilterFlags, err := parseEventFlag(fmt.Sprintf("%s.%s", r.Event, f))
if err != nil {
return nil, nil, errfmt.WrapError(err)
Expand Down Expand Up @@ -297,8 +299,8 @@ func CreatePolicies(policyScopeMap PolicyScopeMap, policyEventsMap PolicyEventMa
continue
}

if evtFlag.eventOptionType == "args" {
err := p.ArgFilter.Parse(evtFilter, operatorAndValues, eventsNameToID)
if evtFlag.eventOptionType == "data" || evtFlag.eventOptionType == "args" {
err := p.DataFilter.Parse(evtFilter, operatorAndValues, eventsNameToID)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/ebpf/events_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func (t *Tracee) matchPolicies(event *trace.Event) uint64 {
}

// 3. event arguments filters
if !p.ArgFilter.Filter(eventID, event.Args) {
if !p.DataFilter.Filter(eventID, event.Args) {
utils.ClearBit(&bitmap, bitOffset)
continue
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/ebpf/tracee.go
Original file line number Diff line number Diff line change
Expand Up @@ -1620,12 +1620,12 @@ func (t *Tracee) triggerMemDump(event trace.Event) []error {
if !isChosen {
continue
}
printMemDumpFilters := p.ArgFilter.GetEventFilters(events.PrintMemDump)
printMemDumpFilters := p.DataFilter.GetEventFilters(events.PrintMemDump)
if len(printMemDumpFilters) == 0 {
errs = append(errs, errfmt.Errorf("policy %d: no address or symbols were provided to print_mem_dump event. "+
"please provide it via -e print_mem_dump.args.address=<hex address>"+
", -e print_mem_dump.args.symbol_name=<owner>:<symbol> or "+
"-e print_mem_dump.args.symbol_name=<symbol> if specifying a system owned symbol", p.ID))
"please provide it via -e print_mem_dump.data.address=<hex address>"+
", -e print_mem_dump.data.symbol_name=<owner>:<symbol> or "+
"-e print_mem_dump.data.symbol_name=<symbol> if specifying a system owned symbol", p.ID))

continue
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/events/derive/symbols_collision.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func SymbolsCollision(soLoader sharedobjs.DynamicSymbolsLoader, policies *policy
// pick white and black lists from the filters (TODO: change this)
for it := policies.CreateAllIterator(); it.HasNext(); {
p := it.Next()
f := p.ArgFilter.GetEventFilters(events.SymbolsCollision)
f := p.DataFilter.GetEventFilters(events.SymbolsCollision)
maps.Copy(symbolsCollisionFilters, f)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/events/derive/symbols_loaded.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func SymbolsLoaded(

for it := policies.CreateAllIterator(); it.HasNext(); {
p := it.Next()
f := p.ArgFilter.GetEventFilters(events.SymbolsLoaded)
f := p.DataFilter.GetEventFilters(events.SymbolsLoaded)
maps.Copy(symbolsLoadedFilters, f)
}

Expand Down
101 changes: 51 additions & 50 deletions pkg/filters/args.go → pkg/filters/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,28 @@ import (
"github.com/aquasecurity/tracee/types/trace"
)

type ArgFilter struct {
type DataFilter struct {
filters map[events.ID]map[string]Filter[*StringFilter]
enabled bool
}

// Compile-time check to ensure that ArgFilter implements the Cloner interface
var _ utils.Cloner[*ArgFilter] = &ArgFilter{}
// Compile-time check to ensure that DataFilter implements the Cloner interface
var _ utils.Cloner[*DataFilter] = &DataFilter{}

func NewArgFilter() *ArgFilter {
return &ArgFilter{
func NewDataFilter() *DataFilter {
return &DataFilter{
filters: map[events.ID]map[string]Filter[*StringFilter]{},
enabled: false,
}
}

// GetEventFilters returns the argument filters map for a specific event
// GetEventFilters returns the data filters map for a specific event
// writing to the map may have unintentional consequences, avoid doing so
func (af *ArgFilter) GetEventFilters(eventID events.ID) map[string]Filter[*StringFilter] {
func (af *DataFilter) GetEventFilters(eventID events.ID) map[string]Filter[*StringFilter] {
return af.filters[eventID]
}

func (af *ArgFilter) Filter(eventID events.ID, args []trace.Argument) bool {
func (af *DataFilter) Filter(eventID events.ID, data []trace.Argument) bool {
if !af.Enabled() {
return true
}
Expand All @@ -46,14 +46,14 @@ func (af *ArgFilter) Filter(eventID events.ID, args []trace.Argument) bool {
return true
}

for argName, f := range af.filters[eventID] {
for dataName, f := range af.filters[eventID] {
found := false
var argVal interface{}
var dataVal interface{}

for _, arg := range args {
if arg.Name == argName {
for _, d := range data {
if d.Name == dataName {
found = true
argVal = arg.Value
dataVal = d.Value
break
}
}
Expand All @@ -62,9 +62,9 @@ func (af *ArgFilter) Filter(eventID events.ID, args []trace.Argument) bool {
}

// TODO: use type assertion instead of string conversion
argVal = fmt.Sprint(argVal)
dataVal = fmt.Sprint(dataVal)

res := f.Filter(argVal)
res := f.Filter(dataVal)
if !res {
return false
}
Expand All @@ -73,21 +73,22 @@ func (af *ArgFilter) Filter(eventID events.ID, args []trace.Argument) bool {
return true
}

func (af *ArgFilter) Parse(filterName string, operatorAndValues string, eventsNameToID map[string]events.ID) error {
// Event argument filter has the following format: "event.args.argname=argval"
// filterName have the format event.argname, and operatorAndValues have the format "=argval"
func (af *DataFilter) Parse(filterName string, operatorAndValues string, eventsNameToID map[string]events.ID) error {
// Event data filter has the following format: "event.data.dataname=dataval"
// filterName have the format event.dataname, and operatorAndValues have the format "=dataval"
parts := strings.Split(filterName, ".")
if len(parts) != 3 {
return InvalidExpression(filterName + operatorAndValues)
}
if parts[1] != "args" {
// option "args" will be deprecate in future
if (parts[1] != "data") && (parts[1] != "args") {
return InvalidExpression(filterName + operatorAndValues)
}

eventName := parts[0]
argName := parts[2]
dataName := parts[2]

if eventName == "" || argName == "" {
if eventName == "" || dataName == "" {
return InvalidExpression(filterName + operatorAndValues)
}

Expand All @@ -102,18 +103,18 @@ func (af *ArgFilter) Parse(filterName string, operatorAndValues string, eventsNa
eventDefinition := events.Core.GetDefinitionByID(id)
eventParams := eventDefinition.GetParams()

// check if argument name exists for this event
argFound := false
// check if data name exists for this event
dataFound := false
for i := range eventParams {
if eventParams[i].Name == argName {
argFound = true
if eventParams[i].Name == dataName {
dataFound = true
break
}
}

// if the event is a signature event, we allow filtering on dynamic argument
if !argFound && !eventDefinition.IsSignature() {
return InvalidEventArgument(argName)
if !dataFound && !eventDefinition.IsSignature() {
return InvalidEventData(dataName)
}

// valueHandler is passed to the filter constructor to allow for custom value handling
Expand All @@ -122,7 +123,7 @@ func (af *ArgFilter) Parse(filterName string, operatorAndValues string, eventsNa
switch id {
case events.SysEnter,
events.SysExit:
if argName == "syscall" { // handle either syscall name or syscall id
if dataName == "syscall" { // handle either syscall name or syscall id
_, err := strconv.Atoi(val)
if err != nil {
// if val is a syscall name, then we need to convert it to a syscall id
Expand All @@ -134,21 +135,21 @@ func (af *ArgFilter) Parse(filterName string, operatorAndValues string, eventsNa
}
}
case events.HookedSyscall:
if argName == "syscall" { // handle either syscall name or syscall id
argEventID, err := strconv.Atoi(val)
if dataName == "syscall" { // handle either syscall name or syscall id
dataEventID, err := strconv.Atoi(val)
if err == nil {
// if val is a syscall id, then we need to convert it to a syscall name
val = events.Core.GetDefinitionByID(events.ID(argEventID)).GetName()
val = events.Core.GetDefinitionByID(events.ID(dataEventID)).GetName()
}
}
}

return val, nil
}

err := af.parseFilter(id, argName, operatorAndValues,
err := af.parseFilter(id, dataName, operatorAndValues,
func() Filter[*StringFilter] {
// TODO: map argument type to an appropriate filter constructor
// TODO: map data type to an appropriate filter constructor
return NewStringFilter(valueHandler)
})
if err != nil {
Expand All @@ -160,33 +161,33 @@ func (af *ArgFilter) Parse(filterName string, operatorAndValues string, eventsNa
return nil
}

// parseFilter adds an argument filter with the relevant filterConstructor
// parseFilter adds an data filter with the relevant filterConstructor
// The user must responsibly supply a reliable Filter object.
func (af *ArgFilter) parseFilter(id events.ID, argName string, operatorAndValues string, filterConstructor func() Filter[*StringFilter]) error {
func (af *DataFilter) parseFilter(id events.ID, dataName string, operatorAndValues string, filterConstructor func() Filter[*StringFilter]) error {
if _, ok := af.filters[id]; !ok {
af.filters[id] = map[string]Filter[*StringFilter]{}
}

if _, ok := af.filters[id][argName]; !ok {
// store new event arg filter if missing
argFilter := filterConstructor()
af.filters[id][argName] = argFilter
if _, ok := af.filters[id][dataName]; !ok {
// store new event data filter if missing
dataFilter := filterConstructor()
af.filters[id][dataName] = dataFilter
}

// extract the arg filter and parse expression into it
f := af.filters[id][argName]
// extract the data filter and parse expression into it
f := af.filters[id][dataName]
err := f.Parse(operatorAndValues)
if err != nil {
return errfmt.WrapError(err)
}

// store the arg filter again
af.filters[id][argName] = f
// store the data filter again
af.filters[id][dataName] = f

return nil
}

func (af *ArgFilter) Enable() {
func (af *DataFilter) Enable() {
af.enabled = true
for _, filterMap := range af.filters {
for _, f := range filterMap {
Expand All @@ -195,7 +196,7 @@ func (af *ArgFilter) Enable() {
}
}

func (af *ArgFilter) Disable() {
func (af *DataFilter) Disable() {
af.enabled = false
for _, filterMap := range af.filters {
for _, f := range filterMap {
Expand All @@ -204,21 +205,21 @@ func (af *ArgFilter) Disable() {
}
}

func (af *ArgFilter) Enabled() bool {
func (af *DataFilter) Enabled() bool {
return af.enabled
}

func (af *ArgFilter) Clone() *ArgFilter {
func (af *DataFilter) Clone() *DataFilter {
if af == nil {
return nil
}

n := NewArgFilter()
n := NewDataFilter()

for eventID, filterMap := range af.filters {
n.filters[eventID] = map[string]Filter[*StringFilter]{}
for argName, f := range filterMap {
n.filters[eventID][argName] = f.Clone()
for dataName, f := range filterMap {
n.filters[eventID][dataName] = f.Clone()
}
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/filters/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ func InvalidEventName(event string) error {
return fmt.Errorf("invalid event name in filter: %s", event)
}

func InvalidEventArgument(argument string) error {
return fmt.Errorf("invalid filter event argument: %s", argument)
func InvalidEventData(data string) error {
return fmt.Errorf("invalid filter event data: %s", data)
}

func InvalidScopeField(field string) error {
Expand Down
2 changes: 1 addition & 1 deletion pkg/policy/policies_compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (ps *Policies) updateUserlandPolicies() {
continue
}

if p.ArgFilter.Enabled() ||
if p.DataFilter.Enabled() ||
p.RetFilter.Enabled() ||
p.ScopeFilter.Enabled() ||
(p.UIDFilter.Enabled() && ps.uidFilterableInUserland) ||
Expand Down
Loading

0 comments on commit f07388c

Please sign in to comment.