Skip to content

Commit

Permalink
tetragon: Add killer tests
Browse files Browse the repository at this point in the history
Adding test for killer sensor and testing both killing
application matching the selector and overriding syscall
that matches the selector.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
  • Loading branch information
olsajiri committed Oct 7, 2023
1 parent 495d8b9 commit 1c28428
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 1 deletion.
3 changes: 2 additions & 1 deletion contrib/tester-progs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ PROGS = sigkill-tester \
lseek-pipe \
threads-tester \
bench-reader \
threads-exit
threads-exit \
killer-tester

all: $(PROGS)

Expand Down
9 changes: 9 additions & 0 deletions contrib/tester-progs/killer-tester.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <stdio.h>
#include <sys/prctl.h>
#include <errno.h>

int main(void)
{
prctl(0xffff, 0, 0, 0, 0);
return errno;
}
221 changes: 221 additions & 0 deletions pkg/sensors/tracing/killer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Tetragon

package tracing

import (
"context"
"os"
"os/exec"
"sync"
"syscall"
"testing"

"github.com/cilium/tetragon/api/v1/tetragon"
"github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker"
ec "github.com/cilium/tetragon/api/v1/tetragon/codegen/eventchecker"
"github.com/cilium/tetragon/pkg/bpf"
"github.com/cilium/tetragon/pkg/jsonchecker"
lc "github.com/cilium/tetragon/pkg/matchers/listmatcher"
"github.com/cilium/tetragon/pkg/observer/observertesthelper"
"github.com/cilium/tetragon/pkg/testutils"
tus "github.com/cilium/tetragon/pkg/testutils/sensors"
"github.com/stretchr/testify/assert"
)

func test_killer(t *testing.T, configHook string, test string,
checker *eventchecker.UnorderedEventChecker,
checkerFunc func(err error, rc int)) {

var doneWG, readyWG sync.WaitGroup
defer doneWG.Wait()

ctx, cancel := context.WithTimeout(context.Background(), tus.Conf().CmdWaitTime)
defer cancel()

err := os.WriteFile(testConfigFile, []byte(configHook), 0644)
if err != nil {
t.Fatalf("writeFile(%s): err %s", testConfigFile, err)
}

obs, err := observertesthelper.GetDefaultObserverWithFile(t, ctx, testConfigFile, tus.Conf().TetragonLib, observertesthelper.WithMyPid())
if err != nil {
t.Fatalf("GetDefaultObserverWithFile error: %s", err)
}
observertesthelper.LoopEvents(ctx, t, &doneWG, &readyWG, obs)
readyWG.Wait()

cmd := exec.Command(test)
err = cmd.Run()

checkerFunc(err, cmd.ProcessState.ExitCode())

err = jsonchecker.JsonTestCheck(t, checker)
assert.NoError(t, err)
}

func TestKillerOverride(t *testing.T) {
if !bpf.HasOverrideHelper() {
t.Skip("skipping killer test, bpf_override_return helper not available")
}

test := testutils.RepoRootPath("contrib/tester-progs/killer-tester")
configHook := `
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: "kill-syscalls"
spec:
lists:
- name: "mine"
type: "syscalls"
values:
- "sys_prctl"
killers:
- syscalls:
- "list:mine"
tracepoints:
- subsystem: "raw_syscalls"
event: "sys_enter"
args:
- index: 4
type: "uint64"
selectors:
- matchArgs:
- index: 0
operator: "InMap"
values:
- "list:mine"
matchBinaries:
- operator: "In"
values:
- "` + test + `"
matchActions:
- action: "NotifyKiller"
argError: -17 # EEXIST
`

tpChecker := ec.NewProcessTracepointChecker("").
WithArgs(ec.NewKprobeArgumentListMatcher().
WithOperator(lc.Ordered).
WithValues(
ec.NewKprobeArgumentChecker().WithSizeArg(syscall.SYS_PRCTL),
)).
WithAction(tetragon.KprobeAction_KPROBE_ACTION_NOTIFYKILLER)

checker := ec.NewUnorderedEventChecker(tpChecker)

checkerFunc := func(err error, rc int) {
if rc != int(syscall.EEXIST) {
t.Fatalf("Wrong exit code %d expected %d", rc, int(syscall.EEXIST))
}
}

test_killer(t, configHook, test, checker, checkerFunc)
}

func TestKillerSignal(t *testing.T) {
if !bpf.HasOverrideHelper() {
t.Skip("skipping killer test, bpf_override_return helper not available")
}

test := testutils.RepoRootPath("contrib/tester-progs/killer-tester")
configHook := `
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: "kill-syscalls"
spec:
lists:
- name: "mine"
type: "syscalls"
values:
- "sys_prctl"
killers:
- syscalls:
- "list:mine"
tracepoints:
- subsystem: "raw_syscalls"
event: "sys_enter"
args:
- index: 4
type: "uint64"
selectors:
- matchArgs:
- index: 0
operator: "InMap"
values:
- "list:mine"
matchBinaries:
- operator: "In"
values:
- "` + test + `"
matchActions:
- action: "NotifyKiller"
argSig: 9 # SIGKILL
`

tpChecker := ec.NewProcessTracepointChecker("").
WithArgs(ec.NewKprobeArgumentListMatcher().
WithOperator(lc.Ordered).
WithValues(
ec.NewKprobeArgumentChecker().WithSizeArg(syscall.SYS_PRCTL),
)).
WithAction(tetragon.KprobeAction_KPROBE_ACTION_NOTIFYKILLER)

checker := ec.NewUnorderedEventChecker(tpChecker)

checkerFunc := func(err error, rc int) {
if err == nil || err.Error() != "signal: killed" {
t.Fatalf("Wrong error '%v' expected 'killed'", err)
}
}

test_killer(t, configHook, test, checker, checkerFunc)
}

func TestKillerMulti(t *testing.T) {
if !bpf.HasOverrideHelper() {
t.Skip("skipping killer test, bpf_override_return helper not available")
}

crd := `
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
name: "kill-syscalls"
spec:
lists:
- name: "mine1"
type: "syscalls"
values:
- "sys_prctl"
- name: "mine2"
type: "syscalls"
values:
- "sys_prctl"
killers:
- syscalls:
- "list:mine1"
- syscalls:
- "list:mine2"
tracepoints:
- subsystem: "raw_syscalls"
event: "sys_enter"
args:
- index: 4
type: "uint64"
selectors:
- matchArgs:
- index: 0
operator: "InMap"
values:
- "list:mine1"
matchActions:
- action: "NotifyKiller"
argSig: 9 # SIGKILL
`

err := checkCrd(t, crd)
assert.Error(t, err)
}

0 comments on commit 1c28428

Please sign in to comment.