Skip to content

Commit

Permalink
tetragon: Add support for tail calls in retkprobe probe
Browse files Browse the repository at this point in the history
Add separate generic_output code into separate tail call,
as a preparation for return kprobe filtering coming in
following changes.

Signed-off-by: Jiri Olsa <[email protected]>
  • Loading branch information
olsajiri committed Sep 4, 2023
1 parent cc75495 commit fb8e379
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 22 deletions.
33 changes: 19 additions & 14 deletions bpf/process/bpf_generic_retkprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

#include "vmlinux.h"
#include "api.h"
#include "bpf_tracing.h"

#define GENERIC_KRETPROBE

#include "bpf_tracing.h"
#include "bpf_event.h"
#include "bpf_task.h"
#include "retprobe_map.h"
Expand All @@ -21,6 +23,13 @@ struct {
__type(value, struct msg_generic_kprobe);
} process_call_heap SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
__uint(max_entries, 1);
__uint(key_size, sizeof(__u32));
__uint(value_size, sizeof(__u32));
} retkprobe_calls SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 1);
Expand Down Expand Up @@ -56,7 +65,6 @@ BPF_KRETPROBE(generic_retkprobe_event, unsigned long ret)
bool walker = false;
int zero = 0;
__u32 ppid;
long total = 0;
long size = 0;
long ty_arg, do_copy;
__u64 pid_tgid;
Expand Down Expand Up @@ -139,17 +147,14 @@ BPF_KRETPROBE(generic_retkprobe_event, unsigned long ret)
e->current.pad[3] = 0;

e->func_id = config->func_id;
e->common.size = size;

total = size;
total += generic_kprobe_common_size();
/* Code movement from clang forces us to inline bounds checks here */
asm volatile("%[total] &= 0x7fff;\n"
"if %[total] < 9000 goto +1\n;"
"%[total] = 9000;\n"
:
: [total] "+r"(total)
:);
e->common.size = total;
perf_event_output(ctx, &tcpmon_map, BPF_F_CURRENT_CPU, e, total);
return 0;
tail_call(ctx, &retkprobe_calls, 0);
return 1;
}

__attribute__((section("kprobe/0"), used)) int
BPF_KRETPROBE(generic_retkprobe_output)
{
return generic_output(ctx, (struct bpf_map_def *)&process_call_heap);
}
3 changes: 3 additions & 0 deletions bpf/process/types/basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1991,6 +1991,8 @@ generic_output(void *ctx, struct bpf_map_def *heap)
if (!e)
return 0;

/* We don't need this data in return kprobe event */
#ifndef GENERIC_KRETPROBE
#ifdef __NS_CHANGES_FILTER
/* update the namespaces if we matched a change on that */
if (e->sel.match_ns) {
Expand All @@ -2015,6 +2017,7 @@ generic_output(void *ctx, struct bpf_map_def *heap)
get_current_subj_caps(&enter->caps, task);
}
#endif
#endif // !GENERIC_KRETPROBE

