diff --git a/bpf/process/bpf_execve_event.c b/bpf/process/bpf_execve_event.c index a2484ff0221..b68f9bbcfb4 100644 --- a/bpf/process/bpf_execve_event.c +++ b/bpf/process/bpf_execve_event.c @@ -270,6 +270,9 @@ execve_send(void *ctx) { struct msg_execve_event *event; struct execve_map_value *curr; +#ifdef __LARGE_BPF_PROG + struct execve_heap *heap; +#endif struct msg_process *p; __u32 zero = 0; uint64_t size; @@ -329,10 +332,19 @@ execve_send(void *ctx) memset(&curr->bin, 0, sizeof(curr->bin)); #ifdef __LARGE_BPF_PROG // read from proc exe stored at execve time - if (event->exe.len <= BINARY_PATH_MAX_LEN) { + if (event->exe.len <= BINARY_PATH_MAX_LEN && !event->exe.error) { curr->bin.path_length = probe_read(curr->bin.path, event->exe.len, event->exe.off); if (curr->bin.path_length == 0) curr->bin.path_length = event->exe.len; + } else { + heap = map_lookup_elem(&execve_heap, &zero); + if (heap) { + curr->bin.path_length = probe_read_str(curr->bin.path, BINARY_PATH_MAX_LEN, &heap->maxpath); + if (curr->bin.path_length > 1) { + // don't include the NULL byte in the length + curr->bin.path_length--; + } + } } #else // reuse p->args first string that contains the filename, this can't be diff --git a/pkg/sensors/tracing/kprobe_test.go b/pkg/sensors/tracing/kprobe_test.go index 5ecc0d2902b..a7fc37004d4 100644 --- a/pkg/sensors/tracing/kprobe_test.go +++ b/pkg/sensors/tracing/kprobe_test.go @@ -3886,6 +3886,48 @@ func TestKprobeMatchBinaries(t *testing.T) { }) } +func TestKprobeMatchBinariesPrefixLargePath(t *testing.T) { + if !kernels.EnableLargeProgs() { + t.Skip() + } + repoBinPath := testutils.RepoRootPath("contrib/tester-progs/nop") + tmpDir := t.TempDir() + + tmpDirLarge := tmpDir + "/" + strings.Repeat("a", 250) + err := os.Mkdir(tmpDirLarge, 0755) + assert.NoError(t, err) + + tmpBinaryPath := tmpDirLarge + "/nop" + + err = exec.Command("cp", repoBinPath, tmpBinaryPath).Run() + assert.NoError(t, err) + + var doneWG, readyWG sync.WaitGroup + defer doneWG.Wait() + + ctx, cancel := context.WithTimeout(context.Background(), tus.Conf().CmdWaitTime) + defer cancel() + + createCrdFile(t, getMatchBinariesCrd("Prefix", []string{tmpDir})) + + obs, err := observertesthelper.GetDefaultObserverWithFile(t, ctx, testConfigFile, tus.Conf().TetragonLib, observertesthelper.WithMyPid()) + if err != nil { + t.Fatalf("GetDefaultObserverWithFile error: %s", err) + } + observertesthelper.LoopEvents(ctx, t, &doneWG, &readyWG, obs) + readyWG.Wait() + + if err := exec.Command(tmpBinaryPath).Run(); err != nil { + t.Fatalf("failed to run nop: %s", err) + } + + checker := ec.NewUnorderedEventChecker(ec.NewProcessKprobeChecker(""). + WithProcess(ec.NewProcessChecker().WithBinary(sm.Full(tmpBinaryPath))). + WithFunctionName(sm.Full("fd_install"))) + err = jsonchecker.JsonTestCheck(t, checker) + assert.NoError(t, err) +} + // matchBinariesPerfringTest checks that the matchBinaries do correctly // filter the events i.e. it checks that no other events appear. func matchBinariesPerfringTest(t *testing.T, operator string, values []string) {