tetragon

Форк
0
/
encoder_test.go 
537 строк · 14.7 Кб
1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright Authors of Tetragon
3

4
package encoder
5

6
import (
7
	"bytes"
8
	"encoding/json"
9
	"os"
10
	"testing"
11

12
	"google.golang.org/protobuf/encoding/protojson"
13
	"google.golang.org/protobuf/proto"
14
	"google.golang.org/protobuf/types/known/timestamppb"
15

16
	"github.com/cilium/tetragon/api/v1/tetragon"
17
	"github.com/sryoya/protorand"
18
	"github.com/stretchr/testify/assert"
19
	"github.com/stretchr/testify/require"
20
)
21

22
func TestCompactEncoder_InvalidEventToString(t *testing.T) {
23
	p := NewCompactEncoder(os.Stdout, Never, false, false)
24

25
	// should fail if the event field is nil.
26
	_, err := p.EventToString(&tetragon.GetEventsResponse{})
27
	assert.Error(t, err)
28
}
29

30
func TestCompactEncoder_ExecEventToString(t *testing.T) {
31
	p := NewCompactEncoder(os.Stdout, Never, false, false)
32

33
	// should fail if the process field is nil.
34
	_, err := p.EventToString(&tetragon.GetEventsResponse{
35
		Event: &tetragon.GetEventsResponse_ProcessExec{
36
			ProcessExec: &tetragon.ProcessExec{},
37
		},
38
	})
39
	assert.Error(t, err)
40

41
	// without pod info
42
	result, err := p.EventToString(&tetragon.GetEventsResponse{
43
		Event: &tetragon.GetEventsResponse_ProcessExec{
44
			ProcessExec: &tetragon.ProcessExec{
45
				Process: &tetragon.Process{
46
					Binary:    "/usr/bin/curl",
47
					Arguments: "cilium.io",
48
				},
49
			},
50
		},
51
		NodeName: "my-node",
52
	})
53
	assert.NoError(t, err)
54
	assert.Equal(t, "🚀 process my-node /usr/bin/curl cilium.io", result)
55

56
	// with pod info
57
	result, err = p.EventToString(&tetragon.GetEventsResponse{
58
		Event: &tetragon.GetEventsResponse_ProcessExec{
59
			ProcessExec: &tetragon.ProcessExec{
60
				Process: &tetragon.Process{
61
					Binary:    "/usr/bin/curl",
62
					Arguments: "cilium.io",
63
					Pod: &tetragon.Pod{
64
						Namespace: "kube-system",
65
						Name:      "tetragon",
66
					},
67
				},
68
			},
69
		},
70
	})
71
	assert.NoError(t, err)
72
	assert.Equal(t, "🚀 process kube-system/tetragon /usr/bin/curl cilium.io", result)
73
}
74

75
func TestCompactEncoder_ExitEventToString(t *testing.T) {
76
	p := NewCompactEncoder(os.Stdout, Never, false, false)
77

78
	// should fail if the process field is nil.
79
	_, err := p.EventToString(&tetragon.GetEventsResponse{
80
		Event: &tetragon.GetEventsResponse_ProcessExit{
81
			ProcessExit: &tetragon.ProcessExit{},
82
		},
83
	})
84
	assert.Error(t, err)
85

86
	// with status
87
	result, err := p.EventToString(&tetragon.GetEventsResponse{
88
		Event: &tetragon.GetEventsResponse_ProcessExit{
89
			ProcessExit: &tetragon.ProcessExit{
90
				Process: &tetragon.Process{
91
					Binary:    "/usr/bin/curl",
92
					Arguments: "cilium.io",
93
					Pod: &tetragon.Pod{
94
						Namespace: "kube-system",
95
						Name:      "tetragon",
96
					},
97
				},
98
				Status: 1,
99
			},
100
		},
101
	})
102
	assert.NoError(t, err)
103
	assert.Equal(t, "💥 exit    kube-system/tetragon /usr/bin/curl cilium.io 1", result)
104

105
	// with signal
106
	result, err = p.EventToString(&tetragon.GetEventsResponse{
107
		Event: &tetragon.GetEventsResponse_ProcessExit{
108
			ProcessExit: &tetragon.ProcessExit{
109
				Process: &tetragon.Process{
110
					Binary:    "/usr/bin/curl",
111
					Arguments: "cilium.io",
112
					Pod: &tetragon.Pod{
113
						Namespace: "kube-system",
114
						Name:      "tetragon",
115
					},
116
				},
117
				Signal: "SIGKILL",
118
			},
119
		},
120
	})
121
	assert.NoError(t, err)
122
	assert.Equal(t, "💥 exit    kube-system/tetragon /usr/bin/curl cilium.io SIGKILL", result)
123
}
124

