Skip to content

Commit 6382892

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

File tree

4 files changed

+112
-29
lines changed

4 files changed

+112
-29
lines changed

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: 81 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ func createGenericKprobeSensor(
643643
}
644644
dups[sym] = instance
645645

646-
id, err := addKprobe(sym, instance, &kprobes[i], &in)
646+
id, err := addKprobe(sym, instance, &kprobes[i], &in, has)
647647
if err != nil {
648648
return nil, err
649649
}
@@ -703,7 +703,7 @@ func initEventConfig() *api.EventConfig {
703703
// addKprobe will, amongst other things, create a generic kprobe entry and add
704704
// it to the genericKprobeTable. The caller should make sure that this entry is
705705
// properly removed on kprobe removal.
706-
func addKprobe(funcName string, instance int, f *v1alpha1.KProbeSpec, in *addKprobeIn) (id idtable.EntryID, err error) {
706+
func addKprobe(funcName string, instance int, f *v1alpha1.KProbeSpec, in *addKprobeIn, has hasMaps) (id idtable.EntryID, err error) {
707707
var argSigPrinters []argPrinter
708708
var argReturnPrinters []argPrinter
709709
var setRetprobe bool
@@ -920,7 +920,8 @@ func addKprobe(funcName string, instance int, f *v1alpha1.KProbeSpec, in *addKpr
920920
eventConfig.FuncId = uint32(kprobeEntry.tableId.ID)
921921

922922
logger.GetLogger().
923-
Info("Added kprobe", "return", setRetprobe, "function", kprobeEntry.funcName, "override", kprobeEntry.hasOverride)
923+
Info("Added kprobe", "return", setRetprobe, "function", kprobeEntry.funcName,
924+
"override", kprobeEntry.hasOverride, "enforcer", has.enforcer)
924925

925926
return kprobeEntry.tableId, nil
926927
}
@@ -931,20 +932,48 @@ func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe
931932
loadProgName, loadProgRetName := config.GenericKprobeObjs(false)
932933
isSecurityFunc := strings.HasPrefix(kprobeEntry.funcName, "security_")
933934

935+
useFentry := false
936+
934937
pinProg := kprobeEntry.funcName
935938
if kprobeEntry.instance != 0 {
936939
pinProg = fmt.Sprintf("%s:%d", kprobeEntry.funcName, kprobeEntry.instance)
937940
}
938941

939-
load := program.Builder(
940-
path.Join(option.Config.HubbleLib, loadProgName),
941-
kprobeEntry.funcName,
942-
"kprobe/generic_kprobe",
943-
pinProg,
944-
"generic_kprobe").
945-
SetLoaderData(kprobeEntry.tableId).
946-
SetPolicy(kprobeEntry.policyName)
942+
var load *program.Program
943+
944+
if useFentry {
945+
data := &program.TracingAttachData{
946+
AttachTo: kprobeEntry.funcName,
947+
}
948+
949+
loadProgName, loadProgRetName = config.GenericTracingObjs()
950+
951+
load = program.Builder(
952+
path.Join(option.Config.HubbleLib, loadProgName),
953+
kprobeEntry.funcName,
954+
"fentry/generic_fentry",
955+
pinProg,
956+
"generic_kprobe").
957+
SetAttachData(data)
958+
959+
tailCalls := program.MapBuilderProgram("fentry_calls", load)
960+
maps = append(maps, tailCalls)
961+
} else {
962+
load = program.Builder(
963+
path.Join(option.Config.HubbleLib, loadProgName),
964+
kprobeEntry.funcName,
965+
"kprobe/generic_kprobe",
966+
pinProg,
967+
"generic_kprobe")
968+
969+
tailCalls := program.MapBuilderProgram("kprobe_calls", load)
970+
maps = append(maps, tailCalls)
971+
}
972+
973+
load.SetPolicy(kprobeEntry.policyName)
974+
load.SetLoaderData(kprobeEntry.tableId)
947975
load.Override = kprobeEntry.hasOverride
976+
948977
if load.Override {
949978
load.OverrideFmodRet = isSecurityFunc && bpf.HasModifyReturn()
950979
}
@@ -959,9 +988,6 @@ func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe
959988
configMap := program.MapBuilderProgram("config_map", load)
960989
maps = append(maps, configMap)
961990

962-
tailCalls := program.MapBuilderProgram("kprobe_calls", load)
963-
maps = append(maps, tailCalls)
964-
965991
filterMap := program.MapBuilderProgram("filter_map", load)
966992
maps = append(maps, filterMap)
967993

@@ -1032,15 +1058,40 @@ func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe
10321058
if kprobeEntry.instance != 0 {
10331059
pinRetProg = sensors.PathJoin(fmt.Sprintf("%s_return:%d", kprobeEntry.funcName, kprobeEntry.instance))
10341060
}
1035-
loadret := program.Builder(
1036-
path.Join(option.Config.HubbleLib, loadProgRetName),
1037-
kprobeEntry.funcName,
1038-
"kprobe/generic_retkprobe",
1039-
pinRetProg,
1040-
"generic_kprobe").
1041-
SetRetProbe(true).
1042-
SetLoaderData(kprobeEntry.tableId).
1043-
SetPolicy(kprobeEntry.policyName)
1061+
1062+
var loadret *program.Program
1063+
1064+
if useFentry {
1065+
data := &program.TracingAttachData{
1066+
AttachTo: kprobeEntry.funcName,
1067+
}
1068+
1069+
loadret = program.Builder(
1070+
path.Join(option.Config.HubbleLib, loadProgRetName),
1071+
kprobeEntry.funcName,
1072+
"fexit/generic_fexit",
1073+
pinRetProg,
1074+
"generic_kprobe").
1075+
SetAttachData(data)
1076+
1077+
tailCalls := program.MapBuilderProgram("fexit_calls", loadret)
1078+
maps = append(maps, tailCalls)
1079+
} else {
1080+
loadret = program.Builder(
1081+
path.Join(option.Config.HubbleLib, loadProgRetName),
1082+
kprobeEntry.funcName,
1083+
"kprobe/generic_retkprobe",
1084+
pinRetProg,
1085+
"generic_kprobe")
1086+
1087+
tailCalls := program.MapBuilderProgram("retkprobe_calls", loadret)
1088+
maps = append(maps, tailCalls)
1089+
}
1090+
1091+
loadret.SetRetProbe(true)
1092+
loadret.SetLoaderData(kprobeEntry.tableId)
1093+
loadret.SetPolicy(kprobeEntry.policyName)
1094+
10441095
progs = append(progs, loadret)
10451096

10461097
retProbe := program.MapBuilderSensor("retprobe_map", loadret)
@@ -1049,9 +1100,6 @@ func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe
10491100
retConfigMap := program.MapBuilderProgram("config_map", loadret)
10501101
maps = append(maps, retConfigMap)
10511102

1052-
tailCalls := program.MapBuilderProgram("retkprobe_calls", loadret)
1053-
maps = append(maps, tailCalls)
1054-
10551103
filterMap := program.MapBuilderProgram("filter_map", loadret)
10561104
maps = append(maps, filterMap)
10571105

@@ -1125,10 +1173,14 @@ func loadSingleKprobeSensor(id idtable.EntryID, bpfDir string, load *program.Pro
11251173
}
11261174
load.MapLoad = append(load.MapLoad, config)
11271175

1128-
if err := program.LoadKprobeProgram(bpfDir, load, maps, verbose); err == nil {
1129-
logger.GetLogger().Info(fmt.Sprintf("Loaded generic kprobe program: %s -> %s", load.Name, load.Attach))
1176+
if load.Label == "fentry/generic_fentry" || load.Label == "fexit/generic_fexit" {
1177+
if err = program.LoadTracingProgram(bpfDir, load, maps, verbose); err == nil {
1178+
logger.GetLogger().Info(fmt.Sprintf("Loaded generic fentry program: %s -> %s", load.Name, load.Attach))
1179+
}
11301180
} else {
1131-
return err
1181+
if err = program.LoadKprobeProgram(bpfDir, load, maps, verbose); err == nil {
1182+
logger.GetLogger().Info(fmt.Sprintf("Loaded generic kprobe program: %s -> %s", load.Name, load.Attach))
1183+
}
11321184
}
11331185

11341186
return err

0 commit comments

Comments
 (0)