diff --git a/bpf/Makefile b/bpf/Makefile index ff53d8866e5..1c2d9595812 100644 --- a/bpf/Makefile +++ b/bpf/Makefile @@ -28,7 +28,8 @@ PROCESS = bpf_execve_event.o bpf_execve_event_v53.o bpf_fork.o bpf_exit.o bpf_ge bpf_generic_uprobe_v511.o \ bpf_loader.o \ bpf_cgroup.o \ - bpf_enforcer.o bpf_multi_enforcer.o bpf_fmodret_enforcer.o + bpf_enforcer.o bpf_multi_enforcer.o bpf_fmodret_enforcer.o \ + bpf_map_test_p1.o bpf_map_test_p2.o CGROUP = bpf_cgroup_mkdir.o bpf_cgroup_rmdir.o bpf_cgroup_release.o BPFTEST = bpf_lseek.o diff --git a/bpf/process/bpf_map_test_p1.c b/bpf/process/bpf_map_test_p1.c new file mode 100644 index 00000000000..ecf6eca49f4 --- /dev/null +++ b/bpf/process/bpf_map_test_p1.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* Copyright Authors of Cilium */ + +#include "vmlinux.h" +#include "api.h" +#include "bpf_tracing.h" +#include "bpf_helpers.h" +#include "compiler.h" + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, int); + __type(value, int); +} m1 SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, int); + __type(value, int); +} m2 SEC(".maps"); + +__attribute__((section("kprobe/wake_up_new_task"), used)) int +BPF_KPROBE(p1) +{ + map_lookup_elem(&m1, &(int){ 0 }); + map_lookup_elem(&m2, &(int){ 0 }); + return 0; +} diff --git a/bpf/process/bpf_map_test_p2.c b/bpf/process/bpf_map_test_p2.c new file mode 100644 index 00000000000..42c20563a6c --- /dev/null +++ b/bpf/process/bpf_map_test_p2.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* Copyright Authors of Cilium */ + +#include "vmlinux.h" +#include "api.h" +#include "bpf_tracing.h" +#include "bpf_helpers.h" +#include "compiler.h" + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, int); + __type(value, int); +} m1 SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 1); + __type(key, int); + __type(value, int); +} m2 SEC(".maps"); + +__attribute__((section("kprobe/wake_up_new_task"), used)) int +BPF_KPROBE(p2) +{ + map_lookup_elem(&m1, &(int){ 0 }); + map_lookup_elem(&m2, &(int){ 0 }); + return 0; +} diff --git a/pkg/sensors/test/sensors_test.go b/pkg/sensors/test/sensors_test.go new file mode 100644 index 00000000000..099b44f1456 --- /dev/null +++ b/pkg/sensors/test/sensors_test.go @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Authors of Tetragon + +package test + +import ( + "path/filepath" + "testing" + + "github.com/cilium/tetragon/pkg/bpf" + "github.com/cilium/tetragon/pkg/option" + "github.com/cilium/tetragon/pkg/sensors" + "github.com/cilium/tetragon/pkg/sensors/program" + tus "github.com/cilium/tetragon/pkg/testutils/sensors" + "github.com/stretchr/testify/assert" +) + +func TestMapBuildersSingle(t *testing.T) { + option.Config.HubbleLib = tus.Conf().TetragonLib + option.Config.Verbosity = 5 + + p1 := program.Builder( + "bpf_map_test_p1.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p1", + "kprobe", + ) + + test := func(m1 *program.Map, ty program.MapType) { + s := &sensors.Sensor{ + Name: "sensor", + Progs: []*program.Program{p1}, + Maps: []*program.Map{m1}, + Policy: "policy", + } + + getMapPath := func(m *program.Map) string { + path := "./" + switch ty { + case program.MapTypeGlobal: + // nothing + case program.MapTypePolicy: + path = filepath.Join(path, "policy") + case program.MapTypeSensor: + path = filepath.Join(path, "policy", "sensor") + case program.MapTypeProgram: + path = filepath.Join(path, "policy", "sensor", m.Prog.PinName) + } + return filepath.Join(path, m.Name) + } + + s.Load(bpf.MapPrefixPath()) + + assert.Equal(t, getMapPath(m1), m1.PinPath) + + s.Unload() + } + + test(program.MapBuilder("m1", p1), program.MapTypeGlobal) + test(program.MapBuilderProgram("m1", p1), program.MapTypeProgram) + test(program.MapBuilderSensor("m1", p1), program.MapTypeSensor) + test(program.MapBuilderPolicy("m1", p1), program.MapTypePolicy) +} + +func TestMapBuildersMulti(t *testing.T) { + option.Config.HubbleLib = tus.Conf().TetragonLib + option.Config.Verbosity = 5 + + p1 := program.Builder( + "bpf_map_test_p1.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p1", + "kprobe", + ) + + p2 := program.Builder( + "bpf_map_test_p2.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p2", + "kprobe", + ) + + test := func(m1, m2 *program.Map, path1, path2 string) { + s := &sensors.Sensor{ + Name: "sensor", + Progs: []*program.Program{p1, p2}, + Maps: []*program.Map{m1, m2}, + Policy: "policy", + } + + s.Load(bpf.MapPrefixPath()) + + assert.Equal(t, path1, m1.PinPath) + assert.Equal(t, path2, m2.PinPath) + + s.Unload() + } + + var m1 *program.Map + var m2 *program.Map + + // NOTE For program.MapBuilderProgram the map takes the + // first program as the base for its path + + // m1: policy/sensor/p1/m1 + // m2: policy/sensor/p2/m2 + m1 = program.MapBuilderProgram("m1", p1, p2) + m2 = program.MapBuilderProgram("m2", p2, p1) + + test(m1, m2, "policy/sensor/p1/m1", "policy/sensor/p2/m2") + + // m1: policy/m1 + // m2: policy/m2 + m1 = program.MapBuilderPolicy("m1", p1, p2) + m2 = program.MapBuilderPolicy("m2", p2, p1) + + test(m1, m2, "policy/m1", "policy/m2") + + // m1: policy/sensor/p1/m1 + // m2: policy/m2 + m1 = program.MapBuilderProgram("m1", p1, p2) + m2 = program.MapBuilderPolicy("m2", p2, p1) + + test(m1, m2, "policy/sensor/p1/m1", "policy/m2") + + // m1: policy/sensor/p1/m1 + // m2: policy/m2 + m1 = program.MapBuilderSensor("m1", p2, p1) + m2 = program.MapBuilderPolicy("m2", p2, p1) + + test(m1, m2, "policy/sensor/m1", "policy/m2") +} + +func TestPolicyMapPath(t *testing.T) { + option.Config.HubbleLib = tus.Conf().TetragonLib + option.Config.Verbosity = 5 + + p1 := program.Builder( + "bpf_map_test_p1.o", + "wake_up_new_task", + "kprobe/wake_up_new_task", + "p1", + "kprobe", + ) + + m1 := program.MapBuilderPolicy("m1", p1) + + s := &sensors.Sensor{ + Name: "sensor", + Progs: []*program.Program{p1}, + Maps: []*program.Map{m1}, + Policy: "policy", + } + + s.Load(bpf.MapPrefixPath()) + + assert.Equal(t, filepath.Join(bpf.MapPrefixPath(), m1.PinPath), program.PolicyMapPath(bpf.MapPrefixPath(), "policy", "m1")) + + s.Unload() +}