125
func TestCompactEncoder_KprobeEventToString(t *testing.T) {
126
	p := NewCompactEncoder(os.Stdout, Never, false, false)
127

128
	// should fail without process field
129
	_, err := p.EventToString(&tetragon.GetEventsResponse{
130
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
131
			ProcessKprobe: &tetragon.ProcessKprobe{
132
				FunctionName: "unhandled_function",
133
			},
134
		},
135
	})
136
	assert.Error(t, err)
137

138
	// unknown function
139
	result, err := p.EventToString(&tetragon.GetEventsResponse{
140
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
141
			ProcessKprobe: &tetragon.ProcessKprobe{
142
				Process: &tetragon.Process{
143
					Binary: "/usr/bin/curl",
144
					Pod: &tetragon.Pod{
145
						Namespace: "kube-system",
146
						Name:      "tetragon",
147
					},
148
				},
149
				FunctionName: "unhandled_function",
150
			},
151
		},
152
	})
153
	assert.NoError(t, err)
154
	assert.Equal(t, "❓ syscall kube-system/tetragon /usr/bin/curl unhandled_function", result)
155

156
}
157

158
func TestCompactEncoder_KprobeOpenEventToString(t *testing.T) {
159
	p := NewCompactEncoder(os.Stdout, Never, false, false)
160

161
	// open without args
162
	result, err := p.EventToString(&tetragon.GetEventsResponse{
163
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
164
			ProcessKprobe: &tetragon.ProcessKprobe{
165
				Process: &tetragon.Process{
166
					Binary: "/usr/bin/curl",
167
					Pod: &tetragon.Pod{
168
						Namespace: "kube-system",
169
						Name:      "tetragon",
170
					},
171
				},
172
				FunctionName: "fd_install",
173
			},
174
		},
175
	})
176
	assert.NoError(t, err)
177
	assert.Equal(t, "📬 open    kube-system/tetragon /usr/bin/curl ", result)
178

179
	// open with args
180
	result, err = p.EventToString(&tetragon.GetEventsResponse{
181
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
182
			ProcessKprobe: &tetragon.ProcessKprobe{
183
				Process: &tetragon.Process{
184
					Binary: "/usr/bin/curl",
185
					Pod: &tetragon.Pod{
186
						Namespace: "kube-system",
187
						Name:      "tetragon",
188
					},
189
				},
190
				FunctionName: "fd_install",
191
				Args: []*tetragon.KprobeArgument{
192
					nil,
193
					{Arg: &tetragon.KprobeArgument_FileArg{FileArg: &tetragon.KprobeFile{Path: "/etc/password"}}},
194
				},
195
			},
196
		},
197
	})
198
	assert.NoError(t, err)
199
	assert.Equal(t, "📬 open    kube-system/tetragon /usr/bin/curl /etc/password", result)
200
}
201

202
func TestCompactEncoder_KprobeWriteEventToString(t *testing.T) {
203
	p := NewCompactEncoder(os.Stdout, Never, false, false)
204

205
	// write without args
206
	result, err := p.EventToString(&tetragon.GetEventsResponse{
207
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
208
			ProcessKprobe: &tetragon.ProcessKprobe{
209
				Process: &tetragon.Process{
210
					Binary: "/usr/bin/curl",
211
					Pod: &tetragon.Pod{
212
						Namespace: "kube-system",
213
						Name:      "tetragon",
214
					},
215
				},
216
				FunctionName: "__x64_sys_write",
217
			},
218
		},
219
	})
220
	assert.NoError(t, err)
221
	assert.Equal(t, "📝 write   kube-system/tetragon /usr/bin/curl  ", result)
222

223
	// write with args
