Skip to content

Commit 589ab67

Browse files
committed
kprobe: support 38+ override on lsm funcs
1. Allow policies to share override programs as long as they share the same attached functions. This includes both programs based on kprobe and fmod_ret. 2. The pinned path of ebpf programs and maps are moved to below locations: /bpffs/tetragon/__override__ /bpffs/tetragon/__override__/kprobe /bpffs/tetragon/__override__/kprobe/__x64_sys_symlinkat /bpffs/tetragon/__override__/kprobe/__x64_sys_symlinkat/link_override /bpffs/tetragon/__override__/kprobe/__x64_sys_symlinkat/prog_override /bpffs/tetragon/__override__/kprobe/__x64_sys_execve /bpffs/tetragon/__override__/kprobe/__x64_sys_execve/link_override /bpffs/tetragon/__override__/kprobe/__x64_sys_execve/prog_override /bpffs/tetragon/__override__/override_tasks /bpffs/tetragon/__override__/fmod_ret /bpffs/tetragon/__override__/fmod_ret/security_bprm_creds_for_exec /bpffs/tetragon/__override__/fmod_ret/security_bprm_creds_for_exec/prog Signed-off-by: Sam Wang (holyspectral) <sam.wang@suse.com>
1 parent f392065 commit 589ab67

File tree

4 files changed

+226
-9
lines changed

4 files changed

+226
-9
lines changed

