summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/eventloop_test.go31
-rw-r--r--internal/generate/classify_test.go27
2 files changed, 58 insertions, 0 deletions
diff --git a/internal/eventloop_test.go b/internal/eventloop_test.go
index 98d7696..3d256be 100644
--- a/internal/eventloop_test.go
+++ b/internal/eventloop_test.go
@@ -66,6 +66,7 @@ func TestEventloop(t *testing.T) {
// NullEvent tests
"SyncEventTest": makeSyncEventTestData(t),
"GetcwdEventTest": makeGetcwdEventTestData(t),
+ "GetcwdFailureEventTest": makeGetcwdFailureEventTestData(t),
"IoUringSetupEventTest": makeIoUringSetupEventTestData(t),
"IoUringSetupFailureTest": makeIoUringSetupFailureTestData(t),
"IoUringEnterEventTest": makeIoUringEnterEventTestData(t),
@@ -1589,6 +1590,9 @@ func makeGetcwdEventTestData(t *testing.T) (td testData) {
if !exitEv.Equals(ep.ExitEv) {
t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
}
+ // getcwd args[0] (buf) is an OUTPUT buffer that is only valid at exit,
+ // so the path is never read at enter. Instead it is resolved at exit
+ // from /proc/<tid>/cwd, which must equal the process cwd here.
if ep.File == nil {
t.Fatalf("Expected getcwd to attach a pathname")
}
@@ -1600,6 +1604,33 @@ func makeGetcwdEventTestData(t *testing.T) (td testData) {
return td
}
+// makeGetcwdFailureEventTestData locks in that a failed getcwd (negative
+// errno return) does NOT resolve or attach a cwd path. The exit handler only
+// reads /proc/<tid>/cwd when ret > 0 (success returns the path length); on
+// error there is nothing to attach.
+func makeGetcwdFailureEventTestData(t *testing.T) (td testData) {
+ enterEv, enterEvBytes := makeEnterNullEvent(t, defaulTime, defaultPid, defaultTid, types.SYS_ENTER_GETCWD)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ // ERANGE: buffer too small. Raw syscall reports it as a negative errno.
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_GETCWD, -int64(syscall.ERANGE))
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, _ *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ if ep.File != nil {
+ t.Errorf("Expected no cwd attached on getcwd failure, got '%v'", ep.File.Name())
+ }
+ })
+
+ return td
+}
+
func makeIoUringSetupEventTestData(t *testing.T) (td testData) {
enterEv, enterEvBytes := makeEnterNullEvent(t, defaulTime, defaultPid, defaultTid, types.SYS_ENTER_IO_URING_SETUP)
td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go
index 06cf1d7..4efdaee 100644
--- a/internal/generate/classify_test.go
+++ b/internal/generate/classify_test.go
@@ -214,11 +214,38 @@ func TestClassifyNullSyslog(t *testing.T) {
}
}
+// TestClassifyNullGetcwd pins getcwd as KindNull at enter.
+//
+// getcwd's args[0] is `char *buf`, an OUTPUT buffer: the kernel writes the
+// absolute cwd path into it and the contents only become valid AFTER the
+// syscall returns (sys_exit). Reading buf at enter would capture an empty or
+// garbage string, so getcwd must NOT be classified as a path-input syscall.
+// KindNull is the correct enter kind; the cwd is resolved at exit from
+// /proc/<tid>/cwd (see eventLoop.handleNullExit). This test locks that in:
+// - the enter kind is KindNull (not KindPathname/KindName), and
+// - no pathname field is captured from the buffer at enter.
func TestClassifyNullGetcwd(t *testing.T) {
r := classifyFromData(t, FormatGetcwd)
if r.Kind != KindNull {
t.Errorf("getcwd: got kind %d, want KindNull", r.Kind)
}
+ if r.Kind == KindPathname || r.Kind == KindName {
+ t.Errorf("getcwd: enter must not capture output buf as a path, got kind %d", r.Kind)
+ }
+ if r.PathnameField != "" {
+ t.Errorf("getcwd: no enter-time pathname field expected, got %q", r.PathnameField)
+ }
+}
+
+// TestClassifyByFieldGetcwdBufNotPath is a defense-in-depth lock-in: even if
+// the name-only KindNull override for getcwd were removed, the generic
+// field-based classifier must not treat `char *buf` as a pathname. Only the
+// field names pathname/path/filename/newname are path-like; "buf" is not, so
+// classifyByField must report no match for getcwd's output buffer.
+func TestClassifyByFieldGetcwdBufNotPath(t *testing.T) {
+ if r, ok := classifyByField("char *", "buf"); ok {
+ t.Errorf("getcwd buf: char *buf must not classify as a field kind, got %d", r.Kind)
+ }
}
func TestClassifyNullIoUring(t *testing.T) {