From 8e2c9792df2aff4b40412101168df3472def099b Mon Sep 17 00:00:00 2001 From: Mahe Tardy Date: Mon, 21 Oct 2024 11:18:57 +0200 Subject: [PATCH 1/2] pkg/sensors: fix memory use of unloaded sensors Sensors that are disabled are not loaded and should not use memory, thus we clear the LoadedMapsInfo on unloading programs. Signed-off-by: Mahe Tardy --- pkg/sensors/program/program.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/sensors/program/program.go b/pkg/sensors/program/program.go index 134f147cf8b..16eff8d1d65 100644 --- a/pkg/sensors/program/program.go +++ b/pkg/sensors/program/program.go @@ -206,6 +206,11 @@ func (p *Program) Unload() error { } p.unloader = nil p.unloaderOverride = nil + // The above unloader can succeed while not removing a pin to the program + // because of option.Config.KeepSensorsOnExit, and thus the maps remain. + if !p.Prog.IsPinned() { + p.LoadedMapsInfo = nil + } return nil } From e4ce4a2fe5eea3bc05750bbf3feca9af795d123a Mon Sep 17 00:00:00 2001 From: Mahe Tardy Date: Wed, 23 Oct 2024 12:48:22 +0200 Subject: [PATCH 2/2] pkg/sensors: test kernel memory stat with disabling/enabling policy This adds a high level tests making sure that the kernel memory bytes stat is working and that disabling/enabling a policy should do what expected with regard to kernel memory usage. Signed-off-by: Mahe Tardy --- pkg/sensors/tracing/generickprobe_test.go | 106 ++++++++++++++++------ 1 file changed, 80 insertions(+), 26 deletions(-) diff --git a/pkg/sensors/tracing/generickprobe_test.go b/pkg/sensors/tracing/generickprobe_test.go index 01af82cb4a6..c44c6a22841 100644 --- a/pkg/sensors/tracing/generickprobe_test.go +++ b/pkg/sensors/tracing/generickprobe_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/cilium/tetragon/api/v1/tetragon" "github.com/cilium/tetragon/pkg/bpf" "github.com/cilium/tetragon/pkg/idtable" "github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1" @@ -16,6 +17,7 @@ import ( "github.com/cilium/tetragon/pkg/sensors/base" tus "github.com/cilium/tetragon/pkg/testutils/sensors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -114,10 +116,29 @@ func Test_SensorDestroyHook(t *testing.T) { } } -// Test_Kprobe_DisableEnablePolicy tests that disabling and enabling a tracing +const ( + tcpConnectPolicyName = "test" + tcpConnectPolicyNamespace = "" +) + +var tcpConnectPolicy = v1alpha1.TracingPolicy{ + ObjectMeta: v1.ObjectMeta{ + Name: tcpConnectPolicyName, + }, + Spec: v1alpha1.TracingPolicySpec{ + KProbes: []v1alpha1.KProbeSpec{ + { + Call: "tcp_connect", + Syscall: false, + }, + }, + }, +} + +// Test_DisableEnablePolicy_Kprobe tests that disabling and enabling a tracing // policy containing a kprobe works. This is following a regression: // https://github.com/cilium/tetragon/issues/1489 -func Test_Kprobe_DisableEnablePolicy(t *testing.T) { +func Test_DisableEnablePolicy_Kprobe(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -131,47 +152,80 @@ func Test_Kprobe_DisableEnablePolicy(t *testing.T) { } }) - const policyName = "test" - const policyNamespace = "" - policy := v1alpha1.TracingPolicy{ - ObjectMeta: v1.ObjectMeta{ - Name: policyName, - }, - Spec: v1alpha1.TracingPolicySpec{ - KProbes: []v1alpha1.KProbeSpec{ - { - Call: "tcp_connect", - Syscall: false, - }, - }, - }, - } - t.Run("sensor", func(t *testing.T) { - err = mgr.AddTracingPolicy(ctx, &policy) + err = mgr.AddTracingPolicy(ctx, &tcpConnectPolicy) assert.NoError(t, err) t.Cleanup(func() { - err = mgr.DeleteTracingPolicy(ctx, policyName, policyNamespace) + err = mgr.DeleteTracingPolicy(ctx, tcpConnectPolicyName, tcpConnectPolicyNamespace) assert.NoError(t, err) }) - err = mgr.DisableSensor(ctx, policyName) + err = mgr.DisableSensor(ctx, tcpConnectPolicyName) assert.NoError(t, err) - err = mgr.EnableSensor(ctx, policyName) + err = mgr.EnableSensor(ctx, tcpConnectPolicyName) assert.NoError(t, err) }) t.Run("tracing-policy", func(t *testing.T) { - err = mgr.AddTracingPolicy(ctx, &policy) + err = mgr.AddTracingPolicy(ctx, &tcpConnectPolicy) assert.NoError(t, err) t.Cleanup(func() { - err = mgr.DeleteTracingPolicy(ctx, policyName, policy.Namespace) + err = mgr.DeleteTracingPolicy(ctx, tcpConnectPolicyName, tcpConnectPolicyNamespace) assert.NoError(t, err) }) - err = mgr.DisableTracingPolicy(ctx, policyName, policyNamespace) + err = mgr.DisableTracingPolicy(ctx, tcpConnectPolicyName, tcpConnectPolicyNamespace) assert.NoError(t, err) - err = mgr.EnableTracingPolicy(ctx, policyName, policyNamespace) + err = mgr.EnableTracingPolicy(ctx, tcpConnectPolicyName, tcpConnectPolicyNamespace) assert.NoError(t, err) }) } + +// Test_DisableEnablePolicy_KernelMemoryBytes first check that disabling and +// enabling a policy works and then verifies that the kernel memory bytes for a +// loaded policy is non-zero, and that for a disabled policy it's zero. +func Test_DisableEnablePolicy_KernelMemoryBytes(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + tus.LoadSensor(t, base.GetInitialSensor()) + path := bpf.MapPrefixPath() + mgr, err := sensors.StartSensorManager(path, nil) + require.NoError(t, err) + t.Cleanup(func() { + if err := mgr.StopSensorManager(ctx); err != nil { + t.Fatal("failed to stop sensor manager") + } + }) + + err = mgr.AddTracingPolicy(ctx, &tcpConnectPolicy) + require.NoError(t, err) + t.Cleanup(func() { + err = mgr.DeleteTracingPolicy(ctx, tcpConnectPolicyName, tcpConnectPolicyNamespace) + assert.NoError(t, err) + }) + + list, err := mgr.ListTracingPolicies(ctx) + require.NoError(t, err) + require.Len(t, list.Policies, 1) + assert.Equal(t, tetragon.TracingPolicyState_TP_STATE_ENABLED, list.Policies[0].State) + assert.NotZero(t, list.Policies[0].KernelMemoryBytes) + + err = mgr.DisableTracingPolicy(ctx, tcpConnectPolicyName, tcpConnectPolicyNamespace) + require.NoError(t, err) + + list, err = mgr.ListTracingPolicies(ctx) + require.NoError(t, err) + require.Len(t, list.Policies, 1) + assert.Equal(t, tetragon.TracingPolicyState_TP_STATE_DISABLED, list.Policies[0].State) + assert.Zero(t, list.Policies[0].KernelMemoryBytes) + + err = mgr.EnableTracingPolicy(ctx, tcpConnectPolicyName, tcpConnectPolicyNamespace) + require.NoError(t, err) + + list, err = mgr.ListTracingPolicies(ctx) + require.NoError(t, err) + require.Len(t, list.Policies, 1) + assert.Equal(t, tetragon.TracingPolicyState_TP_STATE_ENABLED, list.Policies[0].State) + assert.NotZero(t, list.Policies[0].KernelMemoryBytes) +}