summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-06 15:50:50 +0200
committerPaul Buetow <paul@buetow.org>2026-03-06 15:50:50 +0200
commit58825fb53b900aedd3b161ff0e3b769a2cf188ab (patch)
tree2b805fabfba124cb794006f1b4b16ed05f5e7da0 /internal
parent99b02bf8c389a793df5d5986db05eed7e459f7b1 (diff)
fix: return errors for invalid event filters (task 382)
Diffstat (limited to 'internal')
-rw-r--r--internal/bench_components_test.go25
-rw-r--r--internal/bench_pipeline_test.go2
-rw-r--r--internal/eventfilter.go10
-rw-r--r--internal/eventloop.go10
-rw-r--r--internal/eventloop_constructor_test.go41
-rw-r--r--internal/eventloop_error_handling_test.go6
-rw-r--r--internal/eventloop_filter_test.go2
-rw-r--r--internal/eventloop_test.go6
-rw-r--r--internal/ior.go5
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)
}