Skip to content

Commit

Permalink
filters: refactor to allow multiple parses
Browse files Browse the repository at this point in the history
Calling Parse will now parse the filter expression into the existing
filter instead of overriding it's previous data.

For example:
using "-t comm=ls -t comm=pwd" will not override the first ls filter,
instead combining the two.

Filters now also have a Filter method to run on userspace values.
  • Loading branch information
NDStrahilevitz committed Oct 11, 2022
1 parent 05bf6f5 commit 9e8ba73
Show file tree
Hide file tree
Showing 14 changed files with 714 additions and 322 deletions.
6 changes: 3 additions & 3 deletions cmd/tracee-ebpf/flags/capabilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ func PrepareCapsConfig(capsCfgArray []string) (CapsConfig, error) {
case CancelDropFlag:
cfg.CancelCapsDrop = true
case AddReqCapsFlag:
addedCapsFilter := filters.StringFilter{}
addedCapsFilter := filters.NewStringFilter()
err := addedCapsFilter.Parse(operatorAndValues)
if err != nil {
return cfg, err
}
if addedCapsFilter.FilterOut() {
capsFilteredOut, err := capsStringSliceToValues(addedCapsFilter.NotEqual)
capsFilteredOut, err := capsStringSliceToValues(addedCapsFilter.NotEqual())
if err != nil {
return cfg, err
}
Expand All @@ -84,7 +84,7 @@ func PrepareCapsConfig(capsCfgArray []string) (CapsConfig, error) {
}
cfg.CapsToPreserve = rcaps
} else {
cfg.CapsToPreserve, err = capsStringSliceToValues(addedCapsFilter.Equal)
cfg.CapsToPreserve, err = capsStringSliceToValues(addedCapsFilter.Equal())
if err != nil {
return cfg, err
}
Expand Down
77 changes: 44 additions & 33 deletions cmd/tracee-ebpf/flags/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Examples:
--trace pid=510,1709 | only trace events from pid 510 or pid 1709
--trace p=510 --trace p=1709 | only trace events from pid 510 or pid 1709 (same as above)
--trace container=new | only trace events from newly created containers
--trace container=ab356bc4dd554 | only trace events from container id ab356bc4dd554
--trace container_id=ab356bc4dd554 | only trace events from container id ab356bc4dd554
--trace container | only trace events from containers
--trace c | only trace events from containers (same as above)
--trace '!container' | only trace events from the host
Expand Down Expand Up @@ -111,28 +111,28 @@ func PrepareFilter(filtersArr []string) (tracee.Filter, error) {
}
}

for _, f := range filtersArr {
filterName := f
for _, filterFlag := range filtersArr {
filterName := filterFlag
operatorAndValues := ""
operatorIndex := strings.IndexAny(f, "=!<>")
operatorIndex := strings.IndexAny(filterFlag, "=!<>")
if operatorIndex > 0 {
filterName = f[0:operatorIndex]
operatorAndValues = f[operatorIndex:]
filterName = filterFlag[0:operatorIndex]
operatorAndValues = filterFlag[operatorIndex:]
}

if len(operatorAndValues) == 1 || operatorAndValues == "!=" || operatorAndValues == "<=" || operatorAndValues == ">=" {
return tracee.Filter{}, filters.InvalidExpression(f)
return tracee.Filter{}, filters.InvalidExpression(filterFlag)
}

if strings.Contains(f, ".retval") {
if strings.Contains(filterFlag, ".retval") {
err := filter.RetFilter.Parse(filterName, operatorAndValues, eventsNameToID)
if err != nil {
return tracee.Filter{}, err
}
continue
}

if strings.Contains(f, ".") {
if strings.Contains(filterFlag, ".") {
err := filter.ArgFilter.Parse(filterName, operatorAndValues, eventsNameToID)
if err != nil {
return tracee.Filter{}, err
Expand All @@ -151,28 +151,41 @@ func PrepareFilter(filtersArr []string) (tracee.Filter, error) {
continue
}

if strings.HasPrefix("container", f) || (strings.HasPrefix("!container", f) && len(f) > 1) {
err := filter.ContFilter.Parse(f)
if err != nil {
return tracee.Filter{}, err
}
continue
}

if strings.HasPrefix("container", filterName) {
if operatorAndValues == "=new" {
filter.NewContFilter.Enable()
filter.NewContFilter.Value = true
err := filter.NewContFilter.Parse("new")
if err != nil {
return tracee.Filter{}, err
}
continue
}
if operatorAndValues == "!=new" {
filter.ContFilter.Enable()
filter.ContFilter.Value = true
filter.NewContFilter.Enable()
filter.NewContFilter.Value = false
err := filter.ContFilter.Parse(filterName)
if err != nil {
return tracee.Filter{}, err
}
err = filter.NewContFilter.Parse("!new")
if err != nil {
return tracee.Filter{}, err
}
continue
}
err := filter.ContIDFilter.Parse(operatorAndValues)
if strings.Contains(operatorAndValues, "=") {
err := filter.ContIDFilter.Parse(operatorAndValues)
if err != nil {
return tracee.Filter{}, err
}
continue
}
err := filter.ContFilter.Parse(filterName)
if err != nil {
return tracee.Filter{}, err
}
continue
}

if strings.HasPrefix("!container", filterName) {
err := filter.ContFilter.Parse(filterName)
if err != nil {
return tracee.Filter{}, err
}
Expand Down Expand Up @@ -221,13 +234,11 @@ func PrepareFilter(filtersArr []string) (tracee.Filter, error) {

if strings.HasPrefix("pid", filterName) {
if operatorAndValues == "=new" {
filter.NewPidFilter.Enable()
filter.NewPidFilter.Value = true
filter.NewPidFilter.Parse("new")
continue
}
if operatorAndValues == "!=new" {
filter.NewPidFilter.Enable()
filter.NewPidFilter.Value = false
filter.NewPidFilter.Parse("!new")
continue
}
err := filter.PIDFilter.Parse(operatorAndValues)
Expand Down Expand Up @@ -261,11 +272,11 @@ func PrepareFilter(filtersArr []string) (tracee.Filter, error) {
continue
}

if strings.HasPrefix("follow", f) {
if strings.HasPrefix("follow", filterFlag) {
filter.Follow = true
continue
}
return tracee.Filter{}, InvalidFilterOptionError(f)
return tracee.Filter{}, InvalidFilterOptionError(filterFlag)
}

var err error
Expand All @@ -279,9 +290,9 @@ func PrepareFilter(filtersArr []string) (tracee.Filter, error) {

func prepareEventsToTrace(eventFilter *filters.StringFilter, setFilter *filters.StringFilter, eventsNameToID map[string]events.ID) ([]events.ID, error) {
eventFilter.Enable()
eventsToTrace := eventFilter.Equal
excludeEvents := eventFilter.NotEqual
setsToTrace := setFilter.Equal
eventsToTrace := eventFilter.Equal()
excludeEvents := eventFilter.NotEqual()
setsToTrace := setFilter.Equal()

var res []events.ID
setsToEvents := make(map[string][]events.ID)
Expand Down
4 changes: 2 additions & 2 deletions cmd/tracee-ebpf/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ func main() {
}
cfg.Filter = &filter

containerMode := (cfg.Filter.ContFilter.Enabled() && cfg.Filter.ContFilter.Value) ||
(cfg.Filter.NewContFilter.Enabled() && cfg.Filter.NewContFilter.Value) ||
containerMode := (cfg.Filter.ContFilter.Enabled() && cfg.Filter.ContFilter.Value()) ||
(cfg.Filter.NewContFilter.Enabled() && cfg.Filter.NewContFilter.Value()) ||
cfg.Filter.ContIDFilter.Enabled()

outputSlice := c.StringSlice("output")
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 @@ -249,7 +249,7 @@ func (t *Tracee) processEvents(ctx context.Context, in <-chan *trace.Event) (<-c
continue
}

if (t.config.Filter.ContFilter.Value || t.config.Filter.NewContFilter.Enabled()) && event.ContainerID == "" {
if (t.config.Filter.ContFilter.Value() || t.config.Filter.NewContFilter.Enabled()) && event.ContainerID == "" {
// Don't trace false container positives -
// a container filter is set by the user, but this event wasn't originated in a container.
// Although kernel filters shouldn't submit such events, we do this check to be on the safe side.
Expand Down
33 changes: 11 additions & 22 deletions pkg/ebpf/tracee.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,6 @@ func (tc Config) Validate() error {
}
}
}
for eventID, eventFilters := range tc.Filter.ArgFilter.Filters {
for argName := range eventFilters {
eventDefinition, ok := events.Definitions.GetSafe(eventID)
if !ok {
return fmt.Errorf("invalid argument filter event id: %d", eventID)
}
eventParams := eventDefinition.Params
// check if argument name exists for this event
argFound := false
for i := range eventParams {
if eventParams[i].Name == argName {
argFound = true
break
}
}
if !argFound {
return fmt.Errorf("invalid argument filter argument name: %s", argName)
}
}
}
if (tc.PerfBufferSize & (tc.PerfBufferSize - 1)) != 0 {
return fmt.Errorf("invalid perf buffer size - must be a power of 2")
}
Expand Down Expand Up @@ -524,6 +504,15 @@ func (t *Tracee) initDerivationTable() error {
pathResolver := containers.InitPathResolver(&t.pidsInMntns)
soLoader := sharedobjs.InitContainersSymbolsLoader(&pathResolver, 1024)

symbolsLoadedFilter := t.config.Filter.ArgFilter.GetEventFilters(events.SymbolsLoaded)
watchedSymbols := []string{}
whitelistedLibs := []string{}

if symbolsLoadedFilter != nil {
watchedSymbols = symbolsLoadedFilter["symbols"].Equal()
whitelistedLibs = symbolsLoadedFilter["library_path"].NotEqual()
}

t.eventDerivations = derive.Table{
events.CgroupMkdir: {
events.ContainerCreate: {
Expand Down Expand Up @@ -566,8 +555,8 @@ func (t *Tracee) initDerivationTable() error {
Enabled: t.events[events.SymbolsLoaded].submit,
DeriveFunction: derive.SymbolsLoaded(
soLoader,
t.config.Filter.ArgFilter.Filters[events.SymbolsLoaded]["symbols"].Equal,
t.config.Filter.ArgFilter.Filters[events.SymbolsLoaded]["library_path"].NotEqual,
watchedSymbols,
whitelistedLibs,
t.config.Debug,
),
},
Expand Down
Loading

0 comments on commit 9e8ba73

Please sign in to comment.