Skip to content

Commit 5056c40

Browse files
committed
tetragon: Add support to use tracing program for single kprobe
Signed-off-by: Jiri Olsa <[email protected]>
1 parent 57464bf commit 5056c40

File tree

5 files changed

+140
-26
lines changed

5 files changed

+140
-26
lines changed

bpf/process/generic_calls.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,37 @@ generic_process_event_and_setup(struct pt_regs *ctx, struct bpf_map_def *tailcal
664664
retprobe_map_set(e->func_id, e->retprobe_id, e->common.ktime, 1);
665665
#endif
666666

667+
#ifdef GENERIC_FENTRY
668+
struct bpf_raw_tracepoint_args *raw_args = (struct bpf_raw_tracepoint_args *)ctx;
669+
670+
if (config->syscall) {
671+
struct pt_regs *_ctx = (struct pt_regs *) BPF_CORE_READ(raw_args, args[0]);
672+
673+
if (!_ctx)
674+
return 0;
675+
e->a0 = PT_REGS_PARM1_CORE_SYSCALL(_ctx);
676+
e->a1 = PT_REGS_PARM2_CORE_SYSCALL(_ctx);
677+
e->a2 = PT_REGS_PARM3_CORE_SYSCALL(_ctx);
678+
e->a3 = PT_REGS_PARM4_CORE_SYSCALL(_ctx);
679+
e->a4 = PT_REGS_PARM5_CORE_SYSCALL(_ctx);
680+
} else {
681+
e->a0 = BPF_CORE_READ(raw_args, args[0]);
682+
e->a1 = BPF_CORE_READ(raw_args, args[1]);
683+
e->a2 = BPF_CORE_READ(raw_args, args[2]);
684+
e->a3 = BPF_CORE_READ(raw_args, args[3]);
685+
e->a4 = BPF_CORE_READ(raw_args, args[4]);
686+
}
687+
688+
generic_process_init(e, MSG_OP_GENERIC_KPROBE, config);
689+
690+
e->retprobe_id = retprobe_map_get_key(ctx);
691+
692+
/* If return arg is needed mark retprobe */
693+
ty = config->argreturn;
694+
if (ty > 0)
695+
retprobe_map_set(e->func_id, e->retprobe_id, e->common.ktime, 1);
696+
#endif
697+
667698
#ifdef GENERIC_LSM
668699
struct bpf_raw_tracepoint_args *raw_args = (struct bpf_raw_tracepoint_args *)ctx;
669700

pkg/config/config_linux.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,19 @@ func GenericKprobeObjs(multi bool) (string, string) {
7474
return "bpf_generic_kprobe.o", "bpf_generic_retkprobe.o"
7575
}
7676

77+
func GenericTracingObjs() (string, string) {
78+
if EnableV612Progs() {
79+
return "bpf_generic_fentry_v612.o", "bpf_generic_fexit_v612.o"
80+
} else if EnableV61Progs() {
81+
return "bpf_generic_fentry_v61.o", "bpf_generic_fexit_v61.o"
82+
} else if kernels.MinKernelVersion("5.11") {
83+
return "bpf_generic_fentry_v511.o", "bpf_generic_fexit_v511.o"
84+
} else if EnableLargeProgs() {
85+
return "bpf_generic_fentry_v53.o", "bpf_generic_fexit_v53.o"
86+
}
87+
return "bpf_generic_fentry.o", "bpf_generic_fexit.o"
88+
}
89+
7790
func GenericUprobeObjs(multi bool) string {
7891
if multi {
7992
if EnableV612Progs() {

pkg/sensors/program/loader_linux.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,19 @@ func MultiUprobeAttach(load *Program, bpfDir string) AttachFunc {
378378
}
379379
}
380380

381+
func TracingOpen(load *Program) OpenFunc {
382+
return func(coll *ebpf.CollectionSpec) error {
383+
data, ok := load.AttachData.(*TracingAttachData)
384+
if !ok {
385+
return nil
386+
}
387+
for _, spec := range coll.Programs {
388+
spec.AttachTo = data.AttachTo
389+
}
390+
return nil
391+
}
392+
}
393+
381394
func TracingAttach(load *Program, bpfDir string) AttachFunc {
382395
return func(_ *ebpf.Collection, _ *ebpf.CollectionSpec,
383396
prog *ebpf.Program, spec *ebpf.ProgramSpec) (unloader.Unloader, error) {
@@ -632,6 +645,7 @@ func LoadFmodRetProgram(bpfDir string, load *Program, maps []*Map, progName stri
632645
func LoadTracingProgram(bpfDir string, load *Program, maps []*Map, verbose int) error {
633646
opts := &LoadOpts{
634647
Attach: TracingAttach(load, bpfDir),
648+
Open: TracingOpen(load),
635649
Maps: maps,
636650
}
637651
return loadProgram(bpfDir, load, opts, verbose)

pkg/sensors/program/program.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ type MapLoad struct {
7373
Load func(m *ebpf.Map, pinPathPrefix string) error
7474
}
7575

76+
type TracingAttachData struct {
77+
AttachTo string
78+
}
79+
7680
type MultiKprobeAttachData struct {
7781
Symbols []string
7882
Cookies []uint64

pkg/sensors/tracing/generickprobe.go

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -945,15 +945,42 @@ func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe
945945
pinProg = fmt.Sprintf("%s:%d", kprobeEntry.funcName, kprobeEntry.instance)
946946
}
947947

948-
load := program.Builder(
949-
path.Join(option.Config.HubbleLib, loadProgName),
950-
kprobeEntry.funcName,
951-
"kprobe/generic_kprobe",
952-
pinProg,
953-
"generic_kprobe").
954-
SetLoaderData(kprobeEntry.tableId).
955-
SetPolicy(kprobeEntry.policyName)
948+
var load *program.Program
949+
950+
if kprobeEntry.hasOverride {
951+
load = program.Builder(
952+
path.Join(option.Config.HubbleLib, loadProgName),
953+
kprobeEntry.funcName,
954+
"kprobe/generic_kprobe",
955+
pinProg,
956+
"generic_kprobe")
957+
958+
tailCalls := program.MapBuilderProgram("kprobe_calls", load)
959+
maps = append(maps, tailCalls)
960+
961+
} else {
962+
data := &program.TracingAttachData{
963+
AttachTo: kprobeEntry.funcName,
964+
}
965+
966+
loadProgName, loadProgRetName = config.GenericTracingObjs()
967+
968+
load = program.Builder(
969+
path.Join(option.Config.HubbleLib, loadProgName),
970+
kprobeEntry.funcName,
971+
"fentry/generic_fentry",
972+
pinProg,
973+
"generic_kprobe").
974+
SetAttachData(data)
975+
976+
tailCalls := program.MapBuilderProgram("fentry_calls", load)
977+
maps = append(maps, tailCalls)
978+
}
979+
980+
load.SetPolicy(kprobeEntry.policyName)
981+
load.SetLoaderData(kprobeEntry.tableId)
956982
load.Override = kprobeEntry.hasOverride
983+
957984
if load.Override {
958985
load.OverrideFmodRet = isSecurityFunc && bpf.HasModifyReturn()
959986
}
@@ -968,9 +995,6 @@ func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe
968995
configMap := program.MapBuilderProgram("config_map", load)
969996
maps = append(maps, configMap)
970997

971-
tailCalls := program.MapBuilderProgram("kprobe_calls", load)
972-
maps = append(maps, tailCalls)
973-
974998
filterMap := program.MapBuilderProgram("filter_map", load)
975999
maps = append(maps, filterMap)
9761000

@@ -1041,15 +1065,42 @@ func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe
10411065
if kprobeEntry.instance != 0 {
10421066
pinRetProg = sensors.PathJoin(fmt.Sprintf("%s_return:%d", kprobeEntry.funcName, kprobeEntry.instance))
10431067
}
1044-
loadret := program.Builder(
1045-
path.Join(option.Config.HubbleLib, loadProgRetName),
1046-
kprobeEntry.funcName,
1047-
"kprobe/generic_retkprobe",
1048-
pinRetProg,
1049-
"generic_kprobe").
1050-
SetRetProbe(true).
1051-
SetLoaderData(kprobeEntry.tableId).
1052-
SetPolicy(kprobeEntry.policyName)
1068+
1069+
var loadret *program.Program
1070+
1071+
if kprobeEntry.hasOverride {
1072+
loadret = program.Builder(
1073+
path.Join(option.Config.HubbleLib, loadProgRetName),
1074+
kprobeEntry.funcName,
1075+
"kprobe/generic_retkprobe",
1076+
pinRetProg,
1077+
"generic_kprobe")
1078+
1079+
tailCalls := program.MapBuilderProgram("retkprobe_calls", loadret)
1080+
maps = append(maps, tailCalls)
1081+
} else {
1082+
data := &program.TracingAttachData{
1083+
AttachTo: kprobeEntry.funcName,
1084+
}
1085+
1086+
loadProgName, loadProgRetName = config.GenericTracingObjs()
1087+
1088+
loadret = program.Builder(
1089+
path.Join(option.Config.HubbleLib, loadProgRetName),
1090+
kprobeEntry.funcName,
1091+
"fexit/generic_fexit",
1092+
pinRetProg,
1093+
"generic_kprobe").
1094+
SetAttachData(data)
1095+
1096+
tailCalls := program.MapBuilderProgram("fexit_calls", loadret)
1097+
maps = append(maps, tailCalls)
1098+
}
1099+
1100+
loadret.SetRetProbe(true)
1101+
loadret.SetLoaderData(kprobeEntry.tableId)
1102+
loadret.SetPolicy(kprobeEntry.policyName)
1103+
10531104
progs = append(progs, loadret)
10541105

10551106
retProbe := program.MapBuilderSensor("retprobe_map", loadret)
@@ -1058,9 +1109,6 @@ func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe
10581109
retConfigMap := program.MapBuilderProgram("config_map", loadret)
10591110
maps = append(maps, retConfigMap)
10601111

1061-
tailCalls := program.MapBuilderProgram("retkprobe_calls", loadret)
1062-
maps = append(maps, tailCalls)
1063-
10641112
filterMap := program.MapBuilderProgram("filter_map", loadret)
10651113
maps = append(maps, filterMap)
10661114

@@ -1134,10 +1182,14 @@ func loadSingleKprobeSensor(id idtable.EntryID, bpfDir string, load *program.Pro
11341182
}
11351183
load.MapLoad = append(load.MapLoad, config)
11361184

1137-
if err := program.LoadKprobeProgram(bpfDir, load, maps, verbose); err == nil {
1138-
logger.GetLogger().Info(fmt.Sprintf("Loaded generic kprobe program: %s -> %s", load.Name, load.Attach))
1185+
if load.Label == "fentry/generic_fentry" || load.Label == "fexit/generic_fexit" {
1186+
if err = program.LoadTracingProgram(bpfDir, load, maps, verbose); err == nil {
1187+
logger.GetLogger().Info(fmt.Sprintf("Loaded generic fentry program: %s -> %s", load.Name, load.Attach))
1188+
}
11391189
} else {
1140-
return err
1190+
if err = program.LoadKprobeProgram(bpfDir, load, maps, verbose); err == nil {
1191+
logger.GetLogger().Info(fmt.Sprintf("Loaded generic kprobe program: %s -> %s", load.Name, load.Attach))
1192+
}
11411193
}
11421194

11431195
return err

0 commit comments

Comments
 (0)