224
	result, err = p.EventToString(&tetragon.GetEventsResponse{
225
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
226
			ProcessKprobe: &tetragon.ProcessKprobe{
227
				Process: &tetragon.Process{
228
					Binary: "/usr/bin/curl",
229
					Pod: &tetragon.Pod{
230
						Namespace: "kube-system",
231
						Name:      "tetragon",
232
					},
233
				},
234
				FunctionName: "__x64_sys_write",
235
				Args: []*tetragon.KprobeArgument{
236
					{Arg: &tetragon.KprobeArgument_FileArg{FileArg: &tetragon.KprobeFile{Path: "/etc/password"}}},
237
					nil,
238
					{Arg: &tetragon.KprobeArgument_SizeArg{SizeArg: 1234}},
239
				},
240
			},
241
		},
242
	})
243
	assert.NoError(t, err)
244
	assert.Equal(t, "📝 write   kube-system/tetragon /usr/bin/curl /etc/password 1234 bytes", result)
245
}
246

247
func TestCompactEncoder_KprobeCloseEventToString(t *testing.T) {
248
	p := NewCompactEncoder(os.Stdout, Never, false, false)
249

250
	// open without args
251
	result, err := p.EventToString(&tetragon.GetEventsResponse{
252
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
253
			ProcessKprobe: &tetragon.ProcessKprobe{
254
				Process: &tetragon.Process{
255
					Binary: "/usr/bin/curl",
256
					Pod: &tetragon.Pod{
257
						Namespace: "kube-system",
258
						Name:      "tetragon",
259
					},
260
				},
261
				FunctionName: "__x64_sys_close",
262
			},
263
		},
264
	})
265
	assert.NoError(t, err)
266
	assert.Equal(t, "📪 close   kube-system/tetragon /usr/bin/curl ", result)
267

268
	// open with args
269
	result, err = p.EventToString(&tetragon.GetEventsResponse{
270
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
271
			ProcessKprobe: &tetragon.ProcessKprobe{
272
				Process: &tetragon.Process{
273
					Binary: "/usr/bin/curl",
274
					Pod: &tetragon.Pod{
275
						Namespace: "kube-system",
276
						Name:      "tetragon",
277
					},
278
				},
279
				FunctionName: "__x64_sys_close",
280
				Args: []*tetragon.KprobeArgument{
281
					{Arg: &tetragon.KprobeArgument_FileArg{FileArg: &tetragon.KprobeFile{Path: "/etc/password"}}},
282
				},
283
			},
284
		},
285
	})
286
	assert.NoError(t, err)
287
	assert.Equal(t, "📪 close   kube-system/tetragon /usr/bin/curl /etc/password", result)
288
}
289

290
func TestCompactEncoder_KprobeBPFEventToString(t *testing.T) {
291
	p := NewCompactEncoder(os.Stdout, Never, false, false)
292

293
	// bpf with no args
294
	result, err := p.EventToString(&tetragon.GetEventsResponse{
295
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
296
			ProcessKprobe: &tetragon.ProcessKprobe{
297
				Process: &tetragon.Process{
298
					Binary: "/usr/bin/bpftool",
299
					Pod: &tetragon.Pod{
300
						Namespace: "kube-system",
301
						Name:      "tetragon",
302
					},
303
				},
304
				FunctionName: "bpf_check",
305
			},
306
		}})
307
	assert.NoError(t, err)
308
	assert.Equal(t, "🐝 bpf_load kube-system/tetragon /usr/bin/bpftool ", result)
309

310
	// bpf with args
311
	result, err = p.EventToString(&tetragon.GetEventsResponse{
312
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
313
			ProcessKprobe: &tetragon.ProcessKprobe{
314
				Process: &tetragon.Process{
315
					Binary: "/usr/bin/bpftool",
316
					Pod: &tetragon.Pod{
317
						Namespace: "kube-system",
318
						Name:      "tetragon",
319
					},
320
				},
321
				FunctionName: "bpf_check",
322
				Args: []*tetragon.KprobeArgument{
323
					{Arg: &tetragon.KprobeArgument_BpfAttrArg{
324
						BpfAttrArg: &tetragon.KprobeBpfAttr{
325
							ProgType: "BPF_PROG_TYPE_KPROBE",
326
							InsnCnt:  2048,
327
							ProgName: "amazing-program",
328
						},
329
					},
330
					},
331
				},
332
			},
333
		}})
