Skip to content

Commit

Permalink
fix: update selector_filter index assignment to use sel->index
Browse files Browse the repository at this point in the history
Signed-off-by: arthur-zhang <[email protected]>
  • Loading branch information
arthur-zhang committed Jan 6, 2025
1 parent c3df31c commit ac4f9c7
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 1 deletion.
4 changes: 4 additions & 0 deletions bpf/process/pfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,15 +342,19 @@ selector_match(__u32 *f, struct selector_filter *sel,
four:
res4 = process_filter(sel, f, enter, &msg->ns, &msg->caps);
index = next_pid_value(index, f, ty);
sel->index = index;
three:
res3 = process_filter(sel, f, enter, &msg->ns, &msg->caps);
index = next_pid_value(index, f, ty);
sel->index = index;
two:
res2 = process_filter(sel, f, enter, &msg->ns, &msg->caps);
index = next_pid_value(index, f, ty);
sel->index = index;
one:
res1 = process_filter(sel, f, enter, &msg->ns, &msg->caps);
index = next_pid_value(index, f, ty);
sel->index = index;

if (ty == op_filter_notin)
return res1 & res2 & res3 & res4;
Expand Down
2 changes: 1 addition & 1 deletion bpf/tests/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include ../Makefile.defs

TESTS = prepend_name_test.o
TESTS = prepend_name_test.o pid_match_test.o

OBJSDIR := objs/
OBJS := $(addprefix $(OBJSDIR),$(TESTS))
Expand Down
63 changes: 63 additions & 0 deletions bpf/tests/pid_match_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright Authors of Cilium */

//go:build ignore

#include "vmlinux.h"
#include "compiler.h"
#include "bpf_core_read.h"
#include "bpf_helpers.h"
#include "process/retprobe_map.h"

#include "process/types/basic.h"
#include "process/generic_calls.h"
#include "process/pfilter.h"

char _license[] __attribute__((section("license"), used)) = "Dual BSD/GPL";

struct filter_map_value {
unsigned char buf[FILTER_SIZE];
};

struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 1);
__type(key, int);
__type(value, struct filter_map_value);
} test_filter_map SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 1);
__type(key, __u32);
__type(value, int);
} test_result_map SEC(".maps");

__attribute__((section("raw_tracepoint/test"), used)) int
test_pid_match()
{
int zero = 0;
__u32 *f = map_lookup_elem(&test_filter_map, &zero);
if (!f) {
return 0;
}
struct pid_filter *pid;
int index = 0;
struct execve_map_value *enter;
pid = (struct pid_filter *)((u64)f + index);
index += sizeof(struct pid_filter);
struct selector_filter sel = {
.index = index,
.ty = pid->op,
.flags = pid->flags,
.len = pid->len,
};

enter = map_lookup_elem(&execve_map, &zero);
if (!enter) {
return 0;
}
int res = selector_match(f, &sel, enter, NULL, &process_filter_pid);
map_update_elem(&test_result_map, &zero, &res, BPF_ANY);
return 0;
}
112 changes: 112 additions & 0 deletions bpf/tests/pid_match_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Tetragon

package bpf

import (
"errors"
"testing"

"github.com/cilium/ebpf"
"github.com/cilium/tetragon/pkg/api/processapi"
"github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1"
"github.com/cilium/tetragon/pkg/selectors"
"github.com/cilium/tetragon/pkg/sensors/exec/execvemap"
"github.com/stretchr/testify/assert"
)

const (
programNamePidMatch = "test_pid_match"
)

func Test_PidMatch(t *testing.T) {
coll, err := ebpf.LoadCollection("objs/pid_match_test.o")
if err != nil {
var ve *ebpf.VerifierError
if errors.As(err, &ve) {
t.Fatalf("verifier error: %+v\n", ve)
}
t.Fatal(err)
}
defer coll.Close()

prog, ok := coll.Programs[programNamePidMatch]
assert.True(t, ok, "program %s not found", programNamePidMatch)

execvMap, ok := coll.Maps["execve_map"]
assert.True(t, ok, "execve_map not found")

resultMap, ok := coll.Maps["test_result_map"]
assert.True(t, ok, "test_result_map not found")

runProg := func(selfPid uint32) {
err := execvMap.Update(uint32(0), &execvemap.ExecveValue{
Process: processapi.MsgExecveKey{Pid: selfPid},
}, 0)
assert.NoError(t, err)
prog.Run(&ebpf.RunOptions{})
}
getResult := func() int32 {
var res int32
err = resultMap.Lookup(uint32(0), &res)
assert.NoError(t, err)
return res
}

initKernelStatedata := func(pids []uint32) {
k := &selectors.KernelSelectorState{}
err := selectors.ParseMatchPid(k,
&v1alpha1.PIDSelector{
Operator: "In",
Values: pids,
IsNamespacePID: false,
FollowForks: false})
assert.NoError(t, err)
filterMap, ok := coll.Maps["test_filter_map"]
assert.True(t, ok, "test_filter_map not found")
err = filterMap.Update(uint32(0), k.Buffer(), 0)
assert.NoError(t, err)
}

resetResult := func() {
err := resultMap.Update(uint32(0), int32(-1), 0)
assert.NoError(t, err)
}

t.Run("Match_1_PID", func(t *testing.T) {
resetResult()
initKernelStatedata([]uint32{1})
runProg(1)
result := getResult()
assert.Equal(t, int32(1), result)
})
t.Run("Match_2_PID", func(t *testing.T) {
resetResult()
initKernelStatedata([]uint32{1, 2})
runProg(2)
result := getResult()
assert.Equal(t, int32(1), result)
})
t.Run("Match_2_PID_NOT_IN_LIST", func(t *testing.T) {
resetResult()
initKernelStatedata([]uint32{1, 2})
runProg(3)
result := getResult()
assert.Equal(t, int32(0), result)
})

t.Run("Match_4_PID", func(t *testing.T) {
resetResult()
initKernelStatedata([]uint32{1, 2, 3, 4})
runProg(4)
result := getResult()
assert.Equal(t, int32(1), result)
})
t.Run("Match_4_PID_NOT_IN_LIST", func(t *testing.T) {
initKernelStatedata([]uint32{1, 2, 3, 4})
resetResult()
runProg(5)
result := getResult()
assert.Equal(t, int32(0), result)
})
}

0 comments on commit ac4f9c7

Please sign in to comment.