From 350d8e619c6cd792f792e2cf32ada02f6c235c35 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Fri, 19 Jul 2024 11:44:35 +0100 Subject: [PATCH 1/3] bpf: store thread leader namespaces/caps at fork and reduce false positives [ Upstream main 67e436b4b92e4f2 ] Store the thread leader namespaces during fork so we can check later if they changed, as right now they are only stored late during execv which will point to a new exec_id entry anyway. Right now during fork they are zeroed in the execve_map which make it unreliable to detect if they changed between the fork and the final execve, they will always be reported as if they changed which could be a false positive report. While we are it improve how we fetch and store capabilities. Signed-off-by: Djalal Harouni --- bpf/process/bpf_fork.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bpf/process/bpf_fork.c b/bpf/process/bpf_fork.c index 7fd3ac00fe4..eb9902c5a4a 100644 --- a/bpf/process/bpf_fork.c +++ b/bpf/process/bpf_fork.c @@ -47,6 +47,17 @@ BPF_KPROBE(event_wake_up_new_task, struct task_struct *task) curr->binary = parent->binary; curr->pkey = parent->key; + /* Store the thread leader capabilities so we can check later + * before the execve hook point if they changed or not. + * This needs to be converted later to credentials. + */ + get_current_subj_caps(&curr->caps, task); + + /* Store the thread leader namespaces so we can check later + * before the execve hook point if they changed or not. + */ + get_namespaces(&curr->ns, task); + u64 size = sizeof(struct msg_clone_event); struct msg_clone_event msg = { .common.op = MSG_OP_CLONE, From e87fb7e2875bbc6f998e945680501b064f287519 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Fri, 19 Jul 2024 11:54:52 +0100 Subject: [PATCH 2/3] test:clone: more namespace checks [ Upstream main 87ec91ced726 ] Signed-off-by: Djalal Harouni --- pkg/sensors/tracing/kprobe_threads_test.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/pkg/sensors/tracing/kprobe_threads_test.go b/pkg/sensors/tracing/kprobe_threads_test.go index 8096a787c61..1a856e01bbf 100644 --- a/pkg/sensors/tracing/kprobe_threads_test.go +++ b/pkg/sensors/tracing/kprobe_threads_test.go @@ -18,6 +18,8 @@ import ( "github.com/cilium/tetragon/pkg/logger" sm "github.com/cilium/tetragon/pkg/matchers/stringmatcher" "github.com/cilium/tetragon/pkg/observer/observertesthelper" + "github.com/cilium/tetragon/pkg/reader/caps" + "github.com/cilium/tetragon/pkg/reader/namespace" "github.com/cilium/tetragon/pkg/testutils" tus "github.com/cilium/tetragon/pkg/testutils/sensors" "github.com/stretchr/testify/assert" @@ -90,10 +92,15 @@ spec: cti.AssertPidsTids(t) + myCaps := ec.NewCapabilitiesChecker().FromCapabilities(caps.GetCurrentCapabilities()) + myNs := ec.NewNamespacesChecker().FromNamespaces(namespace.GetCurrentNamespace()) + parentCheck := ec.NewProcessChecker(). WithBinary(sm.Suffix("threads-tester")). WithPid(cti.ParentPid). - WithTid(cti.ParentTid) + WithTid(cti.ParentTid). + WithCap(myCaps). + WithNs(myNs) execCheck := ec.NewProcessExecChecker(""). WithProcess(parentCheck) @@ -104,7 +111,9 @@ spec: child1Checker := ec.NewProcessChecker(). WithBinary(sm.Suffix("threads-tester")). WithPid(cti.Child1Pid). - WithTid(cti.Child1Tid) + WithTid(cti.Child1Tid). + WithCap(myCaps). + WithNs(myNs) child1KpChecker := ec.NewProcessKprobeChecker(""). WithProcess(child1Checker).WithParent(parentCheck) @@ -112,7 +121,9 @@ spec: thread1Checker := ec.NewProcessChecker(). WithBinary(sm.Suffix("threads-tester")). WithPid(cti.Thread1Pid). - WithTid(cti.Thread1Tid) + WithTid(cti.Thread1Tid). + WithCap(myCaps). + WithNs(myNs) thread1KpChecker := ec.NewProcessKprobeChecker(""). WithProcess(thread1Checker).WithParent(parentCheck) From 2aaf287803ca57dc258995b361d2ceaf577bb070 Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Fri, 19 Jul 2024 12:05:19 +0100 Subject: [PATCH 3/3] tests:process_exec: more tests for get caps and ns [Upstream main 11a8cb0ce27695 ] Signed-off-by: Djalal Harouni --- pkg/sensors/exec/exec_test.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/pkg/sensors/exec/exec_test.go b/pkg/sensors/exec/exec_test.go index 396cf25e85a..20ecf9946a1 100644 --- a/pkg/sensors/exec/exec_test.go +++ b/pkg/sensors/exec/exec_test.go @@ -31,6 +31,7 @@ import ( "github.com/cilium/tetragon/pkg/observer/observertesthelper" "github.com/cilium/tetragon/pkg/option" proc "github.com/cilium/tetragon/pkg/process" + "github.com/cilium/tetragon/pkg/reader/caps" "github.com/cilium/tetragon/pkg/reader/namespace" "github.com/cilium/tetragon/pkg/sensors" "github.com/cilium/tetragon/pkg/sensors/base" @@ -257,9 +258,14 @@ func TestEventExecve(t *testing.T) { testNop := testutils.RepoRootPath("contrib/tester-progs/nop") + myCaps := ec.NewCapabilitiesChecker().FromCapabilities(caps.GetCurrentCapabilities()) + myNs := ec.NewNamespacesChecker().FromNamespaces(namespace.GetCurrentNamespace()) + procChecker := ec.NewProcessChecker(). WithBinary(sm.Full(testNop)). - WithArguments(sm.Full("arg1 arg2 arg3")) + WithArguments(sm.Full("arg1 arg2 arg3")). + WithCap(myCaps). + WithNs(myNs) execChecker := ec.NewProcessExecChecker("").WithProcess(procChecker) checker := ec.NewUnorderedEventChecker(execChecker) @@ -873,6 +879,9 @@ func TestExecProcessCredentials(t *testing.T) { testNop := testutils.RepoRootPath("contrib/tester-progs/nop") + myCaps := ec.NewCapabilitiesChecker().FromCapabilities(caps.GetCurrentCapabilities()) + myNs := ec.NewNamespacesChecker().FromNamespaces(namespace.GetCurrentNamespace()) + if err := exec.Command(testNop).Run(); err != nil { t.Fatalf("Failed to execute test binary: %s\n", err) } @@ -895,10 +904,14 @@ func TestExecProcessCredentials(t *testing.T) { WithGid(0).WithEgid(gid).WithSgid(gid).WithFsgid(gid) procExecChecker := ec.NewProcessChecker(). - WithBinary(sm.Full(testNop)).WithProcessCredentials(creds).WithBinaryProperties(nil) + WithBinary(sm.Full(testNop)).WithProcessCredentials(creds).WithBinaryProperties(nil). + WithCap(myCaps). + WithNs(myNs) procGidExecChecker := ec.NewProcessChecker(). - WithBinary(sm.Full(testNop)).WithProcessCredentials(gidCreds).WithBinaryProperties(nil) + WithBinary(sm.Full(testNop)).WithProcessCredentials(gidCreds).WithBinaryProperties(nil). + WithCap(myCaps). + WithNs(myNs) execChecker := ec.NewProcessExecChecker("exec").WithProcess(procExecChecker) execGidChecker := ec.NewProcessExecChecker("exec").WithProcess(procGidExecChecker)