334
	assert.NoError(t, err)
335
	assert.Equal(t, "🐝 bpf_load kube-system/tetragon /usr/bin/bpftool BPF_PROG_TYPE_KPROBE amazing-program instruction count 2048", result)
336
}
337

338
func TestCompactEncoder_KprobePerfEventAllocEventToString(t *testing.T) {
339
	p := NewCompactEncoder(os.Stdout, Never, false, false)
340

341
	// perf event alloc with no args
342
	result, err := p.EventToString(&tetragon.GetEventsResponse{
343
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
344
			ProcessKprobe: &tetragon.ProcessKprobe{
345
				Process: &tetragon.Process{
346
					Binary: "/usr/bin/bpftool",
347
					Pod: &tetragon.Pod{
348
						Namespace: "kube-system",
349
						Name:      "tetragon",
350
					},
351
				},
352
				FunctionName: "security_perf_event_alloc",
353
			},
354
		}})
355
	assert.NoError(t, err)
356
	assert.Equal(t, "🐝 perf_event_alloc kube-system/tetragon /usr/bin/bpftool ", result)
357

358
	// perf event alloc with args
359
	result, err = p.EventToString(&tetragon.GetEventsResponse{
360
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
361
			ProcessKprobe: &tetragon.ProcessKprobe{
362
				Process: &tetragon.Process{
363
					Binary: "/usr/bin/bpftool",
364
					Pod: &tetragon.Pod{
365
						Namespace: "kube-system",
366
						Name:      "tetragon",
367
					},
368
				},
369
				FunctionName: "security_perf_event_alloc",
370
				Args: []*tetragon.KprobeArgument{
371
					{Arg: &tetragon.KprobeArgument_PerfEventArg{
372
						PerfEventArg: &tetragon.KprobePerfEvent{
373
							KprobeFunc: "commit_creds",
374
							Type:       "PERF_TYPE_TRACEPOINT",
375
						},
376
					},
377
					},
378
				},
379
			},
380
		}})
381
	assert.NoError(t, err)
382
	assert.Equal(t, "🐝 perf_event_alloc kube-system/tetragon /usr/bin/bpftool PERF_TYPE_TRACEPOINT commit_creds", result)
383
}
384

385
func TestCompactEncoder_KprobeBPFMapAllocEventToString(t *testing.T) {
386
	p := NewCompactEncoder(os.Stdout, Never, false, false)
387

388
	// bpf map with no args
389
	result, err := p.EventToString(&tetragon.GetEventsResponse{
390
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
391
			ProcessKprobe: &tetragon.ProcessKprobe{
392
				Process: &tetragon.Process{
393
					Binary: "/usr/bin/bpftool",
394
					Pod: &tetragon.Pod{
395
						Namespace: "kube-system",
396
						Name:      "tetragon",
397
					},
398
				},
399
				FunctionName: "security_bpf_map_alloc",
400
			},
401
		}})
402
	assert.NoError(t, err)
403
	assert.Equal(t, "🗺 bpf_map_create kube-system/tetragon /usr/bin/bpftool ", result)
404

405
	// bpf map with args
406
	result, err = p.EventToString(&tetragon.GetEventsResponse{
407
		Event: &tetragon.GetEventsResponse_ProcessKprobe{
408
			ProcessKprobe: &tetragon.ProcessKprobe{
409
				Process: &tetragon.Process{
410
					Binary: "/usr/bin/bpftool",
411
					Pod: &tetragon.Pod{
412
						Namespace: "kube-system",
413
						Name:      "tetragon",
414
					},
415
				},
416
				FunctionName: "security_bpf_map_alloc",
417
				Args: []*tetragon.KprobeArgument{
418
					{Arg: &tetragon.KprobeArgument_BpfMapArg{
419
						BpfMapArg: &tetragon.KprobeBpfMap{
420
							MapType:    "BPF_MAP_TYPE_HASH",
421
							KeySize:    8,
422
							ValueSize:  8,
423
							MaxEntries: 1024,
424
							MapName:    "amazing-map",
425
						},
426
					},
427
					},
428
				},
429
			},
430
		}})