total = e->common.size + generic_kprobe_common_size();
/* Code movement from clang forces us to inline bounds checks here */
Expand Down
11 changes: 9 additions & 2 deletions pkg/sensors/program/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func LoadRawTracepointProgram(bpfDir, mapDir string, load *Program, verbose int)
func LoadKprobeProgram(bpfDir, mapDir string, load *Program, verbose int) error {
var ci *customInstall
for mName, mPath := range load.PinMap {
if mName == "kprobe_calls" {
if mName == "kprobe_calls" || mName == "retkprobe_calls" {
ci = &customInstall{mPath, "kprobe"}
break
}
Expand Down Expand Up @@ -408,10 +408,17 @@ func LoadUprobeProgram(bpfDir, mapDir string, load *Program, verbose int) error
}

func LoadMultiKprobeProgram(bpfDir, mapDir string, load *Program, verbose int) error {
var ci *customInstall
for mName, mPath := range load.PinMap {
if mName == "kprobe_calls" || mName == "retkprobe_calls" {
ci = &customInstall{mPath, "kprobe"}
break
}
}
opts := &loadOpts{
attach: MultiKprobeAttach(load, bpfDir),
open: KprobeOpen(load),
ci: &customInstall{fmt.Sprintf("%s-kp_calls", load.PinPath), "kprobe"},
ci: ci,
}
return loadProgram(bpfDir, []string{mapDir}, load, opts, verbose)
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/sensors/tracing/generickprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ func createMultiKprobeSensor(sensorPath string, multiIDs, multiRetIDs []idtable.
socktrack := program.MapBuilderPin("socktrack_map", sensors.PathJoin(sensorPath, "socktrack_map"), loadret)
maps = append(maps, socktrack)

tailCalls := program.MapBuilderPin("retkprobe_calls", sensors.PathJoin(pinPath, "retprobe-kp_calls"), loadret)
maps = append(maps, tailCalls)

retConfigMap.SetMaxEntries(len(multiRetIDs))
}

Expand Down Expand Up @@ -781,6 +784,9 @@ func addKprobe(funcName string, f *v1alpha1.KProbeSpec, in *addKprobeIn) (out *a
retConfigMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "retprobe_config_map"), loadret)
out.maps = append(out.maps, retConfigMap)

tailCalls := program.MapBuilderPin("retkprobe_calls", sensors.PathJoin(pinPath, "retprobe-kp_calls"), loadret)
out.maps = append(out.maps, tailCalls)

// add maps with non-default paths (pins) to the retprobe
program.MapBuilderPin("process_call_heap", sensors.PathJoin(pinPath, "process_call_heap"), loadret)
program.MapBuilderPin("fdinstall_map", sensors.PathJoin(in.sensorPath, "fdinstall_map"), loadret)
Expand Down
17 changes: 11 additions & 6 deletions pkg/sensors/tracing/kprobe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3489,14 +3489,19 @@ func TestLoadKprobeSensor(t *testing.T) {
13: tus.SensorProg{Name: "generic_kprobe_output", Type: ebpf.Kprobe},
// retkprobe
14: tus.SensorProg{Name: "generic_retkprobe_event", Type: ebpf.Kprobe},
15: tus.SensorProg{Name: "generic_retkprobe_output", Type: ebpf.Kprobe},
}

var sensorMaps = []tus.SensorMap{
// all kprobe programs
tus.SensorMap{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}},
// all but generic_kprobe_output,generic_retkprobe_event
tus.SensorMap{Name: "process_call_heap", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},

// all but generic_kprobe_output
tus.SensorMap{Name: "kprobe_calls", Progs: []uint{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}},

// generic_retkprobe_event
tus.SensorMap{Name: "retkprobe_calls", Progs: []uint{14}},

// generic_kprobe_process_filter,generic_kprobe_filter_arg*,
// generic_kprobe_actions,generic_kprobe_output
tus.SensorMap{Name: "filter_map", Progs: []uint{6, 7, 8, 9, 10, 11, 12}},
Expand All @@ -3515,17 +3520,17 @@ func TestLoadKprobeSensor(t *testing.T) {
// shared with base sensor
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{0, 6, 7, 8, 9, 10, 11, 12, 13, 14}})

// generic_kprobe_process_event*,generic_kprobe_output,generic_retkprobe_event
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{1, 2, 3, 4, 5, 13, 14}})
// generic_kprobe_process_event*,generic_kprobe_output,generic_retkprobe_output
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{1, 2, 3, 4, 5, 13, 15}})

// generic_kprobe_process_event*,generic_kprobe_actions,retkprobe
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "socktrack_map", Progs: []uint{1, 2, 3, 4, 5, 12, 14}})
} else {
// shared with base sensor
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "execve_map", Progs: []uint{0, 6, 7, 8, 9, 10, 11, 14}})

// generic_kprobe_output,generic_retkprobe_event
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{13, 14}})
// generic_kprobe_output,generic_retkprobe_output
sensorMaps = append(sensorMaps, tus.SensorMap{Name: "tcpmon_map", Progs: []uint{13, 15}})
}

readHook := `
Expand Down

0 comments on commit fb8e379

Please sign in to comment.