From c9b5c42a351e1ab1a2040d0cc36e8dd8d9627500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Momar=20TOUR=C3=89?= <36661127+mftoure@users.noreply.github.com> Date: Fri, 28 Feb 2025 14:58:26 +0100 Subject: [PATCH] [CWS] Add container scope to secl variables output (#34532) Co-authored-by: lebauce --- .../status_templates/runtimesecurity.tmpl | 2 +- pkg/security/resolvers/cgroup/resolver.go | 7 +++ pkg/security/rules/engine.go | 9 +-- pkg/security/rules/engine_linux.go | 61 +++++++++++++++++++ pkg/security/rules/engine_others.go | 23 +++++++ 5 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 pkg/security/rules/engine_linux.go create mode 100644 pkg/security/rules/engine_others.go diff --git a/pkg/security/agent/status_templates/runtimesecurity.tmpl b/pkg/security/agent/status_templates/runtimesecurity.tmpl index 9a197b3281c28..e669aff97bb65 100644 --- a/pkg/security/agent/status_templates/runtimesecurity.tmpl +++ b/pkg/security/agent/status_templates/runtimesecurity.tmpl @@ -62,7 +62,7 @@ {{- range $variable := $variables }} - {{ $variable.Name }}: {{ $variable.Value }} {{- end }} - {{- end }} + {{ end }} {{- end }} {{- if not .seclScopedVariables }} No variable found diff --git a/pkg/security/resolvers/cgroup/resolver.go b/pkg/security/resolvers/cgroup/resolver.go index de710c7e7e647..31ccd865e9c85 100644 --- a/pkg/security/resolvers/cgroup/resolver.go +++ b/pkg/security/resolvers/cgroup/resolver.go @@ -149,6 +149,13 @@ func (cr *Resolver) GetCGroupContext(cgroupPath model.PathKey) (*model.CGroupCon return cr.cgroups.Get(cgroupPath) } +// GetContainerWorkloads returns the container workloads +func (cr *Resolver) GetContainerWorkloads() *simplelru.LRU[containerutils.ContainerID, *cgroupModel.CacheEntry] { + cr.Lock() + defer cr.Unlock() + return cr.containerWorkloads +} + // GetWorkload returns the workload referenced by the provided ID func (cr *Resolver) GetWorkload(id containerutils.ContainerID) (*cgroupModel.CacheEntry, bool) { if id == "" { diff --git a/pkg/security/rules/engine.go b/pkg/security/rules/engine.go index 47c16fdb0c2c7..0322805eb8584 100644 --- a/pkg/security/rules/engine.go +++ b/pkg/security/rules/engine.go @@ -377,12 +377,7 @@ func (e *RuleEngine) notifyAPIServer(ruleIDs []rules.RuleID, policies []*monitor e.apiServer.ApplyPolicyStates(policies) } -// GetSECLVariables returns the set of SECL variables along with theirs values -func (e *RuleEngine) GetSECLVariables() map[string]*api.SECLVariableState { - rs := e.GetRuleSet() - if rs == nil { - return nil - } +func (e *RuleEngine) getCommonSECLVariables(rs *rules.RuleSet) map[string]*api.SECLVariableState { var seclVariables = make(map[string]*api.SECLVariableState) for name, value := range rs.GetVariables() { if strings.HasPrefix(name, "process.") { @@ -410,8 +405,6 @@ func (e *RuleEngine) GetSECLVariables() map[string]*api.SECLVariableState { Value: scopedValue, } }) - } else if strings.HasPrefix(name, "container.") { - continue // skip container variables for now } else { // global variables value, found := value.(eval.Variable).GetValue() if !found { diff --git a/pkg/security/rules/engine_linux.go b/pkg/security/rules/engine_linux.go new file mode 100644 index 0000000000000..ec8c7bdff3105 --- /dev/null +++ b/pkg/security/rules/engine_linux.go @@ -0,0 +1,61 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Package rules holds rules related files +package rules + +import ( + "fmt" + "strings" + + "github.com/DataDog/datadog-agent/pkg/security/probe" + "github.com/DataDog/datadog-agent/pkg/security/proto/api" + "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" +) + +// GetSECLVariables returns the set of SECL variables along with theirs values +func (e *RuleEngine) GetSECLVariables() map[string]*api.SECLVariableState { + rs := e.GetRuleSet() + if rs == nil { + return nil + } + + seclVariables := e.getCommonSECLVariables(rs) + for name, value := range rs.GetVariables() { + if strings.HasPrefix(name, "container.") { + scopedVariable := value.(eval.ScopedVariable) + ebpfProbe, ok := e.probe.PlatformProbe.(*probe.EBPFProbe) + if !ok { + continue + } + cgr := ebpfProbe.Resolvers.CGroupResolver + containerWorkloads := cgr.GetContainerWorkloads() + if containerWorkloads == nil { + continue + } + + for _, cgce := range containerWorkloads.Values() { + cgce.RLock() + defer cgce.RUnlock() + + event := e.probe.PlatformProbe.NewEvent() + event.ContainerContext = &cgce.ContainerContext + ctx := eval.NewContext(event) + scopedName := fmt.Sprintf("%s.%s", name, cgce.ContainerContext.ContainerID) + value, found := scopedVariable.GetValue(ctx) + if !found { + continue + } + + scopedValue := fmt.Sprintf("%v", value) + seclVariables[scopedName] = &api.SECLVariableState{ + Name: scopedName, + Value: scopedValue, + } + } + } + } + return seclVariables +} diff --git a/pkg/security/rules/engine_others.go b/pkg/security/rules/engine_others.go new file mode 100644 index 0000000000000..5ed53ba82ce68 --- /dev/null +++ b/pkg/security/rules/engine_others.go @@ -0,0 +1,23 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build !linux + +// Package rules holds rules related files +package rules + +import ( + "github.com/DataDog/datadog-agent/pkg/security/proto/api" +) + +// GetSECLVariables returns the set of SECL variables along with theirs values +func (e *RuleEngine) GetSECLVariables() map[string]*api.SECLVariableState { + rs := e.GetRuleSet() + if rs == nil { + return nil + } + + return e.getCommonSECLVariables(rs) +}