431
	assert.NoError(t, err)
432
	assert.Equal(t, "🗺 bpf_map_create kube-system/tetragon /usr/bin/bpftool BPF_MAP_TYPE_HASH amazing-map key size 8 value size 8 max entries 1024", result)
433
}
434

435
func TestCompactEncoder_Encode(t *testing.T) {
436
	var b bytes.Buffer
437
	p := NewCompactEncoder(&b, Never, false, false)
438

439
	// invalid event
440
	err := p.Encode(nil)
441
	assert.Error(t, err)
442

443
	// more invalid event
444
	err = p.Encode(&tetragon.GetEventsResponse{})
445
	assert.Error(t, err)
446

447
	// valid event
448
	err = p.Encode(&tetragon.GetEventsResponse{
449
		Event: &tetragon.GetEventsResponse_ProcessExec{
450
			ProcessExec: &tetragon.ProcessExec{
451
				Process: &tetragon.Process{
452
					Binary:    "/usr/bin/curl",
453
					Arguments: "cilium.io",
454
					Pod: &tetragon.Pod{
455
						Namespace: "kube-system",
456
						Name:      "tetragon",
457
					},
458
				},
459
			},
460
		},
461
	})
462
	assert.NoError(t, err)
463
	assert.Equal(t, "🚀 process kube-system/tetragon /usr/bin/curl cilium.io\n", b.String())
464
}
465

466
func TestCompactEncoder_EncodeWithTimestamp(t *testing.T) {
467
	var b bytes.Buffer
468
	p := NewCompactEncoder(&b, Never, true, false)
469

470
	// invalid event
471
	err := p.Encode(nil)
472
	assert.Error(t, err)
473

474
	// more invalid event
475
	err = p.Encode(&tetragon.GetEventsResponse{})
476
	assert.Error(t, err)
477

478
	// valid event
479
	err = p.Encode(&tetragon.GetEventsResponse{
480
		Event: &tetragon.GetEventsResponse_ProcessExec{
481
			ProcessExec: &tetragon.ProcessExec{
482
				Process: &tetragon.Process{
483
					Binary:    "/usr/bin/curl",
484
					Arguments: "cilium.io",
485
					Pod: &tetragon.Pod{
486
						Namespace: "kube-system",
487
						Name:      "tetragon",
488
					},
489
				},
490
			},
491
		},
492
		Time: &timestamppb.Timestamp{},
493
	})
494
	assert.NoError(t, err)
495
	assert.Equal(t, "1970-01-01T00:00:00.000000000Z 🚀 process kube-system/tetragon /usr/bin/curl cilium.io\n", b.String())
496
}
497

498
func FuzzProtojsonCompatibility(f *testing.F) {
499
	for _, n := range []int64{
500
		1337,
501
		78776406,
502
		56343416,
503
		68876713,
504
		51156281,
505
		45544244,
506
		4011756,
507
	} {
508
		f.Add(n)
509
	}
510
	f.Fuzz(func(t *testing.T, seed int64) {
511
		pr := protorand.New()
512
		pr.Seed(seed)
513
		ev := &tetragon.GetEventsResponse{}
514
		msg, err := pr.Gen(ev)
515
		require.NoError(t, err)
516

517
		var buf1 bytes.Buffer
518
		protojsonEncoder := NewProtojsonEncoder(&buf1)
519
		err = protojsonEncoder.Encode(msg)
520
		require.NoError(t, err)
521

522
		var buf2 bytes.Buffer
523
		jsonEncoder := json.NewEncoder(&buf2)
524
		err = jsonEncoder.Encode(msg)
525
		require.NoError(t, err)
526

527
		msgProtojson := &tetragon.GetEventsResponse{}
528
		err = protojson.Unmarshal(buf2.Bytes(), msgProtojson)
529
		require.NoError(t, err)
530
		msgJson := &tetragon.GetEventsResponse{}
531
		err = json.Unmarshal(buf2.Bytes(), msgJson)
532
		require.NoError(t, err)
533

534
		assert.True(t, proto.Equal(msgJson, msgProtojson))
535
		assert.True(t, proto.Equal(msg, msgProtojson))
536
	})
537
}
538

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

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

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

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