tetragon

Форк
0
271 строка · 6.2 Кб
1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright Authors of Tetragon
3

4
package sensors
5

6
import (
7
	"strings"
8
	"testing"
9

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"
14
)
15

16
type ProgMatch = int
17

18
const (
19
	ProgMatchFull    ProgMatch = iota // ==
20
	ProgMatchPartial                  // strings.Contains()
21
)
22

23
type SensorProg struct {
24
	Name  string
25
	Type  ebpf.ProgramType
26
	NotIn bool
27
	Match ProgMatch
28
}
29

30
type SensorMap struct {
31
	Name  string
32
	Progs []uint
33
}
34

35
func findMapForProg(coll *program.LoadedCollection, nam string, p *program.LoadedProgram) *program.LoadedMap {
36
	for name, m := range coll.Maps {
37
		if nam != name {
38
			continue
39
		}
40
		for _, id := range p.MapIDs {
41
			if m.ID == id {
42
				return m
43
			}
44
		}
45
	}
46
	return nil
47
}
48

49
type prog struct {
50
	name string
51
	prog *program.LoadedProgram
52
	coll *program.LoadedCollection
53
	mark bool
54
}
55

56
func findProgram(cache []*prog, name string, typ ebpf.ProgramType, match ProgMatch) []*prog {
57
	var p []*prog
58

59
	for _, c := range cache {
60
		if c.prog.Type != typ {
61
			continue
62
		}
63
		switch match {
64
		case ProgMatchPartial:
65
			if strings.Contains(c.name, name) {
66
				p = append(p, c)
67
			}
68
		case ProgMatchFull:
69
			if c.name == name {
70
				p = append(p, c)
71
			}
72
		}
73
	}
74
	return p
75
}
76

77
func mergeSensorMaps(t *testing.T, maps1, maps2 []SensorMap, progs1, progs2 []SensorProg) ([]SensorMap, []SensorProg) {
78
	// we take maps1,progs1 and merge in maps2,progs2
79
	mapsReturn := maps1
80
	progsReturn := progs1
81

82
	var idxList []uint
83
	idx := uint(len(progsReturn))
84

85
	// merge in progs2
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)
91
			}
92
		}
93

94
		progsReturn = append(progsReturn, p2)
95
		idxList = append(idxList, idx)
96
		idx++
97
	}
98

99
	// merge in maps2
100
	for _, m2 := range maps2 {
101
		shared := false
102

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])
109
				}
110
				shared = true
111
				break
112
			}
113
		}
114

115
		if shared {
116
			continue
117
		}
118

119
		// new map, merge it in with proper indexes
120
		var newProgs []uint
121

122
		m := m2
123
		for _, i := range m.Progs {
124
			newProgs = append(newProgs, idxList[i])
125
		}
126

127
		m.Progs = newProgs
128
		mapsReturn = append(mapsReturn, m)
129
	}
130

131
	return mapsReturn, progsReturn
132
}
133

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},
142
	}
143

144
	var baseMaps = []SensorMap{
145
		// all programs
146
		SensorMap{Name: "execve_map", Progs: []uint{0, 1, 2, 3, 4}},
147
		SensorMap{Name: "tcpmon_map", Progs: []uint{0, 1, 2, 3, 5}},
148

149
		// all but event_execve
150
		SensorMap{Name: "execve_map_stats", Progs: []uint{1, 2}},
151

152
		// event_execve
153
		SensorMap{Name: "tg_conf_map", Progs: []uint{0, 1, 2}},
154

155
		// event_wake_up_new_task
156
		SensorMap{Name: "execve_val", Progs: []uint{2}},
157

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}},
161
	}
162

163
	if option.CgroupRateEnabled() {
164
		/* 6: tg_cgroup_rmdir */
165
		sensorProgs = append(sensorProgs, SensorProg{Name: "tg_cgroup_rmdir", Type: ebpf.RawTracepoint})
166

167
		/* cgroup_rate_map */
168
		baseMaps = append(baseMaps, SensorMap{Name: "cgroup_rate_map", Progs: []uint{1, 2, 5, 6}})
169
	}
170

171
	return mergeSensorMaps(t, sensorMaps, baseMaps, sensorProgs, baseProgs)
172
}
173

174
func CheckSensorLoad(sensors []*sensors.Sensor, sensorMaps []SensorMap, sensorProgs []SensorProg, t *testing.T) {
175

176
	sensorMaps, sensorProgs = mergeInBaseSensorMaps(t, sensorMaps, sensorProgs)
177

178
	var cache []*prog
179

180
	// make programs cache 'name/type/coll'
181
	for _, sensor := range sensors {
182
		for _, load := range sensor.Progs {
183
			c := load.LC
184
			for n, p := range c.Programs {
185
				c := &prog{name: n, prog: p, coll: c, mark: false}
186
				cache = append(cache, c)
187
			}
188
		}
189
	}
190

191
	// check that we loaded expected programs
192
	for _, tp := range sensorProgs {
193
		cs := findProgram(cache, tp.Name, tp.Type, tp.Match)
194
		if len(cs) == 0 {
195
			t.Fatalf("could not find program %v in sensor", tp.Name)
196
		}
197
		for _, c := range cs {
198
			c.mark = true
199
			t.Logf("Found prog %v type %s\n", c.name, c.prog.Type)
200
		}
201
	}
202

203
	var extra bool
204

205
	// check that we did not load anything else
206
	for _, c := range cache {
207
		if !c.mark {
208
			t.Logf("found extra program loaded: %v type %s", c.name, c.prog.Type)
209
			extra = true
210
		}
211
	}
212

213
	if extra {
214
		t.Fatalf("found extra program loaded")
215
	}
216

217
	// check user provided maps
218
	for _, tm := range sensorMaps {
219
		var sharedId ebpf.MapID
220

221
		t.Logf("Checking map %v\n", tm.Name)
222

223
		for _, c := range cache {
224
			c.mark = false
225
		}
226

227
		// check that tm.Progs programs DO share the map
228
		for _, idx := range tm.Progs {
229
			tp := sensorProgs[idx]
230

231
			cs := findProgram(cache, tp.Name, tp.Type, tp.Match)
232
			if len(cs) == 0 {
233
				t.Fatalf("could not find program %v in sensor\n", tp.Name)
234
			}
235

236
			for _, c := range cs {
237
				m := findMapForProg(c.coll, tm.Name, c.prog)
238
				if m == nil {
239
					t.Fatalf("could not find map %v in program %v\n", tm.Name, tp.Name)
240
				}
241

242
				t.Logf("\tFound map %v id %v in prog %v\n", tm.Name, m.ID, tp.Name)
243

244
				if sharedId == 0 {
245
					sharedId = m.ID
246
				}
247

248
				if m.ID != sharedId {
249
					t.Fatalf("map %v has wrong shared id %v != %v\n", tm.Name, m.ID, sharedId)
250
				}
251
				c.mark = true
252
			}
253
		}
254

255
		// check that rest of the loaded programs DO NOT share the map
256
		for _, c := range cache {
257
			if c.mark {
258
				continue
259
			}
260

261
			m := findMapForProg(c.coll, tm.Name, c.prog)
262
			if m == nil {
263
				continue
264
			}
265

266
			if m.ID == sharedId {
267
				t.Fatalf("Error: Map %s[%d] is shared also with program %s", tm.Name, m.ID, c.name)
268
			}
269
		}
270
	}
271
}
272

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.