From 0e0f82407adc78ceab57e54c69c5903822b39de5 Mon Sep 17 00:00:00 2001 From: Ben Segall Date: Wed, 28 Aug 2024 15:54:07 +0000 Subject: [PATCH] tracing: add flags to reject policies with signal and override actions This patch allows disabling of the 2 action types that allow modification of syscall behaviour. This is desirable in certain scenarios to prevent privilage escalation via loading policies via the gRPC API. This patch implements this by adding 2 flags to the tetragon binary --disable-signal-actions which causes tetragon to reject any policy that specifies `Signal` or `Sigkill` actions --disable-override-actions which causes tetragon to reject any policy that specifies `Override` actions Rejection was preferred over silent removal of the disabled actions from the policy as that will have less unexpected behaviour. Signed-off-by: Ben Segall --- .../en/docs/concepts/enforcement/_index.md | 6 + pkg/option/config.go | 3 + pkg/option/flags.go | 10 + pkg/sensors/tracing/generickprobe.go | 4 + pkg/sensors/tracing/genericlsm.go | 3 + pkg/sensors/tracing/generictracepoint.go | 3 + pkg/sensors/tracing/genericuprobe.go | 6 + pkg/sensors/tracing/kprobe_validation_test.go | 142 +++++++++++++ pkg/sensors/tracing/lsm_test.go | 150 ++++++++++++++ pkg/sensors/tracing/selectors.go | 37 ++++ pkg/sensors/tracing/selectors_test.go | 115 +++++++++++ pkg/sensors/tracing/tracepoint_test.go | 190 ++++++++++++++++++ pkg/sensors/tracing/uprobe_test.go | 145 +++++++++++++ 13 files changed, 814 insertions(+) diff --git a/docs/content/en/docs/concepts/enforcement/_index.md b/docs/content/en/docs/concepts/enforcement/_index.md index 52522a38c09..bb486fd33a5 100644 --- a/docs/content/en/docs/concepts/enforcement/_index.md +++ b/docs/content/en/docs/concepts/enforcement/_index.md @@ -20,6 +20,9 @@ security check functions allow to change their return value in this manner. Deta can configure tracing policies to override the return value can be found in the [Override action]({{< ref "/docs/concepts/tracing-policy/selectors#override-action" >}}) documentation. +This behaviour can be disabled at the daemon level by setting the `--disable-override-actions` flag +which may be desirable to prevent privilage escalation via the gRPC API. + ## Signals Another type of enforcement is signals. For example, users can write a TracingPolicy (details can be @@ -33,3 +36,6 @@ However, it does ensure that the process is terminated synchronously (and any th stopped). In some cases it may be sufficient to ensure the process is stopped and the process does not handle the return of the call. To ensure the operation is not completed, though, the `Signal` action should be combined with the `Override` action. + +This behaviour can be disabled at the daemon level by setting the `--disable-signal-actions` flag +which may be desirable to prevent privilage escalation via the gRPC API. diff --git a/pkg/option/config.go b/pkg/option/config.go index 867acb91391..6f1de9d16b5 100644 --- a/pkg/option/config.go +++ b/pkg/option/config.go @@ -32,6 +32,9 @@ type config struct { DisableKprobeMulti bool + DisableOverrideActions bool + DisableSignalActions bool + GopsAddr string // On start used to store bpf prefix for --bpf-dir option, diff --git a/pkg/option/flags.go b/pkg/option/flags.go index 8ca55b50b0f..956ef00f12a 100644 --- a/pkg/option/flags.go +++ b/pkg/option/flags.go @@ -73,6 +73,9 @@ const ( KeyDisableKprobeMulti = "disable-kprobe-multi" KeyDisableUprobeMulti = "disable-uprobe-multi" + KeyDisableSignalActions = "disable-signal-actions" + KeyDisableOverrideActions = "disable-override-actions" + KeyRBSize = "rb-size" KeyRBSizeTotal = "rb-size-total" KeyRBQueueSize = "rb-queue-size" @@ -146,6 +149,9 @@ func ReadAndSetFlags() error { Config.DisableKprobeMulti = viper.GetBool(KeyDisableKprobeMulti) + Config.DisableSignalActions = viper.GetBool(KeyDisableSignalActions) + Config.DisableOverrideActions = viper.GetBool(KeyDisableOverrideActions) + var err error if Config.RBSize, err = strutils.ParseSize(viper.GetString(KeyRBSize)); err != nil { @@ -353,6 +359,10 @@ func AddFlags(flags *pflag.FlagSet) { // Allow to disable kprobe multi interface flags.Bool(KeyDisableKprobeMulti, false, "Allow to disable kprobe multi interface") + // Allow to disable override and signall selectors + flags.Bool(KeyDisableOverrideActions, false, "Allow to disable override action selectors") + flags.Bool(KeyDisableSignalActions, false, "Allow to disable sigkill and signal selectors") + // Allow to specify perf ring buffer size flags.String(KeyRBSizeTotal, "0", "Set perf ring buffer size in total for all cpus (default 65k per cpu, allows K/M/G suffix)") flags.String(KeyRBSize, "0", "Set perf ring buffer size for single cpu (default 65k, allows K/M/G suffix)") diff --git a/pkg/sensors/tracing/generickprobe.go b/pkg/sensors/tracing/generickprobe.go index a4c4fbff7b8..d801204cd64 100644 --- a/pkg/sensors/tracing/generickprobe.go +++ b/pkg/sensors/tracing/generickprobe.go @@ -450,6 +450,10 @@ func preValidateKprobes(name string, kprobes []v1alpha1.KProbeSpec, lists []v1al for i := range kprobes { f := &kprobes[i] + if err := validateActionSelectors(f.Selectors); err != nil { + return fmt.Errorf("validation failed: %w", err) + } + var list *v1alpha1.ListSpec // the f.Call is either defined as list:NAME diff --git a/pkg/sensors/tracing/genericlsm.go b/pkg/sensors/tracing/genericlsm.go index fff5316cd92..adcbf735603 100644 --- a/pkg/sensors/tracing/genericlsm.go +++ b/pkg/sensors/tracing/genericlsm.go @@ -146,6 +146,9 @@ func handleGenericLsm(r *bytes.Reader) ([]observer.Event, error) { } func isValidLsmSelectors(selectors []v1alpha1.KProbeSelector) error { + if err := validateActionSelectors(selectors); err != nil { + return fmt.Errorf("validation failed: %w", err) + } for _, s := range selectors { if len(s.MatchReturnArgs) > 0 { return fmt.Errorf("MatchReturnArgs selector is not supported") diff --git a/pkg/sensors/tracing/generictracepoint.go b/pkg/sensors/tracing/generictracepoint.go index a81ec1541fd..53a0f5eb089 100644 --- a/pkg/sensors/tracing/generictracepoint.go +++ b/pkg/sensors/tracing/generictracepoint.go @@ -371,6 +371,9 @@ func createGenericTracepointSensor( tracepoints := make([]*genericTracepoint, 0, len(confs)) for i := range confs { + if err := validateActionSelectors(confs[i].Selectors); err != nil { + return nil, fmt.Errorf("validation failed: %w", err) + } tp, err := createGenericTracepoint(name, &confs[i], policyID, policyName, customHandler) if err != nil { return nil, err diff --git a/pkg/sensors/tracing/genericuprobe.go b/pkg/sensors/tracing/genericuprobe.go index e7eca3e7c1e..72d4bcaca32 100644 --- a/pkg/sensors/tracing/genericuprobe.go +++ b/pkg/sensors/tracing/genericuprobe.go @@ -495,6 +495,12 @@ func (k *observerUprobeSensor) PolicyHandler( return nil, fmt.Errorf("uprobe sensor does not implement policy filtering") } + for _, probe := range spec.UProbes { + if err := validateActionSelectors(probe.Selectors); err != nil { + return nil, fmt.Errorf("validation failed: %w", err) + } + } + name := fmt.Sprintf("gup-sensor-%d", atomic.AddUint64(&sensorCounter, 1)) policyName := p.TpName() return createGenericUprobeSensor(name, spec, policyName) diff --git a/pkg/sensors/tracing/kprobe_validation_test.go b/pkg/sensors/tracing/kprobe_validation_test.go index 8ab9c7da7ab..bc6304dd417 100644 --- a/pkg/sensors/tracing/kprobe_validation_test.go +++ b/pkg/sensors/tracing/kprobe_validation_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/cilium/tetragon/pkg/kernels" + "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/sensors" "github.com/cilium/tetragon/pkg/tracingpolicy" "github.com/stretchr/testify/assert" @@ -205,6 +206,147 @@ spec: assert.Error(t, err) } +func TestKprobeValidationOverrideDisabled(t *testing.T) { + + // override on when override actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "list-syscalls" +spec: + kprobes: + - call: "sys_symlinkat" + selectors: + - matchActions: + - action: Override + argError: -1 +` + + oldDisableOverrideActions := option.Config.DisableOverrideActions + option.Config.DisableOverrideActions = true + t.Cleanup(func() { + option.Config.DisableOverrideActions = oldDisableOverrideActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestKprobeValidationSignalDisabled(t *testing.T) { + + // signal when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "list-syscalls" +spec: + kprobes: + - call: "sys_symlinkat" + selectors: + - matchActions: + - action: Signal + argSig: 9 +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestKprobeValidationSigkillDisabled(t *testing.T) { + + // sigkill when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "list-syscalls" +spec: + kprobes: + - call: "sys_symlinkat" + selectors: + - matchActions: + - action: Sigkill + argSig: 9 +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestKprobeValidationNotifyEnforcerSignalDisabled(t *testing.T) { + + // signal via notify enforcer when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "list-syscalls" +spec: + enforcers: + - calls: + - "sys_symlinkat" + kprobes: + - call: "sys_symlinkat" + selectors: + - matchActions: + - action: NotifyEnforcer + argSig: 9 +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestKprobeValidationNotifyEnforcerOverrideDisabled(t *testing.T) { + + // override via notify enforcer when overide actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "list-syscalls" +spec: + enforcers: + - calls: + - "sys_symlinkat" + kprobes: + - call: "sys_symlinkat" + selectors: + - matchActions: + - action: NotifyEnforcer + argError: -1 +` + + oldDisableOverrideActions := option.Config.DisableOverrideActions + option.Config.DisableOverrideActions = true + t.Cleanup(func() { + option.Config.DisableOverrideActions = oldDisableOverrideActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + func TestKprobeValidationNonSyscallOverride(t *testing.T) { // override on non syscall (non override-able) function diff --git a/pkg/sensors/tracing/lsm_test.go b/pkg/sensors/tracing/lsm_test.go index 5fee0397753..43d5f37fe78 100644 --- a/pkg/sensors/tracing/lsm_test.go +++ b/pkg/sensors/tracing/lsm_test.go @@ -20,6 +20,7 @@ import ( lc "github.com/cilium/tetragon/pkg/matchers/listmatcher" sm "github.com/cilium/tetragon/pkg/matchers/stringmatcher" "github.com/cilium/tetragon/pkg/observer/observertesthelper" + "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/sensors" "github.com/cilium/tetragon/pkg/testutils" tus "github.com/cilium/tetragon/pkg/testutils/sensors" @@ -236,3 +237,152 @@ spec: err = jsonchecker.JsonTestCheck(t, ec.NewUnorderedEventChecker(lsmChecker)) assert.NoError(t, err) } + +func TestLSMOverrideDisabled(t *testing.T) { + + // override on when override actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "lsm" +spec: + lsmhooks: + - hook: "bprm_check_security" + args: + - index: 0 + type: "linux_binprm" + selectors: + - matchActions: + - action: Override + argError: -1 +` + + oldDisableOverrideActions := option.Config.DisableOverrideActions + option.Config.DisableOverrideActions = true + t.Cleanup(func() { + option.Config.DisableOverrideActions = oldDisableOverrideActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestLSMSignalDisabled(t *testing.T) { + + // signal when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "lsm" +spec: + lsmhooks: + - hook: "bprm_check_security" + args: + - index: 0 + type: "linux_binprm" + selectors: + - matchActions: + - action: Signal + argSig: 9 +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestLSMSigkillDisabled(t *testing.T) { + + // sigkill when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "lsm" +spec: + lsmhooks: + - hook: "bprm_check_security" + args: + - index: 0 + type: "linux_binprm" + selectors: + - matchActions: + - action: Sigkill +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestLSMNotifyEnforcerSignalDisabled(t *testing.T) { + + // signal via notify enforcer when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "lsm" +spec: + lsmhooks: + - hook: "bprm_check_security" + args: + - index: 0 + type: "linux_binprm" + selectors: + - matchActions: + - action: NotifyEnforcer + argSig: 9 +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestLSMNotifyEnforcerOverrideDisabled(t *testing.T) { + + // override via notify enforcer when overide actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "lsm" +spec: + lsmhooks: + - hook: "bprm_check_security" + args: + - index: 0 + type: "linux_binprm" + selectors: + - matchActions: + - action: NotifyEnforcer + argError: -1 +` + + oldDisableOverrideActions := option.Config.DisableOverrideActions + option.Config.DisableOverrideActions = true + t.Cleanup(func() { + option.Config.DisableOverrideActions = oldDisableOverrideActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} diff --git a/pkg/sensors/tracing/selectors.go b/pkg/sensors/tracing/selectors.go index 06f432c803a..4f4dd3933f5 100644 --- a/pkg/sensors/tracing/selectors.go +++ b/pkg/sensors/tracing/selectors.go @@ -5,12 +5,15 @@ package tracing import ( "fmt" + "strings" "github.com/cilium/ebpf" "github.com/cilium/tetragon/pkg/api/processapi" "github.com/cilium/tetragon/pkg/bpf" + "github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1" "github.com/cilium/tetragon/pkg/kernels" "github.com/cilium/tetragon/pkg/mbset" + "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/selectors" "github.com/cilium/tetragon/pkg/sensors" "github.com/cilium/tetragon/pkg/sensors/program" @@ -571,3 +574,37 @@ func populateStringPostfixFilterMap( return nil } + +func validateActionSelectors(probes []v1alpha1.KProbeSelector) error { + for _, p := range probes { + selectors := p.MatchActions[:] + if p.MatchReturnActions != nil { + selectors = append(selectors, p.MatchReturnActions...) + } + for _, selector := range selectors { + switch strings.ToLower(selector.Action) { + case "sigkill": + if option.Config.DisableSignalActions { + return fmt.Errorf("sigkill actions are disabled") + } + case "signal": + if option.Config.DisableSignalActions { + return fmt.Errorf("signal actions are disabled") + } + case "override": + if option.Config.DisableOverrideActions { + return fmt.Errorf("override actions are disabled") + } + case "notifyenforcer": + if selector.ArgSig != 0 && option.Config.DisableSignalActions { + return fmt.Errorf("signal actions are disabled") + } + if selector.ArgError != 0 && option.Config.DisableOverrideActions { + return fmt.Errorf("override actions are disabled") + } + default: + } + } + } + return nil +} diff --git a/pkg/sensors/tracing/selectors_test.go b/pkg/sensors/tracing/selectors_test.go index 329d6fe767b..6bd910284b7 100644 --- a/pkg/sensors/tracing/selectors_test.go +++ b/pkg/sensors/tracing/selectors_test.go @@ -372,3 +372,118 @@ func TestKprobeSelectors(t *testing.T) { } } + +func TestValidateActionSelectors(t *testing.T) { + testCases := []struct { + name string + disableOverrides bool + disableSignals bool + wantErr bool + selectors []v1alpha1.KProbeSelector + }{ + { + name: "SignalActionEnabled", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "Signal"}}}, + }, + wantErr: false, + }, + { + name: "SignalActionDisabled", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}}}, + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "Signal"}}}, + }, + disableSignals: true, + wantErr: true, + }, + { + name: "SigkillActionEnabled", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "Sigkill"}}}, + }, + wantErr: false, + }, + { + name: "SigkillActionDisabled", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}}}, + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "Sigkill"}}}, + }, + disableSignals: true, + wantErr: true, + }, + { + name: "OverrideActionEnabled", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "Override"}}}, + }, + wantErr: false, + }, + { + name: "OverrideActionDisabled", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}}}, + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "Override"}}}, + }, + disableOverrides: true, + wantErr: true, + }, + { + name: "NotifyEnforcerOverrideAction", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}}}, + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "NotifyEnforcer", ArgError: -1}}}, + }, + wantErr: false, + }, + { + name: "NotifyEnforcerOverrideActionDisabled", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}}}, + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "NotifyEnforcer", ArgError: -1}}}, + }, + disableOverrides: true, + wantErr: true, + }, + { + name: "NotifyEnforcerSignalAction", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}}}, + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "NotifyEnforcer", ArgSig: 9}}}, + }, + wantErr: false, + }, + { + name: "NotifyEnforcerSignalActionDisabled", + selectors: []v1alpha1.KProbeSelector{ + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}}}, + {MatchActions: []v1alpha1.ActionSelector{{Action: "Post"}, {Action: "NotifyEnforcer", ArgSig: 9}}}, + }, + disableSignals: true, + wantErr: true, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + oldDisableOverrideActions := option.Config.DisableOverrideActions + option.Config.DisableOverrideActions = testCase.disableOverrides + t.Cleanup(func() { + option.Config.DisableOverrideActions = oldDisableOverrideActions + }) + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = testCase.disableSignals + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := validateActionSelectors(testCase.selectors) + if err != nil && !testCase.wantErr { + t.Errorf("unexpected error: %v", err) + } + if err == nil && testCase.wantErr { + t.Errorf("expected error, got nil") + } + }) + } +} diff --git a/pkg/sensors/tracing/tracepoint_test.go b/pkg/sensors/tracing/tracepoint_test.go index bdb78f6de26..3c3a23a688d 100644 --- a/pkg/sensors/tracing/tracepoint_test.go +++ b/pkg/sensors/tracing/tracepoint_test.go @@ -28,6 +28,7 @@ import ( sm "github.com/cilium/tetragon/pkg/matchers/stringmatcher" smatcher "github.com/cilium/tetragon/pkg/matchers/stringmatcher" "github.com/cilium/tetragon/pkg/observer/observertesthelper" + "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/policyfilter" "github.com/cilium/tetragon/pkg/reader/notify" "github.com/cilium/tetragon/pkg/sensors" @@ -869,3 +870,192 @@ spec: testListSyscallsDupsRange(t, checker, configHook) } + +func TestTracepointOverrideDisabled(t *testing.T) { + + // override on when override actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "sys-write" +spec: + lists: + - name: "test" + type: "syscalls" + values: + - "sys_dup" + tracepoints: + - subsystem: "raw_syscalls" + event: "sys_enter" + args: + - index: 4 + type: "syscall64" + - index: 5 + type: "uint64" + selectors: + - matchActions: + - action: Override + argError: -1 +` + + oldDisableOverrideActions := option.Config.DisableOverrideActions + option.Config.DisableOverrideActions = true + t.Cleanup(func() { + option.Config.DisableOverrideActions = oldDisableOverrideActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestTracepointSignalDisabled(t *testing.T) { + + // signal when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "sys-write" +spec: + lists: + - name: "test" + type: "syscalls" + values: + - "sys_dup" + tracepoints: + - subsystem: "raw_syscalls" + event: "sys_enter" + args: + - index: 4 + type: "syscall64" + - index: 5 + type: "uint64" + selectors: + - matchActions: + - action: Signal + argSig: 9 +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestTracepointSigkillDisabled(t *testing.T) { + + // sigkill when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "sys-write" +spec: + lists: + - name: "test" + type: "syscalls" + values: + - "sys_dup" + tracepoints: + - subsystem: "raw_syscalls" + event: "sys_enter" + args: + - index: 4 + type: "syscall64" + - index: 5 + type: "uint64" + selectors: + - matchActions: + - action: Sigkill +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestTracepointNotifyEnforcerSignalDisabled(t *testing.T) { + + // signal via notify enforcer when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "sys-write" +spec: + lists: + - name: "test" + type: "syscalls" + values: + - "sys_dup" + tracepoints: + - subsystem: "raw_syscalls" + event: "sys_enter" + args: + - index: 4 + type: "syscall64" + - index: 5 + type: "uint64" + selectors: + - matchActions: + - action: NotifyEnforcer + argSig: 9 +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestTracepointNotifyEnforcerOverrideDisabled(t *testing.T) { + + // override via notify enforcer when overide actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "sys-write" +spec: + lists: + - name: "test" + type: "syscalls" + values: + - "sys_dup" + tracepoints: + - subsystem: "raw_syscalls" + event: "sys_enter" + args: + - index: 4 + type: "syscall64" + - index: 5 + type: "uint64" + selectors: + - matchActions: + - action: NotifyEnforcer + argError: -1 +` + + oldDisableOverrideActions := option.Config.DisableOverrideActions + option.Config.DisableOverrideActions = true + t.Cleanup(func() { + option.Config.DisableOverrideActions = oldDisableOverrideActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} diff --git a/pkg/sensors/tracing/uprobe_test.go b/pkg/sensors/tracing/uprobe_test.go index 7f56efb274c..51c0b70327f 100644 --- a/pkg/sensors/tracing/uprobe_test.go +++ b/pkg/sensors/tracing/uprobe_test.go @@ -19,6 +19,7 @@ import ( lc "github.com/cilium/tetragon/pkg/matchers/listmatcher" sm "github.com/cilium/tetragon/pkg/matchers/stringmatcher" "github.com/cilium/tetragon/pkg/observer/observertesthelper" + "github.com/cilium/tetragon/pkg/option" "github.com/cilium/tetragon/pkg/sensors" "github.com/cilium/tetragon/pkg/testutils" tus "github.com/cilium/tetragon/pkg/testutils/sensors" @@ -551,3 +552,147 @@ spec: err = jsonchecker.JsonTestCheck(t, checker) assert.NoError(t, err) } + +func TestUprobeOverrideDisabled(t *testing.T) { + + // override on when override actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "uprobe" +spec: + uprobes: + - path: "/bin/bash" + symbols: + - "main" + selectors: + - matchActions: + - action: Override + argError: -1 +` + + oldDisableOverrideActions := option.Config.DisableOverrideActions + option.Config.DisableOverrideActions = true + t.Cleanup(func() { + option.Config.DisableOverrideActions = oldDisableOverrideActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestUprobeSignalDisabled(t *testing.T) { + + // signal when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "uprobe" +spec: + uprobes: + - path: "/bin/bash" + symbols: + - "main" + selectors: + - matchActions: + - action: Signal + argSig: 9 +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestUprobeSigkillDisabled(t *testing.T) { + + // sigkill when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "uprobe" +spec: + uprobes: + - path: "/bin/bash" + symbols: + - "main" + selectors: + - matchActions: + - action: Sigkill +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestUprobeNotifyEnforcerSignalDisabled(t *testing.T) { + + // signal via notify enforcer when signal actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "uprobe" +spec: + uprobes: + - path: "/bin/bash" + symbols: + - "main" + selectors: + - matchActions: + - action: NotifyEnforcer + argSig: 9 +` + + oldDisableSignalActions := option.Config.DisableSignalActions + option.Config.DisableSignalActions = true + t.Cleanup(func() { + option.Config.DisableSignalActions = oldDisableSignalActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +} + +func TestUprobeNotifyEnforcerOverrideDisabled(t *testing.T) { + + // override via notify enforcer when overide actions are disabled + + crd := ` +apiVersion: cilium.io/v1alpha1 +kind: TracingPolicy +metadata: + name: "uprobe" +spec: + uprobes: + - path: "/bin/bash" + symbols: + - "main" + selectors: + - matchActions: + - action: NotifyEnforcer + argError: -1 +` + + oldDisableOverrideActions := option.Config.DisableOverrideActions + option.Config.DisableOverrideActions = true + t.Cleanup(func() { + option.Config.DisableOverrideActions = oldDisableOverrideActions + }) + err := checkCrd(t, crd) + assert.Error(t, err) +}