Skip to content

Commit

Permalink
policyconf: policy mode test (override, enforcer)
Browse files Browse the repository at this point in the history
Add a second test for the policy mode test. This test the override and
enforcer actions. Because they do not kill the process, the way we check
for them is different than the sigkill test.

For override, we just check the error that is printed in stdout.
For enforcer, we check the enforcer map contents.

Signed-off-by: Kornilios Kourtis <kornilios@isovalent.com>
  • Loading branch information
kkourt committed Feb 20, 2025
1 parent 5371db5 commit 8384df4
Showing 1 changed file with 117 additions and 2 deletions.
119 changes: 117 additions & 2 deletions pkg/policyconf/test/mode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import (
"github.com/cilium/tetragon/pkg/logger"
"github.com/cilium/tetragon/pkg/policyconf"
"github.com/cilium/tetragon/pkg/reader/notify"
_ "github.com/cilium/tetragon/pkg/sensors/exec" // NB: needed so that the exec sensor can load the execve probe on its init
_ "github.com/cilium/tetragon/pkg/sensors/tracing" // NB: needed so that the exec tracing sensor can load its policy handlers on init
_ "github.com/cilium/tetragon/pkg/sensors/exec" // NB: needed so that the exec sensor can load the execve probe on its init
stracing "github.com/cilium/tetragon/pkg/sensors/tracing" // NB: needed so that the exec tracing sensor can load its policy handlers on init
"github.com/cilium/tetragon/pkg/testutils"
"github.com/cilium/tetragon/pkg/testutils/perfring"
pft "github.com/cilium/tetragon/pkg/testutils/policyfilter/tester"
Expand Down Expand Up @@ -118,3 +118,118 @@ func TestModeSigKill(t *testing.T) {
policyconf.SetPolicyMode(tp, policyconf.EnforceMode)
checkEnforce()
}

func TestModeEnforcer(t *testing.T) {
// NB: the policy below checks for both enforcer and override at the same time, which is why
// we need both (and, also, why fmod_ret is not enough)
if !bpf.HasSignalHelper() {
t.Skip("skipping test, bpf_send_signal helper not available")
}
if !bpf.HasOverrideHelper() {
t.Skip("skipping test, neither bpf_override_return not available")
}

testutils.CaptureLog(t, logger.GetLogger().(*logrus.Logger))
ctx, cancel := context.WithTimeout(context.Background(), tus.Conf().CmdWaitTime)
defer cancel()

pft := pft.Start(t, ctx)

polName := "tp-test"
polNamespace := "namespace"
tp := &tracingpolicy.GenericTracingPolicyNamespaced{
Metadata: v1.ObjectMeta{
Name: polName,
Namespace: polNamespace,
},
Spec: v1alpha1.TracingPolicySpec{
Enforcers: []v1alpha1.EnforcerSpec{{
// NB: add another enforcer call so that we can just check the map
Calls: []string{"sys_lseek"},
}},
KProbes: []v1alpha1.KProbeSpec{{
Call: "sys_getcpu",
Return: true,
Syscall: true,
ReturnArg: &v1alpha1.KProbeArg{
Index: 0,
Type: "int",
},
Selectors: []v1alpha1.KProbeSelector{{
MatchActions: []v1alpha1.ActionSelector{
{Action: "NotifyEnforcer", ArgSig: 9},
{Action: "Override", ArgError: -1},
},
}},
}},
},
}

pft.AddPolicy(t, ctx, tp)

pid := pft.ProgTester.Cmd.Process.Pid

var cmdOut string
var cmdErr error
ops := func() {
cmdOut, cmdErr = pft.ProgTester.Command("getcpu")
t.Logf("command getcpu out:%q err:%v", cmdOut, cmdErr)
}

checkEnforce := func() {
cnt := perfring.RunTestEventReduceCount(t, ctx, ops, perfring.FilterTestMessages,
func(x notify.Message) int {
if kprobe, ok := x.(*tracing.MsgGenericKprobeUnix); ok {
if strings.HasSuffix(kprobe.FuncName, "sys_getcpu") {
return 1
}
return -1
}
return 0
})
require.NoError(t, cmdErr)
require.Equal(t, cnt[1], 1, fmt.Sprintf("count=%v", cnt))
enfDump, enfDumpErr := stracing.DumpEnforcerMap(polName, polNamespace)
require.NoError(t, enfDumpErr)
require.Len(t, enfDump, 1)
require.Contains(t, cmdOut, "operation not permitted")
for key, val := range enfDump {
require.Equal(t, pid, int(key.PidTgid>>32))
require.Equal(t, val.Sig, int16(9))
break
}
}

resetEnforcerMap := func() {
err := stracing.ResetEnforcerMap(t, polName, polNamespace)
require.NoError(t, err)
}

checkMonitor := func() {
cnt := perfring.RunTestEventReduceCount(t, ctx, ops, perfring.FilterTestMessages,
func(x notify.Message) int {
if kprobe, ok := x.(*tracing.MsgGenericKprobeUnix); ok {
if strings.HasSuffix(kprobe.FuncName, "sys_getcpu") {
return 1
}
return -1
}
return 0
})
require.NoError(t, cmdErr)
require.Equal(t, cnt[1], 1, fmt.Sprintf("count=%v", cnt))
require.NotContains(t, cmdOut, "operation not permitted")
enfDump, enfDumpErr := stracing.DumpEnforcerMap(polName, polNamespace)
require.NoError(t, enfDumpErr)
require.Len(t, enfDump, 0)
}

// finally, we can do the test
checkEnforce()
resetEnforcerMap()
policyconf.SetPolicyMode(tp, policyconf.MonitorMode)
checkMonitor()
resetEnforcerMap()
policyconf.SetPolicyMode(tp, policyconf.EnforceMode)
checkEnforce()
}

0 comments on commit 8384df4

Please sign in to comment.