pkg/sensors/load.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ func (s *Sensor) policyDir() string {
6565

6666
func (s *Sensor) createDirs(bpfDir string) {
6767
for _, p := range s.Progs {
68-
// setup sensor based program pin path
69-
p.PinPath = filepath.Join(s.policyDir(), s.Name, p.PinName)
68+
// setup sensor based program pin path if it's not specified
69+
if p.PinPath == "" {
70+
p.PinPath = filepath.Join(s.policyDir(), s.Name, p.PinName)
71+
}
7072
// and make the path
7173
if err := os.MkdirAll(filepath.Join(bpfDir, p.PinPath), os.ModeDir); err != nil {
7274
logger.GetLogger().Warn("Failed to create program dir",

pkg/sensors/load_linux.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import (
1919
)
2020

2121
func (s *Sensor) setMapPinPath(m *program.Map) {
22+
if m.PinPath != "" {
23+
// Use the specified one when m.PinPath is already available.
24+
return
25+
}
2226
policy := s.policyDir()
2327
switch m.Type {
2428
case program.MapTypeGlobal:

pkg/sensors/tracing/generickprobe.go

Lines changed: 116 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,32 @@ type observerKprobeSensor struct {
5353
name string
5454
}
5555

56+
type fmodRetProgram struct {
57+
name string
58+
}
59+
60+
type kprobeOverrideProgram struct {
61+
name string
62+
}
63+
5664
func init() {
5765
kprobe := &observerKprobeSensor{
5866
name: "kprobe sensor",
5967
}
68+
69+
fmodRet := &fmodRetProgram{
70+
name: "fmod_ret program",
71+
}
72+
73+
kprobeOverrideProgram := &kprobeOverrideProgram{
74+
name: "kprobe_override program",
75+
}
76+
6077
sensors.RegisterProbeType("generic_kprobe", kprobe)
6178
observer.RegisterEventHandlerAtInit(ops.MSG_OP_GENERIC_KPROBE, handleGenericKprobe)
79+
80+
sensors.RegisterProbeType("generic_fmod_ret", fmodRet)
81+
sensors.RegisterProbeType("generic_kprobe_override", kprobeOverrideProgram)
6282
}
6383

6484
type kprobeSelectors struct {
@@ -344,11 +364,23 @@ func createMultiKprobeSensor(polInfo *policyInfo, multiIDs []idtable.EntryID, ha
344364
filterMap.SetMaxEntries(len(multiIDs))
345365
configMap.SetMaxEntries(len(multiIDs))
346366

347-
overrideTasksMap := program.MapBuilderProgram("override_tasks", load)
348367
if has.override {
349-
overrideTasksMap.SetMaxEntries(overrideMapMaxEntries)
368+
for _, id := range multiIDs {
369+
gk, err := genericKprobeTableGet(id)
370+
if err != nil {
371+
return nil, nil, err
372+
}
373+
gk.data = &genericKprobeData{}
374+
375+
progs, maps = createKProbeOverrideProgramFromEntry(load, gk.funcName, progs, maps)
376+
}
377+
} else {
378+
overrideTasksMap := program.MapBuilderProgram("override_tasks", load)
379+
if has.override {
380+
overrideTasksMap.SetMaxEntries(overrideMapMaxEntries)
381+
}
382+
maps = append(maps, overrideTasksMap)
350383
}
351-
maps = append(maps, overrideTasksMap)
352384

353385
maps = append(maps, polInfo.policyConfMap(load), polInfo.policyStatsMap(load))
354386

@@ -983,6 +1015,38 @@ func addKprobe(funcName string, instance int, f *v1alpha1.KProbeSpec, in *addKpr
9831015
return kprobeEntry.tableId, nil
9841016
}
9851017

1018+
func createKProbeOverrideProgramFromEntry(load *program.Program, attachFunc string, progs []*program.Program, maps []*program.Map) ([]*program.Program, []*program.Map) {
1019+
// setup kprobe override program and its input
1020+
kprobeOverrideProg, kprobeOverrideMap := getOverrideProg(OverrideTypeKProbe, attachFunc)
1021+
progs = append(progs, kprobeOverrideProg)
1022+
maps = append(maps, kprobeOverrideMap)
1023+
1024+
// setup the output of kprobe
1025+
overrideTasksMap := program.MapBuilder("override_tasks", load)
1026+
overrideTasksMap.PinPath = kprobeOverrideMap.PinPath
1027+
overrideTasksMap.SetMaxEntries(overrideMapMaxEntries)
1028+
1029+
maps = append(maps, overrideTasksMap)
1030+
1031+
return progs, maps
1032+
}
1033+
1034+
func createFmodRetOverrideProgramFromEntry(load *program.Program, attachFunc string, progs []*program.Program, maps []*program.Map) ([]*program.Program, []*program.Map) {
1035+
// setup fmodret program and its input
1036+
fmodRetProg, fmodRetMap := getOverrideProg(OverrideTypeFmodRet, attachFunc)
1037+
progs = append(progs, fmodRetProg)
1038+
maps = append(maps, fmodRetMap)
1039+
1040+
// setup the output of kprobe
1041+
overrideTasksMap := program.MapBuilder("override_tasks", load)
1042+
overrideTasksMap.PinPath = fmodRetMap.PinPath
1043+
overrideTasksMap.SetMaxEntries(overrideMapMaxEntries)
1044+
1045+
maps = append(maps, overrideTasksMap)
1046+
1047+
return progs, maps
1048+
}
1049+
9861050
func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe,
9871051
progs []*program.Program, maps []*program.Map, has hasMaps) ([]*program.Program, []*program.Map) {
9881052

@@ -1080,11 +1144,16 @@ func createKprobeSensorFromEntry(polInfo *policyInfo, kprobeEntry *genericKprobe
10801144
maps = append(maps, program.MapUser(cgtracker.MapName, load))
10811145
}
10821146

1083-
overrideTasksMap := program.MapBuilderProgram("override_tasks", load)
1084-
if has.override {
1085-
overrideTasksMap.SetMaxEntries(overrideMapMaxEntries)
1147+
if load.Override {
1148+
if load.OverrideFmodRet {
1149+
progs, maps = createFmodRetOverrideProgramFromEntry(load, kprobeEntry.funcName, progs, maps)
1150+
} else {
1151+
progs, maps = createKProbeOverrideProgramFromEntry(load, kprobeEntry.funcName, progs, maps)
1152+
}
1153+
} else {
1154+
overrideTasksMap := program.MapBuilderProgram("override_tasks", load)
1155+
maps = append(maps, overrideTasksMap)
10861156
}
1087-
maps = append(maps, overrideTasksMap)
10881157

10891158
maps = append(maps, polInfo.policyConfMap(load), polInfo.policyStatsMap(load))
10901159

@@ -1241,6 +1310,38 @@ func loadMultiKprobeSensor(ids []idtable.EntryID, bpfDir string, load *program.P
12411310
return nil
12421311
}
12431312

1313+
func loadGenericFmodRetProgram(bpfDir string, load *program.Program, maps []*program.Map, verbose int) error {
1314+
if load.LoadState.IsLoaded() {
1315+
logger.GetLogger().Info(fmt.Sprintf("The generic fmodify return program on %s has been loaded", load.Attach))
1316+
return nil
1317+
}
1318+
1319+
logger.GetLogger().Info("loading generic fmod ret program", "prog", load)
1320+
1321+
unload := func(_ bool) error {
1322+
deleteOverrideProg(OverrideTypeFmodRet, load.Attach)
1323+
return nil
1324+
}
1325+
1326+
return program.LoadFmodRetProgram(bpfDir, load, maps, "generic_fmodret_override", verbose, unload)
1327+
}
1328+
1329+
func loadGenericKProbeOverrideProgram(bpfDir string, load *program.Program, maps []*program.Map, verbose int) error {
1330+
if load.LoadState.IsLoaded() {
1331+
logger.GetLogger().Info(fmt.Sprintf("The generic kprobe override program on %s has been loaded", load.Attach))
1332+
return nil
1333+
}
1334+
1335+
logger.GetLogger().Info("loading generic kprobe override program", "prog", load)
1336+
1337+
unload := func(_ bool) error {
1338+
deleteOverrideProg(OverrideTypeKProbe, load.Attach)
1339+
return nil
1340+
}
1341+
1342+
return program.LoadKProbeOverrideProgram(bpfDir, load, maps, "generic_kprobe_override", verbose, unload)
1343+
}
1344+
12441345
func loadGenericKprobeSensor(bpfDir string, load *program.Program, maps []*program.Map, verbose int) error {
12451346
if id, ok := load.LoaderData.(idtable.EntryID); ok {
12461347
return loadSingleKprobeSensor(id, bpfDir, load, maps, verbose)
@@ -1468,3 +1569,11 @@ func retprobeMerge(prev pendingEvent, curr pendingEvent) *tracing.MsgGenericKpro
14681569
func (k *observerKprobeSensor) LoadProbe(args sensors.LoadProbeArgs) error {
14691570
return loadGenericKprobeSensor(args.BPFDir, args.Load, args.Maps, args.Verbose)
14701571
}
1572+
1573+
func (k *fmodRetProgram) LoadProbe(args sensors.LoadProbeArgs) error {
1574+
return loadGenericFmodRetProgram(args.BPFDir, args.Load, args.Maps, args.Verbose)
1575+
}
1576+
1577+
func (k *kprobeOverrideProgram) LoadProbe(args sensors.LoadProbeArgs) error {
1578+
return loadGenericKProbeOverrideProgram(args.BPFDir, args.Load, args.Maps, args.Verbose)
1579+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Authors of Tetragon
3+
4+
package tracing
5+
6+
import (
7+
"path"
8+
9+
"github.com/cilium/tetragon/pkg/logger"
10+
"github.com/cilium/tetragon/pkg/sensors/program"
11+
)
12+
13+
type OverrideType string
14+
15+
const (
16+
OverrideTypeKProbe = "kprobe"
17+
OverrideTypeFmodRet = "fmod_ret"
18+
)
19+
20+
var overrideProgMap map[string]*program.Program
21+
22+
func getOverrideProgMapKey(overrideType OverrideType, attachFunc string) string {
23+
return string(overrideType) + attachFunc
24+
}
25+
26+
func createFmodRetOverrideProg(attachFunc string) *program.Program {
27+
overrideProg := program.Builder(
28+
"bpf_generic_override.o",
29+
attachFunc,
30+
"fmod_ret/security_task_prctl",
31+
"fmod_ret/"+attachFunc,
32+
"generic_fmod_ret")
33+
34+
overrideProg.PinPath = path.Join("__override__", "fmod_ret", attachFunc)
35+
36+
overrideTasksMap := program.MapBuilder("override_tasks", overrideProg)
37+
overrideTasksMap.PinPath = path.Join("__override__", "override_tasks")
38+
overrideTasksMap.SetMaxEntries(overrideMapMaxEntries)
39+
40+
return overrideProg
41+
}
42+
43+
func createKProbeOverrideProg(attachFunc string) *program.Program {
44+
overrideProg := program.Builder(
45+
"bpf_generic_override.o",
46+
attachFunc,
47+
"kprobe/generic_kprobe_override",
48+
"kprobe/"+attachFunc,
49+
"generic_kprobe_override")
50+
51+
overrideProg.PinPath = path.Join("__override__", "kprobe", attachFunc)
52+
53+
overrideTasksMap := program.MapBuilder("override_tasks", overrideProg)
54+
overrideTasksMap.PinPath = path.Join("__override__", "override_tasks")
55+
overrideTasksMap.SetMaxEntries(overrideMapMaxEntries)
56+
57+
return overrideProg
58+
}
59+
60+
func getOverrideProg(overrideType OverrideType, attachFunc string) (*program.Program, *program.Map) {
61+
var overrideProg *program.Program
62+
var ok bool
63+
64+
if overrideProgMap == nil {
65+
overrideProgMap = make(map[string]*program.Program)
66+
}
67+
68+
key := getOverrideProgMapKey(overrideType, attachFunc)
69+
70+
if overrideProg, ok = overrideProgMap[key]; !ok {
71+
72+
switch overrideType {
73+
case OverrideTypeKProbe:
74+
overrideProg = createKProbeOverrideProg(attachFunc)
75+
case OverrideTypeFmodRet:
76+
overrideProg = createFmodRetOverrideProg(attachFunc)
77+
}
78+
79+
overrideProgMap[key] = overrideProg
80+
}
81+
82+
logger.GetLogger().Info("Getting a new override prog", "prog", overrideProg, "map", overrideProg.PinMap["override_tasks"])
83+
84+
return overrideProg, overrideProg.PinMap["override_tasks"]
85+
}
86+
87+
func deleteOverrideProg(overrideType OverrideType, attachFunc string) {
88+
var prog *program.Program
89+
var ok bool
90+
91+
key := getOverrideProgMapKey(overrideType, attachFunc)
92+
93+
if overrideProgMap == nil {
94+
return
95+
}
96+
if prog, ok = overrideProgMap[key]; !ok {
97+
return
98+
}
99+
if !prog.LoadState.IsLoaded() {
100+
delete(overrideProgMap, key)
101+
}
102+
}

0 commit comments

Comments
 (0)