1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright Authors of Tetragon
10
"github.com/cilium/ebpf"
11
"github.com/cilium/tetragon/pkg/option"
12
"github.com/cilium/tetragon/pkg/sensors"
13
"github.com/cilium/tetragon/pkg/sensors/program"
19
ProgMatchFull ProgMatch = iota // ==
20
ProgMatchPartial // strings.Contains()
23
type SensorProg struct {
30
type SensorMap struct {
35
func findMapForProg(coll *program.LoadedCollection, nam string, p *program.LoadedProgram) *program.LoadedMap {
36
for name, m := range coll.Maps {
40
for _, id := range p.MapIDs {
51
prog *program.LoadedProgram
52
coll *program.LoadedCollection
56
func findProgram(cache []*prog, name string, typ ebpf.ProgramType, match ProgMatch) []*prog {
59
for _, c := range cache {
60
if c.prog.Type != typ {
64
case ProgMatchPartial:
65
if strings.Contains(c.name, name) {
77
func mergeSensorMaps(t *testing.T, maps1, maps2 []SensorMap, progs1, progs2 []SensorProg) ([]SensorMap, []SensorProg) {
78
// we take maps1,progs1 and merge in maps2,progs2
83
idx := uint(len(progsReturn))
86
for _, p2 := range progs2 {
87
// do maps share the same program
88
for _, p := range progsReturn {
89
if p.Name == p2.Name && p.Type == p2.Type {
90
t.Fatalf("merge fail: program '%s' in both maps", p.Name)
94
progsReturn = append(progsReturn, p2)
95
idxList = append(idxList, idx)
100
for _, m2 := range maps2 {
103
// do we have shared map
104
for i1, m1 := range maps1 {
105
// shared map, add progs2 into it
106
if m1.Name == m2.Name {
107
for _, ip := range m2.Progs {
108
mapsReturn[i1].Progs = append(mapsReturn[i1].Progs, idxList[ip])
119
// new map, merge it in with proper indexes
123
for _, i := range m.Progs {
124
newProgs = append(newProgs, idxList[i])
128
mapsReturn = append(mapsReturn, m)
131
return mapsReturn, progsReturn
134
func mergeInBaseSensorMaps(t *testing.T, sensorMaps []SensorMap, sensorProgs []SensorProg) ([]SensorMap, []SensorProg) {
135
var baseProgs = []SensorProg{
136
0: SensorProg{Name: "event_execve", Type: ebpf.TracePoint},
137
1: SensorProg{Name: "event_exit", Type: ebpf.Kprobe, Match: ProgMatchPartial},
138
2: SensorProg{Name: "event_wake_up_new_task", Type: ebpf.Kprobe},
139
3: SensorProg{Name: "execve_send", Type: ebpf.TracePoint},
140
4: SensorProg{Name: "tg_kp_bprm_committing_creds", Type: ebpf.Kprobe},
141
5: SensorProg{Name: "execve_rate", Type: ebpf.TracePoint},
144
var baseMaps = []SensorMap{
146
SensorMap{Name: "execve_map", Progs: []uint{0, 1, 2, 3, 4}},
147
SensorMap{Name: "tcpmon_map", Progs: []uint{0, 1, 2, 3, 5}},
149
// all but event_execve
150
SensorMap{Name: "execve_map_stats", Progs: []uint{1, 2}},
153
SensorMap{Name: "tg_conf_map", Progs: []uint{0, 1, 2}},
155
// event_wake_up_new_task
156
SensorMap{Name: "execve_val", Progs: []uint{2}},
158
// event_execve and tg_kp_bprm_committing_creds
159
SensorMap{Name: "tg_execve_joined_info_map", Progs: []uint{0, 4}},
160
SensorMap{Name: "tg_execve_joined_info_map_stats", Progs: []uint{0, 4}},
163
if option.CgroupRateEnabled() {
164
/* 6: tg_cgroup_rmdir */
165
sensorProgs = append(sensorProgs, SensorProg{Name: "tg_cgroup_rmdir", Type: ebpf.RawTracepoint})
167
/* cgroup_rate_map */
168
baseMaps = append(baseMaps, SensorMap{Name: "cgroup_rate_map", Progs: []uint{1, 2, 5, 6}})
171
return mergeSensorMaps(t, sensorMaps, baseMaps, sensorProgs, baseProgs)
174
func CheckSensorLoad(sensors []*sensors.Sensor, sensorMaps []SensorMap, sensorProgs []SensorProg, t *testing.T) {
176
sensorMaps, sensorProgs = mergeInBaseSensorMaps(t, sensorMaps, sensorProgs)
180
// make programs cache 'name/type/coll'
181
for _, sensor := range sensors {
182
for _, load := range sensor.Progs {
184
for n, p := range c.Programs {
185
c := &prog{name: n, prog: p, coll: c, mark: false}
186
cache = append(cache, c)
191
// check that we loaded expected programs
192
for _, tp := range sensorProgs {
193
cs := findProgram(cache, tp.Name, tp.Type, tp.Match)
195
t.Fatalf("could not find program %v in sensor", tp.Name)
197
for _, c := range cs {
199
t.Logf("Found prog %v type %s\n", c.name, c.prog.Type)
205
// check that we did not load anything else
206
for _, c := range cache {
208
t.Logf("found extra program loaded: %v type %s", c.name, c.prog.Type)
214
t.Fatalf("found extra program loaded")
217
// check user provided maps
218
for _, tm := range sensorMaps {
219
var sharedId ebpf.MapID
221
t.Logf("Checking map %v\n", tm.Name)
223
for _, c := range cache {
227
// check that tm.Progs programs DO share the map
228
for _, idx := range tm.Progs {
229
tp := sensorProgs[idx]
231
cs := findProgram(cache, tp.Name, tp.Type, tp.Match)
233
t.Fatalf("could not find program %v in sensor\n", tp.Name)
236
for _, c := range cs {
237
m := findMapForProg(c.coll, tm.Name, c.prog)
239
t.Fatalf("could not find map %v in program %v\n", tm.Name, tp.Name)
242
t.Logf("\tFound map %v id %v in prog %v\n", tm.Name, m.ID, tp.Name)
248
if m.ID != sharedId {
249
t.Fatalf("map %v has wrong shared id %v != %v\n", tm.Name, m.ID, sharedId)
255
// check that rest of the loaded programs DO NOT share the map
256
for _, c := range cache {
261
m := findMapForProg(c.coll, tm.Name, c.prog)
266
if m.ID == sharedId {
267
t.Fatalf("Error: Map %s[%d] is shared also with program %s", tm.Name, m.ID, c.name)