diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-06 15:50:50 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-06 15:50:50 +0200 |
| commit | 58825fb53b900aedd3b161ff0e3b769a2cf188ab (patch) | |
| tree | 2b805fabfba124cb794006f1b4b16ed05f5e7da0 | |
| parent | 99b02bf8c389a793df5d5986db05eed7e459f7b1 (diff) | |
fix: return errors for invalid event filters (task 382)
| -rw-r--r-- | internal/bench_components_test.go | 25 | ||||
| -rw-r--r-- | internal/bench_pipeline_test.go | 2 | ||||
| -rw-r--r-- | internal/eventfilter.go | 10 | ||||
| -rw-r--r-- | internal/eventloop.go | 10 | ||||
| -rw-r--r-- | internal/eventloop_constructor_test.go | 41 | ||||
| -rw-r--r-- | internal/eventloop_error_handling_test.go | 6 | ||||
| -rw-r--r-- | internal/eventloop_filter_test.go | 2 | ||||
| -rw-r--r-- | internal/eventloop_test.go | 6 | ||||
| -rw-r--r-- | internal/ior.go | 5 |
9 files changed, 78 insertions, 29 deletions
diff --git a/internal/bench_components_test.go b/internal/bench_components_test.go index 1f9ccb5..54c6f2e 100644 --- a/internal/bench_components_test.go +++ b/internal/bench_components_test.go @@ -71,7 +71,7 @@ func BenchmarkDeserializeDup3Event(b *testing.B) { func BenchmarkRawHandlerLookup(b *testing.B) { b.ReportAllocs() - el := newEventLoop(eventLoopConfig{}) + el := mustNewEventLoop(b, eventLoopConfig{}) eventTypes := []types.EventType{ types.ENTER_OPEN_EVENT, types.EXIT_OPEN_EVENT, @@ -97,7 +97,7 @@ func BenchmarkTracepointEntered(b *testing.B) { gen := benchutil.NewEventGenerator() _, raw := gen.EnterOpenEvent(1, componentBenchPID, componentBenchTID) - el := newComponentBenchEventLoop(componentBenchTID) + el := newComponentBenchEventLoop(b, componentBenchTID) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -118,7 +118,7 @@ func BenchmarkTracepointExited(b *testing.B) { gen := benchutil.NewEventGenerator() _, enterRaw := gen.EnterNullEvent(1, componentBenchPID, componentBenchTID, types.SYS_ENTER_SYNC) _, exitRaw := gen.ExitNullEvent(2, componentBenchPID, componentBenchTID, types.SYS_EXIT_SYNC) - el := newComponentBenchEventLoop(componentBenchTID) + el := newComponentBenchEventLoop(b, componentBenchTID) out := make(chan *event.Pair, 1) b.ResetTimer() @@ -137,7 +137,7 @@ func BenchmarkHandleOpenExit(b *testing.B) { gen := benchutil.NewEventGenerator() enterTemplate, _ := gen.EnterOpenEvent(1, componentBenchPID, componentBenchTID) exitTemplate, _ := gen.ExitOpenEvent(2, componentBenchPID, componentBenchTID) - el := newComponentBenchEventLoop(componentBenchTID) + el := newComponentBenchEventLoop(b, componentBenchTID) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -160,7 +160,7 @@ func BenchmarkHandleFdExit(b *testing.B) { gen := benchutil.NewEventGenerator() enterTemplate, _ := gen.EnterFdEvent(1, componentBenchPID, componentBenchTID, 99, types.SYS_ENTER_READ) exitTemplate, _ := gen.ExitRetEvent(2, componentBenchPID, componentBenchTID, types.SYS_EXIT_READ, 128) - el := newComponentBenchEventLoop(componentBenchTID) + el := newComponentBenchEventLoop(b, componentBenchTID) el.fdState().set(99, file.NewFd(99, "/tmp/fd", syscall.O_RDONLY)) b.ResetTimer() @@ -184,7 +184,7 @@ func BenchmarkHandlePathExit(b *testing.B) { gen := benchutil.NewEventGenerator() enterTemplate, _ := gen.EnterPathEvent(1, componentBenchPID, componentBenchTID, "/tmp/path", types.SYS_ENTER_MKDIR) exitTemplate, _ := gen.ExitRetEvent(2, componentBenchPID, componentBenchTID, types.SYS_EXIT_MKDIR, 0) - el := newComponentBenchEventLoop(componentBenchTID) + el := newComponentBenchEventLoop(b, componentBenchTID) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -207,7 +207,7 @@ func BenchmarkHandleNameExit(b *testing.B) { gen := benchutil.NewEventGenerator() enterTemplate, _ := gen.EnterNameEvent(1, componentBenchPID, componentBenchTID, "/tmp/a", "/tmp/b", types.SYS_ENTER_RENAME) exitTemplate, _ := gen.ExitRetEvent(2, componentBenchPID, componentBenchTID, types.SYS_EXIT_RENAME, 0) - el := newComponentBenchEventLoop(componentBenchTID) + el := newComponentBenchEventLoop(b, componentBenchTID) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -230,7 +230,7 @@ func BenchmarkHandleNullExit(b *testing.B) { gen := benchutil.NewEventGenerator() enterTemplate, _ := gen.EnterNullEvent(1, componentBenchPID, componentBenchTID, types.SYS_ENTER_SYNC) exitTemplate, _ := gen.ExitNullEvent(2, componentBenchPID, componentBenchTID, types.SYS_EXIT_SYNC) - el := newComponentBenchEventLoop(componentBenchTID) + el := newComponentBenchEventLoop(b, componentBenchTID) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -253,7 +253,7 @@ func BenchmarkHandleFcntlExit(b *testing.B) { gen := benchutil.NewEventGenerator() enterTemplate, _ := gen.EnterFcntlEvent(1, componentBenchPID, componentBenchTID, 7, syscall.F_SETFL, syscall.O_NONBLOCK) exitTemplate, _ := gen.ExitRetEvent(2, componentBenchPID, componentBenchTID, types.SYS_EXIT_FCNTL, 0) - el := newComponentBenchEventLoop(componentBenchTID) + el := newComponentBenchEventLoop(b, componentBenchTID) el.fdState().set(7, file.NewFd(7, "/tmp/fcntl", syscall.O_RDONLY)) b.ResetTimer() @@ -277,7 +277,7 @@ func BenchmarkHandleDup3Exit(b *testing.B) { gen := benchutil.NewEventGenerator() enterTemplate, _ := gen.EnterDup3Event(1, componentBenchPID, componentBenchTID, 9, syscall.O_CLOEXEC) exitTemplate, _ := gen.ExitRetEvent(2, componentBenchPID, componentBenchTID, types.SYS_EXIT_DUP3, 10) - el := newComponentBenchEventLoop(componentBenchTID) + el := newComponentBenchEventLoop(b, componentBenchTID) el.fdState().set(9, file.NewFd(9, "/tmp/dup3", syscall.O_RDONLY)) b.ResetTimer() @@ -354,8 +354,9 @@ func benchmarkDeserialize[T recyclable](b *testing.B, raw []byte, decode func([] } } -func newComponentBenchEventLoop(tids ...uint32) *eventLoop { - el := newEventLoop(eventLoopConfig{}) +func newComponentBenchEventLoop(tb testing.TB, tids ...uint32) *eventLoop { + tb.Helper() + el := mustNewEventLoop(tb, eventLoopConfig{}) for _, tid := range tids { el.setCachedComm(tid, fmt.Sprintf("bench-%d", tid)) } diff --git a/internal/bench_pipeline_test.go b/internal/bench_pipeline_test.go index 822e5a2..aa48302 100644 --- a/internal/bench_pipeline_test.go +++ b/internal/bench_pipeline_test.go @@ -70,7 +70,7 @@ func benchmarkPipelineMix(b *testing.B, mix benchutil.EventMix, events, numThrea close(rawCh) var pairCount int64 - el := newEventLoop(eventLoopConfig{}) + el := mustNewEventLoop(b, eventLoopConfig{}) preseedBenchComms(el, numThreads) el.printCb = func(ep *event.Pair) { pairCount++ diff --git a/internal/eventfilter.go b/internal/eventfilter.go index 1e87fea..d49e612 100644 --- a/internal/eventfilter.go +++ b/internal/eventfilter.go @@ -15,12 +15,12 @@ type eventFilter struct { pathFilter string } -func newEventFilter(commFilter, pathFilter string) *eventFilter { +func newEventFilter(commFilter, pathFilter string) (*eventFilter, error) { var ef eventFilter if commFilter != "" { - if len(commFilter) > types.MAX_FILENAME_LENGTH { - panic(fmt.Sprintf("Comm filter's max size is %d", types.MAX_PROGNAME_LENGTH)) + if len(commFilter) > types.MAX_PROGNAME_LENGTH { + return nil, fmt.Errorf("comm filter max size is %d (got %d)", types.MAX_PROGNAME_LENGTH, len(commFilter)) } ef.commFilterEnable = true ef.commFilter = commFilter @@ -28,13 +28,13 @@ func newEventFilter(commFilter, pathFilter string) *eventFilter { if pathFilter != "" { if len(pathFilter) > types.MAX_FILENAME_LENGTH { - panic(fmt.Sprintf("Path filter's max size is %d", types.MAX_FILENAME_LENGTH)) + return nil, fmt.Errorf("path filter max size is %d (got %d)", types.MAX_FILENAME_LENGTH, len(pathFilter)) } ef.pathFilterEnable = true ef.pathFilter = pathFilter } - return &ef + return &ef, nil } func (ef *eventFilter) eventPair(ev *event.Pair) bool { diff --git a/internal/eventloop.go b/internal/eventloop.go index 6f14325..d95a441 100644 --- a/internal/eventloop.go +++ b/internal/eventloop.go @@ -181,12 +181,16 @@ type eventLoop struct { done chan struct{} } -func newEventLoop(cfg eventLoopConfig) *eventLoop { +func newEventLoop(cfg eventLoopConfig) (*eventLoop, error) { filesByFD := make(map[int32]file.File) commsByTID := make(map[uint32]string) + filter, err := newEventFilter(cfg.commFilter, cfg.pathFilter) + if err != nil { + return nil, fmt.Errorf("create event filter: %w", err) + } el := &eventLoop{ - filter: newEventFilter(cfg.commFilter, cfg.pathFilter), + filter: filter, enterEvs: make(map[uint32]*event.Pair), pendingHandles: make(map[uint32]string), files: filesByFD, @@ -203,7 +207,7 @@ func newEventLoop(cfg eventLoopConfig) *eventLoop { el.initRawHandlers() el.configureOutputCallback() el.seedTrackedPidComm() - return el + return el, nil } func (e *eventLoop) seedTrackedPidComm() { diff --git a/internal/eventloop_constructor_test.go b/internal/eventloop_constructor_test.go new file mode 100644 index 0000000..52ca570 --- /dev/null +++ b/internal/eventloop_constructor_test.go @@ -0,0 +1,41 @@ +package internal + +import ( + "strings" + "testing" + + "ior/internal/types" +) + +func mustNewEventLoop(tb testing.TB, cfg eventLoopConfig) *eventLoop { + tb.Helper() + el, err := newEventLoop(cfg) + if err != nil { + tb.Fatalf("newEventLoop() error = %v", err) + } + return el +} + +func TestNewEventFilterRejectsTooLongCommFilter(t *testing.T) { + tooLong := strings.Repeat("a", types.MAX_PROGNAME_LENGTH+1) + _, err := newEventFilter(tooLong, "") + if err == nil { + t.Fatalf("expected error for comm filter longer than %d", types.MAX_PROGNAME_LENGTH) + } +} + +func TestNewEventFilterRejectsTooLongPathFilter(t *testing.T) { + tooLong := strings.Repeat("a", types.MAX_FILENAME_LENGTH+1) + _, err := newEventFilter("", tooLong) + if err == nil { + t.Fatalf("expected error for path filter longer than %d", types.MAX_FILENAME_LENGTH) + } +} + +func TestNewEventLoopPropagatesFilterError(t *testing.T) { + tooLong := strings.Repeat("a", types.MAX_PROGNAME_LENGTH+1) + _, err := newEventLoop(eventLoopConfig{commFilter: tooLong}) + if err == nil { + t.Fatalf("expected newEventLoop to propagate invalid filter error") + } +} diff --git a/internal/eventloop_error_handling_test.go b/internal/eventloop_error_handling_test.go index 12f9b2f..8361dea 100644 --- a/internal/eventloop_error_handling_test.go +++ b/internal/eventloop_error_handling_test.go @@ -8,7 +8,7 @@ import ( ) func TestTracepointExitedMalformedOpenExitDoesNotPanicAndNotifies(t *testing.T) { - el := newEventLoop(eventLoopConfig{}) + el := mustNewEventLoop(t, eventLoopConfig{}) warnings := make(chan string, 1) el.warningCb = func(message string) { warnings <- message } @@ -48,7 +48,7 @@ func TestTracepointExitedMalformedOpenExitDoesNotPanicAndNotifies(t *testing.T) } func TestTracepointExitedMalformedOpenByHandleAtExitDoesNotPanicAndNotifies(t *testing.T) { - el := newEventLoop(eventLoopConfig{}) + el := mustNewEventLoop(t, eventLoopConfig{}) warnings := make(chan string, 1) el.warningCb = func(message string) { warnings <- message } @@ -84,7 +84,7 @@ func TestTracepointExitedMalformedOpenByHandleAtExitDoesNotPanicAndNotifies(t *t } func TestProcessRawEventUnknownTypeDoesNotPanicAndNotifies(t *testing.T) { - el := newEventLoop(eventLoopConfig{}) + el := mustNewEventLoop(t, eventLoopConfig{}) warnings := make(chan string, 1) el.warningCb = func(message string) { warnings <- message } diff --git a/internal/eventloop_filter_test.go b/internal/eventloop_filter_test.go index ddd6451..e9fa91b 100644 --- a/internal/eventloop_filter_test.go +++ b/internal/eventloop_filter_test.go @@ -21,7 +21,7 @@ func TestCommPropagation(t *testing.T) { inCh := make(chan []byte) outCh := make(chan *event.Pair) - el := newEventLoop(eventLoopConfig{}) + el := mustNewEventLoop(t, eventLoopConfig{}) el.printCb = func(ev *event.Pair) { outCh <- ev } go el.run(ctx, inCh) diff --git a/internal/eventloop_test.go b/internal/eventloop_test.go index 4ae8597..d1bcc16 100644 --- a/internal/eventloop_test.go +++ b/internal/eventloop_test.go @@ -96,7 +96,7 @@ func TestEventloop(t *testing.T) { inCh := make(chan []byte) outCh := make(chan *event.Pair) - el := newEventLoop(eventLoopConfig{}) + el := mustNewEventLoop(t, eventLoopConfig{}) el.printCb = func(ev *event.Pair) { outCh <- ev } go el.run(ctx, inCh) @@ -142,7 +142,7 @@ func TestEventloop(t *testing.T) { } func TestHandleFdExitCloseClearsProcFdCache(t *testing.T) { - el := newEventLoop(eventLoopConfig{}) + el := mustNewEventLoop(t, eventLoopConfig{}) pid := uint32(1001) fd := int32(55) @@ -170,7 +170,7 @@ func TestHandleFdExitCloseClearsProcFdCache(t *testing.T) { } func TestHandleFdExitCloseRangeClearsProcFdCacheRange(t *testing.T) { - el := newEventLoop(eventLoopConfig{}) + el := mustNewEventLoop(t, eventLoopConfig{}) pid := uint32(2002) el.setProcFdCache(10, pid, file.NewFd(10, "keep", syscall.O_RDONLY)) diff --git a/internal/ior.go b/internal/ior.go index 7c1368a..b5f9091 100644 --- a/internal/ior.go +++ b/internal/ior.go @@ -432,7 +432,10 @@ func runTraceWithContext(parentCtx context.Context, started chan<- struct{}, con signalTraceStarted(started) - el := newEventLoop(newEventLoopConfig(cfg)) + el, err := newEventLoop(newEventLoopConfig(cfg)) + if err != nil { + return err + } if configure != nil { configure(el) } |
