From fced9614b71a0346466a069a0fb9c3e38f149937 Mon Sep 17 00:00:00 2001 From: Gui774ume Date: Mon, 30 Mar 2026 17:05:54 +0200 Subject: [PATCH] [WP] Serialize tracer metadata struct in process struct --- docs/cloud-workload-security/backend_linux.md | 133 ++++- .../backend_linux.schema.json | 59 ++- pkg/network/events/monitor.go | 17 +- pkg/network/events/monitor_test.go | 61 ++- .../event_deep_copy/event_deep_copy.tmpl | 27 +- .../resolvers/process/resolver_ebpf.go | 7 +- pkg/security/secl/go.mod | 5 +- pkg/security/secl/go.sum | 7 +- pkg/security/secl/model/BUILD.bazel | 1 + .../secl/model/event_deep_copy_unix.go | 20 +- .../secl/model/event_deep_copy_windows.go | 20 +- pkg/security/secl/model/model.go | 9 +- pkg/security/secl/model/model_unix.go | 3 +- pkg/security/secl/model/model_windows.go | 3 +- .../secl/model/process_cache_entry_unix.go | 2 +- pkg/security/seclwin/go.mod | 7 +- pkg/security/seclwin/go.sum | 4 + pkg/security/seclwin/model/BUILD.bazel | 1 + pkg/security/seclwin/model/model.go | 9 +- pkg/security/seclwin/model/model_win.go | 3 +- .../serializers_base_linux_easyjson.go | 282 +++++++--- pkg/security/serializers/serializers_linux.go | 18 +- .../serializers/serializers_linux_easyjson.go | 484 +++++++++++------- pkg/security/tests/tracer_memfd_test.go | 46 +- 24 files changed, 836 insertions(+), 392 deletions(-) diff --git a/docs/cloud-workload-security/backend_linux.md b/docs/cloud-workload-security/backend_linux.md index 2a77bca407bd49..154bba4eb58db1 100644 --- a/docs/cloud-workload-security/backend_linux.md +++ b/docs/cloud-workload-security/backend_linux.md @@ -1481,11 +1481,8 @@ Workload Protection events for Linux systems have the following JSON schema: "description": "List of AWS Security Credentials that the process had access to" }, "tracer": { - "additionalProperties": { - "type": "string" - }, - "type": "object", - "description": "Tags from an APM tracer instrumentation" + "$ref": "#/$defs/TracerMetadata", + "description": "Metadata from APM tracer instrumentation" }, "variables": { "$ref": "#/$defs/Variables", @@ -1662,11 +1659,8 @@ Workload Protection events for Linux systems have the following JSON schema: "description": "List of AWS Security Credentials that the process had access to" }, "tracer": { - "additionalProperties": { - "type": "string" - }, - "type": "object", - "description": "Tags from an APM tracer instrumentation" + "$ref": "#/$defs/TracerMetadata", + "description": "Metadata from APM tracer instrumentation" }, "variables": { "$ref": "#/$defs/Variables", @@ -2238,6 +2232,51 @@ Workload Protection events for Linux systems have the following JSON schema: "type": "object", "description": "TLSContextSerializer defines a tls context serializer" }, + "TracerMetadata": { + "properties": { + "schema_version": { + "type": "integer" + }, + "runtime_id": { + "type": "string" + }, + "tracer_language": { + "type": "string" + }, + "tracer_version": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "service_name": { + "type": "string" + }, + "service_env": { + "type": "string" + }, + "service_version": { + "type": "string" + }, + "process_tags": { + "type": "string" + }, + "container_id": { + "type": "string" + }, + "logs_collected": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "schema_version", + "tracer_language", + "tracer_version", + "hostname" + ] + }, "UserContext": { "properties": { "id": { @@ -4637,11 +4676,8 @@ Workload Protection events for Linux systems have the following JSON schema: "description": "List of AWS Security Credentials that the process had access to" }, "tracer": { - "additionalProperties": { - "type": "string" - }, - "type": "object", - "description": "Tags from an APM tracer instrumentation" + "$ref": "#/$defs/TracerMetadata", + "description": "Metadata from APM tracer instrumentation" }, "variables": { "$ref": "#/$defs/Variables", @@ -4697,7 +4733,7 @@ Workload Protection events for Linux systems have the following JSON schema: | `source` | Process source | | `syscalls` | List of syscalls captured to generate the event | | `aws_security_credentials` | List of AWS Security Credentials that the process had access to | -| `tracer` | Tags from an APM tracer instrumentation | +| `tracer` | Metadata from APM tracer instrumentation | | `variables` | Variable values | | References | @@ -4708,6 +4744,7 @@ Workload Protection events for Linux systems have the following JSON schema: | [CGroupContext](#cgroupcontext) | | [ContainerContext](#containercontext) | | [SyscallsEvent](#syscallsevent) | +| [TracerMetadata](#tracermetadata) | | [Variables](#variables) | ## `ProcessContext` @@ -4875,11 +4912,8 @@ Workload Protection events for Linux systems have the following JSON schema: "description": "List of AWS Security Credentials that the process had access to" }, "tracer": { - "additionalProperties": { - "type": "string" - }, - "type": "object", - "description": "Tags from an APM tracer instrumentation" + "$ref": "#/$defs/TracerMetadata", + "description": "Metadata from APM tracer instrumentation" }, "variables": { "$ref": "#/$defs/Variables", @@ -4950,7 +4984,7 @@ Workload Protection events for Linux systems have the following JSON schema: | `source` | Process source | | `syscalls` | List of syscalls captured to generate the event | | `aws_security_credentials` | List of AWS Security Credentials that the process had access to | -| `tracer` | Tags from an APM tracer instrumentation | +| `tracer` | Metadata from APM tracer instrumentation | | `variables` | Variable values | | `parent` | Parent process | | `ancestors` | Ancestor processes | @@ -4964,6 +4998,7 @@ Workload Protection events for Linux systems have the following JSON schema: | [CGroupContext](#cgroupcontext) | | [ContainerContext](#containercontext) | | [SyscallsEvent](#syscallsevent) | +| [TracerMetadata](#tracermetadata) | | [Variables](#variables) | | [Process](#process) | @@ -5790,6 +5825,60 @@ Workload Protection events for Linux systems have the following JSON schema: +## `TracerMetadata` + + +{{< code-block lang="json" collapsible="true" >}} +{ + "properties": { + "schema_version": { + "type": "integer" + }, + "runtime_id": { + "type": "string" + }, + "tracer_language": { + "type": "string" + }, + "tracer_version": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "service_name": { + "type": "string" + }, + "service_env": { + "type": "string" + }, + "service_version": { + "type": "string" + }, + "process_tags": { + "type": "string" + }, + "container_id": { + "type": "string" + }, + "logs_collected": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "schema_version", + "tracer_language", + "tracer_version", + "hostname" + ] +} + +{{< /code-block >}} + + + ## `UserContext` diff --git a/docs/cloud-workload-security/backend_linux.schema.json b/docs/cloud-workload-security/backend_linux.schema.json index 0499bcfece3692..ccca2ddc006623 100644 --- a/docs/cloud-workload-security/backend_linux.schema.json +++ b/docs/cloud-workload-security/backend_linux.schema.json @@ -1470,11 +1470,8 @@ "description": "List of AWS Security Credentials that the process had access to" }, "tracer": { - "additionalProperties": { - "type": "string" - }, - "type": "object", - "description": "Tags from an APM tracer instrumentation" + "$ref": "#/$defs/TracerMetadata", + "description": "Metadata from APM tracer instrumentation" }, "variables": { "$ref": "#/$defs/Variables", @@ -1651,11 +1648,8 @@ "description": "List of AWS Security Credentials that the process had access to" }, "tracer": { - "additionalProperties": { - "type": "string" - }, - "type": "object", - "description": "Tags from an APM tracer instrumentation" + "$ref": "#/$defs/TracerMetadata", + "description": "Metadata from APM tracer instrumentation" }, "variables": { "$ref": "#/$defs/Variables", @@ -2227,6 +2221,51 @@ "type": "object", "description": "TLSContextSerializer defines a tls context serializer" }, + "TracerMetadata": { + "properties": { + "schema_version": { + "type": "integer" + }, + "runtime_id": { + "type": "string" + }, + "tracer_language": { + "type": "string" + }, + "tracer_version": { + "type": "string" + }, + "hostname": { + "type": "string" + }, + "service_name": { + "type": "string" + }, + "service_env": { + "type": "string" + }, + "service_version": { + "type": "string" + }, + "process_tags": { + "type": "string" + }, + "container_id": { + "type": "string" + }, + "logs_collected": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "schema_version", + "tracer_language", + "tracer_version", + "hostname" + ] + }, "UserContext": { "properties": { "id": { diff --git a/pkg/network/events/monitor.go b/pkg/network/events/monitor.go index 8d53f064e90a11..1efb9511ce1632 100644 --- a/pkg/network/events/monitor.go +++ b/pkg/network/events/monitor.go @@ -156,15 +156,16 @@ func (h *eventConsumerWrapper) Copy(ev *model.Event) any { } } - tracerTags := ev.GetProcessTracerTags() - for _, tag := range tracerTags { - if tracermetadata.ShouldSkipServiceTag(tag, - tagsFound["DD_SERVICE"], - tagsFound["DD_ENV"], - tagsFound["DD_VERSION"]) { - continue + if tmeta := ev.GetProcessTracerMetadata(); (tmeta != tracermetadata.TracerMetadata{}) { + for key, value := range tmeta.Tags() { + if tracermetadata.ShouldSkipServiceTagKV(key, value, + tagsFound["DD_SERVICE"], + tagsFound["DD_ENV"], + tagsFound["DD_VERSION"]) { + continue + } + p.Tags = append(p.Tags, intern.GetByString(key+":"+value)) } - p.Tags = append(p.Tags, intern.GetByString(tag)) } if cid := ev.GetContainerID(); cid != "" { diff --git a/pkg/network/events/monitor_test.go b/pkg/network/events/monitor_test.go index 8d79199ca95699..bc3814a048503b 100644 --- a/pkg/network/events/monitor_test.go +++ b/pkg/network/events/monitor_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/require" "go4.org/intern" + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/secl/model" ) @@ -259,15 +260,11 @@ func TestEventHandleTracerTags(t *testing.T) { "DD_ENV=env-from-envp", "DD_VERSION=version-from-envp", }, - TracerTags: []string{ - "tracer_service_name:my-service", - "tracer_service_env:my-env", - "tracer_service_version:my-version", - "entrypoint.name:my-entrypoint", - // Should be skipped because it matches the UST tags - "tracer_service_name:service-from-envp", - "tracer_service_env:env-from-envp", - "tracer_service_version:version-from-envp", + TracerMetadata: tracermetadata.TracerMetadata{ + ServiceName: "my-service", + ServiceEnv: "my-env", + ServiceVersion: "my-version", + ProcessTags: "entrypoint.name:my-entrypoint", }, }, }, @@ -286,9 +283,49 @@ func TestEventHandleTracerTags(t *testing.T) { assert.Contains(t, receivedProc.Tags, intern.GetByString("tracer_service_name:my-service")) assert.Contains(t, receivedProc.Tags, intern.GetByString("tracer_service_env:my-env")) assert.Contains(t, receivedProc.Tags, intern.GetByString("tracer_service_version:my-version")) - assert.NotContains(t, receivedProc.Tags, intern.GetByString("tracer_service_name:service-from-envp")) - assert.NotContains(t, receivedProc.Tags, intern.GetByString("tracer_service_env:env-from-envp")) - assert.NotContains(t, receivedProc.Tags, intern.GetByString("tracer_service_version:version-from-envp")) + assert.Contains(t, receivedProc.Tags, intern.GetByString("entrypoint.name:my-entrypoint")) + }) + + t.Run("process event with tracer tags matching UST env vars", func(t *testing.T) { + handler.events = nil // reset + + now := time.Now() + ev := &model.Event{ + BaseEvent: model.BaseEvent{ + Type: uint32(model.ExecEventType), + ProcessContext: &model.ProcessContext{ + Process: model.Process{ + PIDContext: model.PIDContext{ + Pid: 1234, + }, + ExecTime: now, + Envp: []string{ + "DD_SERVICE=my-service", + "DD_ENV=my-env", + "DD_VERSION=my-version", + }, + TracerMetadata: tracermetadata.TracerMetadata{ + ServiceName: "my-service", + ServiceEnv: "my-env", + ServiceVersion: "my-version", + ProcessTags: "entrypoint.name:my-entrypoint", + }, + }, + }, + FieldHandlers: &model.FakeFieldHandlers{}, + }, + } + + p := evHandler.Copy(ev).(*Process) + evHandler.HandleEvent(p) + + require.Len(t, handler.events, 1, "should have received 1 process event") + receivedProc := handler.events[0] + // tracer_service_* tags should be skipped because they match DD_* env vars + assert.NotContains(t, receivedProc.Tags, intern.GetByString("tracer_service_name:my-service")) + assert.NotContains(t, receivedProc.Tags, intern.GetByString("tracer_service_env:my-env")) + assert.NotContains(t, receivedProc.Tags, intern.GetByString("tracer_service_version:my-version")) + // non-service tags should still be present assert.Contains(t, receivedProc.Tags, intern.GetByString("entrypoint.name:my-entrypoint")) }) diff --git a/pkg/security/generators/event_deep_copy/event_deep_copy.tmpl b/pkg/security/generators/event_deep_copy/event_deep_copy.tmpl index 7dd69550990eae..68acb7cceb7b05 100644 --- a/pkg/security/generators/event_deep_copy/event_deep_copy.tmpl +++ b/pkg/security/generators/event_deep_copy/event_deep_copy.tmpl @@ -14,7 +14,8 @@ import ( "github.com/DataDog/datadog-agent/pkg/security/secl/model/utils" "github.com/google/gopacket" {{end}} - + + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" {{if ne $.SourcePkg $.TargetPkg}}"{{.SourcePkg}}"{{end}} "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" ) @@ -74,7 +75,7 @@ func (e *Event) DeepCopy() *Event { {{- $generated := .Generated}} {{- if $node.Field}} {{- $baseName := BaseName $node.Field.OrigType}} - + {{- /* For arrays/maps, check element/value properties; otherwise check field properties */}} {{- $isPtr := false}} {{- $isArray := $node.Field.IsArray}} @@ -86,7 +87,7 @@ func (e *Event) DeepCopy() *Event { {{- else}} {{- $isPtr = $node.Field.IsOrigTypePtr}} {{- end}} - + {{- /* Generate unique key for this function */ -}} {{- $key := $baseName}} {{- if $isPtr}}{{$key = printf "%sPtr" $key}}{{end}} @@ -96,11 +97,11 @@ func (e *Event) DeepCopy() *Event { {{- if $node.Field.MapValue.IsArray}}{{$key = printf "%sArr" $key}}{{end}} {{- $key = printf "%sMap" $key}} {{- end}} - + {{- /* Only generate if not already generated */ -}} {{- if not (hasKey $generated $key)}} {{- $_ := set $generated $key true}} - + {{- /* Build function name */ -}} {{- $funcName := printf "deepCopy%s" $baseName}} {{- if $isPtr}}{{$funcName = printf "%sPtr" $funcName}}{{end}} @@ -110,7 +111,7 @@ func (e *Event) DeepCopy() *Event { {{- if $node.Field.MapValue.IsArray}}{{$funcName = printf "%sArr" $funcName}}{{end}} {{- $funcName = printf "%sMap" $funcName}} {{- end}} - + {{- /* Build type signature */ -}} {{- $typePrefix := ""}} {{- if $isArray}}{{$typePrefix = "[]"}}{{end}} @@ -120,10 +121,10 @@ func (e *Event) DeepCopy() *Event { {{- end}} {{- if $isPtr}}{{$typePrefix = printf "%s*" $typePrefix}}{{end}} {{- $fullType := printf "%s%s" $typePrefix $node.Field.OrigType}} - + func {{$funcName}}(fieldToCopy {{$fullType}}) {{$fullType}} { {{- $strategy := GetFieldCopyStrategy $node.Field}} - + {{- if eq $strategy "pointer"}} if fieldToCopy == nil { return nil @@ -159,7 +160,7 @@ func {{$funcName}}(fieldToCopy {{$fullType}}) {{$fullType}} { {{- end}} {{- end}} return copied - + {{- else if eq $strategy "array"}} if fieldToCopy == nil { return nil @@ -179,7 +180,7 @@ func {{$funcName}}(fieldToCopy {{$fullType}}) {{$fullType}} { } {{- end}} return copied - + {{- else if eq $strategy "map"}} if fieldToCopy == nil { return nil @@ -203,7 +204,7 @@ func {{$funcName}}(fieldToCopy {{$fullType}}) {{$fullType}} { } {{- end}} return copied - + {{- else if eq $strategy "struct"}} copied := {{$node.Field.OrigType}}{} {{- range $node.Children}} @@ -226,7 +227,7 @@ func {{$funcName}}(fieldToCopy {{$fullType}}) {{$fullType}} { {{- end}} {{- $childMapSuffix := ""}} {{- if .Field.IsMap}}{{$childMapSuffix = "Map"}}{{end}} - + {{- /* Fixed-size arrays are value types, copy by assignment; slices and maps always need functions; scalars can be direct assigned */}} {{- if and .Field.IsArray .Field.IsFixedArray}} copied.{{.Name}} = fieldToCopy.{{.Name}} @@ -237,7 +238,7 @@ func {{$funcName}}(fieldToCopy {{$fullType}}) {{$fullType}} { {{- end}} {{- end}} return copied - + {{- else}} return fieldToCopy {{- end}} diff --git a/pkg/security/resolvers/process/resolver_ebpf.go b/pkg/security/resolvers/process/resolver_ebpf.go index ba5e3981f90ba4..9138a667106564 100644 --- a/pkg/security/resolvers/process/resolver_ebpf.go +++ b/pkg/security/resolvers/process/resolver_ebpf.go @@ -1409,17 +1409,12 @@ func (p *EBPFResolver) AddTracerMetadata(pid uint32, event *model.Event) error { return fmt.Errorf("failed to read tracer metadata: %w", err) } - tags := tmeta.GetTags() - if len(tags) == 0 { - return nil - } - p.Lock() defer p.Unlock() entry := p.entryCache[pid] if entry != nil { - entry.TracerTags = tags + entry.TracerMetadata = tmeta } return nil diff --git a/pkg/security/secl/go.mod b/pkg/security/secl/go.mod index 863c2ba8189b67..db85a60cdde0c0 100644 --- a/pkg/security/secl/go.mod +++ b/pkg/security/secl/go.mod @@ -3,6 +3,7 @@ module github.com/DataDog/datadog-agent/pkg/security/secl go 1.25.7 require ( + github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model v0.0.0-00010101000000-000000000000 github.com/Masterminds/semver/v3 v3.4.0 github.com/alecthomas/participle v0.7.1 github.com/charlievieth/strcase v0.0.5 @@ -27,14 +28,14 @@ require ( require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/philhofer/fwd v1.2.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/rogpeppe/go-internal v1.14.1 // indirect + github.com/tinylib/msgp v1.6.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect golang.org/x/net v0.52.0 // indirect golang.org/x/sync v0.20.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/security/secl/go.sum b/pkg/security/secl/go.sum index 1cf0fa05fd24ea..f221a34efcfd50 100644 --- a/pkg/security/secl/go.sum +++ b/pkg/security/secl/go.sum @@ -26,13 +26,12 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/jellydator/ttlcache/v3 v3.4.0 h1:YS4P125qQS0tNhtL6aeYkheEaB/m8HCqdMMP4mnWdTY= github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= +github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -47,6 +46,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s= +github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= github.com/weppos/publicsuffix-go v0.50.3 h1:eT5dcjHQcVDNc0igpFEsGHKIip30feuB2zuuI9eJxiE= github.com/weppos/publicsuffix-go v0.50.3/go.mod h1:/rOa781xBykZhHK/I3QeHo92qdDKVmKZKF7s8qAEM/4= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= diff --git a/pkg/security/secl/model/BUILD.bazel b/pkg/security/secl/model/BUILD.bazel index bf38ef19fa18ee..f8779f9bfb6c6d 100644 --- a/pkg/security/secl/model/BUILD.bazel +++ b/pkg/security/secl/model/BUILD.bazel @@ -61,6 +61,7 @@ go_library( "//pkg/security/secl/model/sharedconsts", "//pkg/security/secl/model/usersession", "//pkg/security/secl/model/utils", + "@com_github_datadog_datadog_agent_pkg_discovery_tracermetadata_model//:model", "@com_github_google_uuid//:uuid", ] + select({ "@rules_go//go/platform:aix": [ diff --git a/pkg/security/secl/model/event_deep_copy_unix.go b/pkg/security/secl/model/event_deep_copy_unix.go index 69028f164c9ab8..5863179691e73e 100644 --- a/pkg/security/secl/model/event_deep_copy_unix.go +++ b/pkg/security/secl/model/event_deep_copy_unix.go @@ -9,6 +9,7 @@ package model import ( + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" "github.com/DataDog/datadog-agent/pkg/security/secl/model/utils" "github.com/google/gopacket" @@ -255,7 +256,7 @@ func deepCopyProcessPtr(fieldToCopy *Process) *Process { copied.SymlinkPathnameStr = fieldToCopy.SymlinkPathnameStr copied.TTYName = fieldToCopy.TTYName copied.TraceID = deepCopyTraceID(fieldToCopy.TraceID) - copied.TracerTags = deepCopystringArr(fieldToCopy.TracerTags) + copied.TracerMetadata = deepCopyTracerMetadata(fieldToCopy.TracerMetadata) copied.UserSession = deepCopyUserSessionContext(fieldToCopy.UserSession) return copied } @@ -400,6 +401,21 @@ func deepCopyTraceID(fieldToCopy utils.TraceID) utils.TraceID { copied.Lo = fieldToCopy.Lo return copied } +func deepCopyTracerMetadata(fieldToCopy tracermetadata.TracerMetadata) tracermetadata.TracerMetadata { + copied := tracermetadata.TracerMetadata{} + copied.ContainerID = fieldToCopy.ContainerID + copied.Hostname = fieldToCopy.Hostname + copied.LogsCollected = fieldToCopy.LogsCollected + copied.ProcessTags = fieldToCopy.ProcessTags + copied.RuntimeID = fieldToCopy.RuntimeID + copied.SchemaVersion = fieldToCopy.SchemaVersion + copied.ServiceEnv = fieldToCopy.ServiceEnv + copied.ServiceName = fieldToCopy.ServiceName + copied.ServiceVersion = fieldToCopy.ServiceVersion + copied.TracerLanguage = fieldToCopy.TracerLanguage + copied.TracerVersion = fieldToCopy.TracerVersion + return copied +} func deepCopyUserSessionContext(fieldToCopy UserSessionContext) UserSessionContext { copied := UserSessionContext{} copied.ID = fieldToCopy.ID @@ -481,7 +497,7 @@ func deepCopyProcess(fieldToCopy Process) Process { copied.SymlinkPathnameStr = fieldToCopy.SymlinkPathnameStr copied.TTYName = fieldToCopy.TTYName copied.TraceID = deepCopyTraceID(fieldToCopy.TraceID) - copied.TracerTags = deepCopystringArr(fieldToCopy.TracerTags) + copied.TracerMetadata = deepCopyTracerMetadata(fieldToCopy.TracerMetadata) copied.UserSession = deepCopyUserSessionContext(fieldToCopy.UserSession) return copied } diff --git a/pkg/security/secl/model/event_deep_copy_windows.go b/pkg/security/secl/model/event_deep_copy_windows.go index 365296a2f603cf..5387638ab899ac 100644 --- a/pkg/security/secl/model/event_deep_copy_windows.go +++ b/pkg/security/secl/model/event_deep_copy_windows.go @@ -9,6 +9,7 @@ package model import ( + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" ) @@ -96,7 +97,7 @@ func deepCopyProcessPtr(fieldToCopy *Process) *Process { copied.PIDContext = deepCopyPIDContext(fieldToCopy.PIDContext) copied.PPid = fieldToCopy.PPid copied.ScrubbedCmdLineResolved = fieldToCopy.ScrubbedCmdLineResolved - copied.TracerTags = deepCopystringArr(fieldToCopy.TracerTags) + copied.TracerMetadata = deepCopyTracerMetadata(fieldToCopy.TracerMetadata) copied.User = fieldToCopy.User return copied } @@ -152,6 +153,21 @@ func deepCopyFileEvent(fieldToCopy FileEvent) FileEvent { copied.PathnameStr = fieldToCopy.PathnameStr return copied } +func deepCopyTracerMetadata(fieldToCopy tracermetadata.TracerMetadata) tracermetadata.TracerMetadata { + copied := tracermetadata.TracerMetadata{} + copied.ContainerID = fieldToCopy.ContainerID + copied.Hostname = fieldToCopy.Hostname + copied.LogsCollected = fieldToCopy.LogsCollected + copied.ProcessTags = fieldToCopy.ProcessTags + copied.RuntimeID = fieldToCopy.RuntimeID + copied.SchemaVersion = fieldToCopy.SchemaVersion + copied.ServiceEnv = fieldToCopy.ServiceEnv + copied.ServiceName = fieldToCopy.ServiceName + copied.ServiceVersion = fieldToCopy.ServiceVersion + copied.TracerLanguage = fieldToCopy.TracerLanguage + copied.TracerVersion = fieldToCopy.TracerVersion + return copied +} func deepCopyProcess(fieldToCopy Process) Process { copied := Process{} copied.ArgsEntry = deepCopyArgsEntryPtr(fieldToCopy.ArgsEntry) @@ -169,7 +185,7 @@ func deepCopyProcess(fieldToCopy Process) Process { copied.PIDContext = deepCopyPIDContext(fieldToCopy.PIDContext) copied.PPid = fieldToCopy.PPid copied.ScrubbedCmdLineResolved = fieldToCopy.ScrubbedCmdLineResolved - copied.TracerTags = deepCopystringArr(fieldToCopy.TracerTags) + copied.TracerMetadata = deepCopyTracerMetadata(fieldToCopy.TracerMetadata) copied.User = fieldToCopy.User return copied } diff --git a/pkg/security/secl/model/model.go b/pkg/security/secl/model/model.go index 219917b77e702f..2555d94e5a619e 100644 --- a/pkg/security/secl/model/model.go +++ b/pkg/security/secl/model/model.go @@ -16,6 +16,7 @@ import ( "sync" "time" + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" "github.com/DataDog/datadog-agent/pkg/security/secl/model/utils" @@ -359,12 +360,12 @@ func (e *Event) ResolveService() string { return e.FieldHandlers.ResolveService(e, &e.BaseEvent) } -// GetProcessTracerTags returns the value of the field, resolving if necessary -func (e *Event) GetProcessTracerTags() []string { +// GetProcessTracerMetadata returns the tracer metadata of the process +func (e *Event) GetProcessTracerMetadata() tracermetadata.TracerMetadata { if e.BaseEvent.ProcessContext == nil { - return []string{} + return tracermetadata.TracerMetadata{} } - return e.BaseEvent.ProcessContext.Process.TracerTags + return e.BaseEvent.ProcessContext.Process.TracerMetadata } // UserSessionContext describes the user session context diff --git a/pkg/security/secl/model/model_unix.go b/pkg/security/secl/model/model_unix.go index 5328859a9bcc77..363e4600cf6756 100644 --- a/pkg/security/secl/model/model_unix.go +++ b/pkg/security/secl/model/model_unix.go @@ -20,6 +20,7 @@ import ( "github.com/google/gopacket" + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" "github.com/DataDog/datadog-agent/pkg/security/secl/model/utils" @@ -391,7 +392,7 @@ type Process struct { AWSSecurityCredentials []AWSSecurityCredentials `field:"-"` - TracerTags []string `field:"-"` // Tags from APM tracer instrumentation + TracerMetadata tracermetadata.TracerMetadata `field:"-"` // Metadata from APM tracer instrumentation ArgsID uint64 `field:"-"` EnvsID uint64 `field:"-"` diff --git a/pkg/security/secl/model/model_windows.go b/pkg/security/secl/model/model_windows.go index 53b0a1c580279d..d101d14c34a256 100644 --- a/pkg/security/secl/model/model_windows.go +++ b/pkg/security/secl/model/model_windows.go @@ -14,6 +14,7 @@ import ( "time" "unsafe" + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" ) @@ -156,7 +157,7 @@ type Process struct { PPid uint32 `field:"ppid"` // SECLDoc[ppid] Definition:`Parent process ID` - TracerTags []string `field:"-"` // Tags from APM tracer instrumentation + TracerMetadata tracermetadata.TracerMetadata `field:"-"` // Metadata from APM tracer instrumentation ArgsEntry *ArgsEntry `field:"-"` EnvsEntry *EnvsEntry `field:"-"` diff --git a/pkg/security/secl/model/process_cache_entry_unix.go b/pkg/security/secl/model/process_cache_entry_unix.go index 39694d9b2ac230..e36a0c7b335034 100644 --- a/pkg/security/secl/model/process_cache_entry_unix.go +++ b/pkg/security/secl/model/process_cache_entry_unix.go @@ -189,7 +189,7 @@ func (pc *ProcessCacheEntry) Fork(child *ProcessCacheEntry) { child.Credentials = pc.Credentials child.LinuxBinprm = pc.LinuxBinprm child.Cookie = pc.Cookie - child.TracerTags = pc.TracerTags + child.TracerMetadata = pc.TracerMetadata child.SetForkParent(pc) } diff --git a/pkg/security/seclwin/go.mod b/pkg/security/seclwin/go.mod index 627133ab5ca3b3..171249c331a313 100644 --- a/pkg/security/seclwin/go.mod +++ b/pkg/security/seclwin/go.mod @@ -2,12 +2,17 @@ module github.com/DataDog/datadog-agent/pkg/security/seclwin go 1.25.7 -require github.com/DataDog/datadog-agent/pkg/security/secl v0.56.0 +require ( + github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model v0.0.0-00010101000000-000000000000 + github.com/DataDog/datadog-agent/pkg/security/secl v0.56.0 +) require ( github.com/alecthomas/participle v0.7.1 // indirect github.com/charlievieth/strcase v0.0.5 // indirect github.com/jellydator/ttlcache/v3 v3.4.0 // indirect + github.com/philhofer/fwd v1.2.0 // indirect + github.com/tinylib/msgp v1.6.3 // indirect github.com/weppos/publicsuffix-go v0.50.3 // indirect golang.org/x/net v0.52.0 // indirect golang.org/x/sync v0.20.0 // indirect diff --git a/pkg/security/seclwin/go.sum b/pkg/security/seclwin/go.sum index ccc8298dfb9652..0c0fe580a48af4 100644 --- a/pkg/security/seclwin/go.sum +++ b/pkg/security/seclwin/go.sum @@ -9,6 +9,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/jellydator/ttlcache/v3 v3.4.0 h1:YS4P125qQS0tNhtL6aeYkheEaB/m8HCqdMMP4mnWdTY= github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4= +github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= +github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -16,6 +18,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s= +github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= github.com/weppos/publicsuffix-go v0.50.3 h1:eT5dcjHQcVDNc0igpFEsGHKIip30feuB2zuuI9eJxiE= github.com/weppos/publicsuffix-go v0.50.3/go.mod h1:/rOa781xBykZhHK/I3QeHo92qdDKVmKZKF7s8qAEM/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= diff --git a/pkg/security/seclwin/model/BUILD.bazel b/pkg/security/seclwin/model/BUILD.bazel index 4ad9e7883b43d0..89302e26ac70f2 100644 --- a/pkg/security/seclwin/model/BUILD.bazel +++ b/pkg/security/seclwin/model/BUILD.bazel @@ -26,5 +26,6 @@ go_library( "//pkg/security/secl/model/sharedconsts", "//pkg/security/secl/model/usersession", "//pkg/security/secl/model/utils", + "@com_github_datadog_datadog_agent_pkg_discovery_tracermetadata_model//:model", ], ) diff --git a/pkg/security/seclwin/model/model.go b/pkg/security/seclwin/model/model.go index 219917b77e702f..2555d94e5a619e 100644 --- a/pkg/security/seclwin/model/model.go +++ b/pkg/security/seclwin/model/model.go @@ -16,6 +16,7 @@ import ( "sync" "time" + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" "github.com/DataDog/datadog-agent/pkg/security/secl/containerutils" "github.com/DataDog/datadog-agent/pkg/security/secl/model/utils" @@ -359,12 +360,12 @@ func (e *Event) ResolveService() string { return e.FieldHandlers.ResolveService(e, &e.BaseEvent) } -// GetProcessTracerTags returns the value of the field, resolving if necessary -func (e *Event) GetProcessTracerTags() []string { +// GetProcessTracerMetadata returns the tracer metadata of the process +func (e *Event) GetProcessTracerMetadata() tracermetadata.TracerMetadata { if e.BaseEvent.ProcessContext == nil { - return []string{} + return tracermetadata.TracerMetadata{} } - return e.BaseEvent.ProcessContext.Process.TracerTags + return e.BaseEvent.ProcessContext.Process.TracerMetadata } // UserSessionContext describes the user session context diff --git a/pkg/security/seclwin/model/model_win.go b/pkg/security/seclwin/model/model_win.go index 53b0a1c580279d..d101d14c34a256 100644 --- a/pkg/security/seclwin/model/model_win.go +++ b/pkg/security/seclwin/model/model_win.go @@ -14,6 +14,7 @@ import ( "time" "unsafe" + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/eval" ) @@ -156,7 +157,7 @@ type Process struct { PPid uint32 `field:"ppid"` // SECLDoc[ppid] Definition:`Parent process ID` - TracerTags []string `field:"-"` // Tags from APM tracer instrumentation + TracerMetadata tracermetadata.TracerMetadata `field:"-"` // Metadata from APM tracer instrumentation ArgsEntry *ArgsEntry `field:"-"` EnvsEntry *EnvsEntry `field:"-"` diff --git a/pkg/security/serializers/serializers_base_linux_easyjson.go b/pkg/security/serializers/serializers_base_linux_easyjson.go index 2c54e2ba4805b9..fad922ef615426 100644 --- a/pkg/security/serializers/serializers_base_linux_easyjson.go +++ b/pkg/security/serializers/serializers_base_linux_easyjson.go @@ -7,6 +7,7 @@ package serializers import ( json "encoding/json" + model "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" utils "github.com/DataDog/datadog-agent/pkg/security/utils" easyjson "github.com/mailru/easyjson" jlexer "github.com/mailru/easyjson/jlexer" @@ -1246,26 +1247,12 @@ func easyjsonA1e47abeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers6(i case "tracer": if in.IsNull() { in.Skip() + out.Tracer = nil } else { - in.Delim('{') - if !in.IsDelim('}') { - out.Tracer = make(map[string]string) - } else { - out.Tracer = nil + if out.Tracer == nil { + out.Tracer = new(model.TracerMetadata) } - for !in.IsDelim('}') { - key := string(in.String()) - in.WantColon() - var v18 string - if in.IsNull() { - in.Skip() - } else { - v18 = string(in.String()) - } - (out.Tracer)[key] = v18 - in.WantComma() - } - in.Delim('}') + easyjsonA1e47abeDecodeGithubComDataDogDatadogAgentPkgDiscoveryTracermetadataModel(in, out.Tracer) } case "variables": if in.IsNull() { @@ -1303,14 +1290,14 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers6(o } { out.RawByte('[') - for v19, v20 := range in.Ancestors { - if v19 > 0 { + for v18, v19 := range in.Ancestors { + if v18 > 0 { out.RawByte(',') } - if v20 == nil { + if v19 == nil { out.RawString("null") } else { - (*v20).MarshalEasyJSON(out) + (*v19).MarshalEasyJSON(out) } } out.RawByte(']') @@ -1426,11 +1413,11 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers6(o out.RawString(prefix) { out.RawByte('[') - for v21, v22 := range in.CapsAttempted { - if v21 > 0 { + for v20, v21 := range in.CapsAttempted { + if v20 > 0 { out.RawByte(',') } - out.String(string(v22)) + out.String(string(v21)) } out.RawByte(']') } @@ -1440,11 +1427,11 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers6(o out.RawString(prefix) { out.RawByte('[') - for v23, v24 := range in.CapsUsed { - if v23 > 0 { + for v22, v23 := range in.CapsUsed { + if v22 > 0 { out.RawByte(',') } - out.String(string(v24)) + out.String(string(v23)) } out.RawByte(']') } @@ -1484,11 +1471,11 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers6(o out.RawString(prefix) { out.RawByte('[') - for v25, v26 := range in.Args { - if v25 > 0 { + for v24, v25 := range in.Args { + if v24 > 0 { out.RawByte(',') } - out.String(string(v26)) + out.String(string(v25)) } out.RawByte(']') } @@ -1503,11 +1490,11 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers6(o out.RawString(prefix) { out.RawByte('[') - for v27, v28 := range in.Envs { - if v27 > 0 { + for v26, v27 := range in.Envs { + if v26 > 0 { out.RawByte(',') } - out.String(string(v28)) + out.String(string(v27)) } out.RawByte(']') } @@ -1554,11 +1541,11 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers6(o out.RawString("null") } else { out.RawByte('[') - for v29, v30 := range *in.Syscalls { - if v29 > 0 { + for v28, v29 := range *in.Syscalls { + if v28 > 0 { out.RawByte(',') } - easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers7(out, v30) + easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers7(out, v29) } out.RawByte(']') } @@ -1568,37 +1555,23 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers6(o out.RawString(prefix) { out.RawByte('[') - for v31, v32 := range in.AWSSecurityCredentials { - if v31 > 0 { + for v30, v31 := range in.AWSSecurityCredentials { + if v30 > 0 { out.RawByte(',') } - if v32 == nil { + if v31 == nil { out.RawString("null") } else { - (*v32).MarshalEasyJSON(out) + (*v31).MarshalEasyJSON(out) } } out.RawByte(']') } } - if len(in.Tracer) != 0 { + if in.Tracer != nil { const prefix string = ",\"tracer\":" out.RawString(prefix) - { - out.RawByte('{') - v33First := true - for v33Name, v33Value := range in.Tracer { - if v33First { - v33First = false - } else { - out.RawByte(',') - } - out.String(string(v33Name)) - out.RawByte(':') - out.String(string(v33Value)) - } - out.RawByte('}') - } + easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgDiscoveryTracermetadataModel(out, *in.Tracer) } if len(in.Variables) != 0 { const prefix string = ",\"variables\":" @@ -1617,6 +1590,157 @@ func (v ProcessContextSerializer) MarshalEasyJSON(w *jwriter.Writer) { func (v *ProcessContextSerializer) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjsonA1e47abeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers6(l, v) } +func easyjsonA1e47abeDecodeGithubComDataDogDatadogAgentPkgDiscoveryTracermetadataModel(in *jlexer.Lexer, out *model.TracerMetadata) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + switch key { + case "schema_version": + if in.IsNull() { + in.Skip() + } else { + out.SchemaVersion = uint8(in.Uint8()) + } + case "runtime_id": + if in.IsNull() { + in.Skip() + } else { + out.RuntimeID = string(in.String()) + } + case "tracer_language": + if in.IsNull() { + in.Skip() + } else { + out.TracerLanguage = string(in.String()) + } + case "tracer_version": + if in.IsNull() { + in.Skip() + } else { + out.TracerVersion = string(in.String()) + } + case "hostname": + if in.IsNull() { + in.Skip() + } else { + out.Hostname = string(in.String()) + } + case "service_name": + if in.IsNull() { + in.Skip() + } else { + out.ServiceName = string(in.String()) + } + case "service_env": + if in.IsNull() { + in.Skip() + } else { + out.ServiceEnv = string(in.String()) + } + case "service_version": + if in.IsNull() { + in.Skip() + } else { + out.ServiceVersion = string(in.String()) + } + case "process_tags": + if in.IsNull() { + in.Skip() + } else { + out.ProcessTags = string(in.String()) + } + case "container_id": + if in.IsNull() { + in.Skip() + } else { + out.ContainerID = string(in.String()) + } + case "logs_collected": + if in.IsNull() { + in.Skip() + } else { + out.LogsCollected = bool(in.Bool()) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgDiscoveryTracermetadataModel(out *jwriter.Writer, in model.TracerMetadata) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"schema_version\":" + out.RawString(prefix[1:]) + out.Uint8(uint8(in.SchemaVersion)) + } + if in.RuntimeID != "" { + const prefix string = ",\"runtime_id\":" + out.RawString(prefix) + out.String(string(in.RuntimeID)) + } + { + const prefix string = ",\"tracer_language\":" + out.RawString(prefix) + out.String(string(in.TracerLanguage)) + } + { + const prefix string = ",\"tracer_version\":" + out.RawString(prefix) + out.String(string(in.TracerVersion)) + } + { + const prefix string = ",\"hostname\":" + out.RawString(prefix) + out.String(string(in.Hostname)) + } + if in.ServiceName != "" { + const prefix string = ",\"service_name\":" + out.RawString(prefix) + out.String(string(in.ServiceName)) + } + if in.ServiceEnv != "" { + const prefix string = ",\"service_env\":" + out.RawString(prefix) + out.String(string(in.ServiceEnv)) + } + if in.ServiceVersion != "" { + const prefix string = ",\"service_version\":" + out.RawString(prefix) + out.String(string(in.ServiceVersion)) + } + if in.ProcessTags != "" { + const prefix string = ",\"process_tags\":" + out.RawString(prefix) + out.String(string(in.ProcessTags)) + } + if in.ContainerID != "" { + const prefix string = ",\"container_id\":" + out.RawString(prefix) + out.String(string(in.ContainerID)) + } + if in.LogsCollected { + const prefix string = ",\"logs_collected\":" + out.RawString(prefix) + out.Bool(bool(in.LogsCollected)) + } + out.RawByte('}') +} func easyjsonA1e47abeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers7(in *jlexer.Lexer, out *SyscallSerializer) { isTopLevel := in.IsStart() if in.IsNull() { @@ -1781,21 +1905,21 @@ func easyjsonA1e47abeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers9(i out.Flows = (out.Flows)[:0] } for !in.IsDelim(']') { - var v34 *FlowSerializer + var v32 *FlowSerializer if in.IsNull() { in.Skip() - v34 = nil + v32 = nil } else { - if v34 == nil { - v34 = new(FlowSerializer) + if v32 == nil { + v32 = new(FlowSerializer) } if in.IsNull() { in.Skip() } else { - (*v34).UnmarshalEasyJSON(in) + (*v32).UnmarshalEasyJSON(in) } } - out.Flows = append(out.Flows, v34) + out.Flows = append(out.Flows, v32) in.WantComma() } in.Delim(']') @@ -1830,14 +1954,14 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers9(o } { out.RawByte('[') - for v35, v36 := range in.Flows { - if v35 > 0 { + for v33, v34 := range in.Flows { + if v33 > 0 { out.RawByte(',') } - if v36 == nil { + if v34 == nil { out.RawString("null") } else { - (*v36).MarshalEasyJSON(out) + (*v34).MarshalEasyJSON(out) } } out.RawByte(']') @@ -2123,13 +2247,13 @@ func easyjsonA1e47abeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers12( out.Tags = (out.Tags)[:0] } for !in.IsDelim(']') { - var v37 string + var v35 string if in.IsNull() { in.Skip() } else { - v37 = string(in.String()) + v35 = string(in.String()) } - out.Tags = append(out.Tags, v37) + out.Tags = append(out.Tags, v35) in.WantComma() } in.Delim(']') @@ -2186,11 +2310,11 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers12( } { out.RawByte('[') - for v38, v39 := range in.Tags { - if v38 > 0 { + for v36, v37 := range in.Tags { + if v36 > 0 { out.RawByte(',') } - out.String(string(v39)) + out.String(string(v37)) } out.RawByte(']') } @@ -2725,13 +2849,13 @@ func easyjsonA1e47abeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers18( out.MatchedRules = (out.MatchedRules)[:0] } for !in.IsDelim(']') { - var v40 MatchedRuleSerializer + var v38 MatchedRuleSerializer if in.IsNull() { in.Skip() } else { - (v40).UnmarshalEasyJSON(in) + (v38).UnmarshalEasyJSON(in) } - out.MatchedRules = append(out.MatchedRules, v40) + out.MatchedRules = append(out.MatchedRules, v38) in.WantComma() } in.Delim(']') @@ -2814,11 +2938,11 @@ func easyjsonA1e47abeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers18( } { out.RawByte('[') - for v41, v42 := range in.MatchedRules { - if v41 > 0 { + for v39, v40 := range in.MatchedRules { + if v39 > 0 { out.RawByte(',') } - (v42).MarshalEasyJSON(out) + (v40).MarshalEasyJSON(out) } out.RawByte(']') } diff --git a/pkg/security/serializers/serializers_linux.go b/pkg/security/serializers/serializers_linux.go index f18f512ffe1fcd..7c936b60e51ea2 100644 --- a/pkg/security/serializers/serializers_linux.go +++ b/pkg/security/serializers/serializers_linux.go @@ -14,7 +14,6 @@ import ( "fmt" "path" "strconv" - "strings" "syscall" "time" @@ -22,6 +21,7 @@ import ( "github.com/google/gopacket/layers" "golang.org/x/sys/unix" + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/events" "github.com/DataDog/datadog-agent/pkg/security/probe/sysctl" sprocess "github.com/DataDog/datadog-agent/pkg/security/resolvers/process" @@ -332,8 +332,8 @@ type ProcessSerializer struct { Syscalls *SyscallsEventSerializer `json:"syscalls,omitempty"` // List of AWS Security Credentials that the process had access to AWSSecurityCredentials []*AWSSecurityCredentialsSerializer `json:"aws_security_credentials,omitempty"` - // Tags from an APM tracer instrumentation - Tracer map[string]string `json:"tracer,omitempty"` + // Metadata from APM tracer instrumentation + Tracer *tracermetadata.TracerMetadata `json:"tracer,omitempty"` // Variable values Variables Variables `json:"variables,omitempty"` } @@ -1006,15 +1006,9 @@ func newProcessSerializer(ps *model.Process, e *model.Event) *ProcessSerializer } } - if len(ps.TracerTags) > 0 { - tracerTags := make(map[string]string, len(ps.TracerTags)) - for _, tag := range ps.TracerTags { - key, value, found := strings.Cut(tag, ":") - if found { - tracerTags[key] = value - } - } - psSerializer.Tracer = tracerTags + if (ps.TracerMetadata != tracermetadata.TracerMetadata{}) { + tmetaCopy := ps.TracerMetadata + psSerializer.Tracer = &tmetaCopy } if len(ps.ContainerContext.ContainerID) != 0 { diff --git a/pkg/security/serializers/serializers_linux_easyjson.go b/pkg/security/serializers/serializers_linux_easyjson.go index 3447d423d90bfa..6ff5da69e6a60e 100644 --- a/pkg/security/serializers/serializers_linux_easyjson.go +++ b/pkg/security/serializers/serializers_linux_easyjson.go @@ -7,6 +7,7 @@ package serializers import ( json "encoding/json" + model "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" utils "github.com/DataDog/datadog-agent/pkg/security/utils" easyjson "github.com/mailru/easyjson" jlexer "github.com/mailru/easyjson/jlexer" @@ -2587,26 +2588,12 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers16( case "tracer": if in.IsNull() { in.Skip() + out.Tracer = nil } else { - in.Delim('{') - if !in.IsDelim('}') { - out.Tracer = make(map[string]string) - } else { - out.Tracer = nil - } - for !in.IsDelim('}') { - key := string(in.String()) - in.WantColon() - var v18 string - if in.IsNull() { - in.Skip() - } else { - v18 = string(in.String()) - } - (out.Tracer)[key] = v18 - in.WantComma() + if out.Tracer == nil { + out.Tracer = new(model.TracerMetadata) } - in.Delim('}') + easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgDiscoveryTracermetadataModel(in, out.Tracer) } case "variables": if in.IsNull() { @@ -2724,11 +2711,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers16( out.RawString(prefix) { out.RawByte('[') - for v19, v20 := range in.CapsAttempted { - if v19 > 0 { + for v18, v19 := range in.CapsAttempted { + if v18 > 0 { out.RawByte(',') } - out.String(string(v20)) + out.String(string(v19)) } out.RawByte(']') } @@ -2738,11 +2725,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers16( out.RawString(prefix) { out.RawByte('[') - for v21, v22 := range in.CapsUsed { - if v21 > 0 { + for v20, v21 := range in.CapsUsed { + if v20 > 0 { out.RawByte(',') } - out.String(string(v22)) + out.String(string(v21)) } out.RawByte(']') } @@ -2782,11 +2769,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers16( out.RawString(prefix) { out.RawByte('[') - for v23, v24 := range in.Args { - if v23 > 0 { + for v22, v23 := range in.Args { + if v22 > 0 { out.RawByte(',') } - out.String(string(v24)) + out.String(string(v23)) } out.RawByte(']') } @@ -2801,11 +2788,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers16( out.RawString(prefix) { out.RawByte('[') - for v25, v26 := range in.Envs { - if v25 > 0 { + for v24, v25 := range in.Envs { + if v24 > 0 { out.RawByte(',') } - out.String(string(v26)) + out.String(string(v25)) } out.RawByte(']') } @@ -2852,11 +2839,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers16( out.RawString("null") } else { out.RawByte('[') - for v27, v28 := range *in.Syscalls { - if v27 > 0 { + for v26, v27 := range *in.Syscalls { + if v26 > 0 { out.RawByte(',') } - easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers17(out, v28) + easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers17(out, v27) } out.RawByte(']') } @@ -2866,37 +2853,23 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers16( out.RawString(prefix) { out.RawByte('[') - for v29, v30 := range in.AWSSecurityCredentials { - if v29 > 0 { + for v28, v29 := range in.AWSSecurityCredentials { + if v28 > 0 { out.RawByte(',') } - if v30 == nil { + if v29 == nil { out.RawString("null") } else { - (*v30).MarshalEasyJSON(out) + (*v29).MarshalEasyJSON(out) } } out.RawByte(']') } } - if len(in.Tracer) != 0 { + if in.Tracer != nil { const prefix string = ",\"tracer\":" out.RawString(prefix) - { - out.RawByte('{') - v31First := true - for v31Name, v31Value := range in.Tracer { - if v31First { - v31First = false - } else { - out.RawByte(',') - } - out.String(string(v31Name)) - out.RawByte(':') - out.String(string(v31Value)) - } - out.RawByte('}') - } + easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgDiscoveryTracermetadataModel(out, *in.Tracer) } if len(in.Variables) != 0 { const prefix string = ",\"variables\":" @@ -2915,6 +2888,157 @@ func (v ProcessSerializer) MarshalEasyJSON(w *jwriter.Writer) { func (v *ProcessSerializer) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers16(l, v) } +func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgDiscoveryTracermetadataModel(in *jlexer.Lexer, out *model.TracerMetadata) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + switch key { + case "schema_version": + if in.IsNull() { + in.Skip() + } else { + out.SchemaVersion = uint8(in.Uint8()) + } + case "runtime_id": + if in.IsNull() { + in.Skip() + } else { + out.RuntimeID = string(in.String()) + } + case "tracer_language": + if in.IsNull() { + in.Skip() + } else { + out.TracerLanguage = string(in.String()) + } + case "tracer_version": + if in.IsNull() { + in.Skip() + } else { + out.TracerVersion = string(in.String()) + } + case "hostname": + if in.IsNull() { + in.Skip() + } else { + out.Hostname = string(in.String()) + } + case "service_name": + if in.IsNull() { + in.Skip() + } else { + out.ServiceName = string(in.String()) + } + case "service_env": + if in.IsNull() { + in.Skip() + } else { + out.ServiceEnv = string(in.String()) + } + case "service_version": + if in.IsNull() { + in.Skip() + } else { + out.ServiceVersion = string(in.String()) + } + case "process_tags": + if in.IsNull() { + in.Skip() + } else { + out.ProcessTags = string(in.String()) + } + case "container_id": + if in.IsNull() { + in.Skip() + } else { + out.ContainerID = string(in.String()) + } + case "logs_collected": + if in.IsNull() { + in.Skip() + } else { + out.LogsCollected = bool(in.Bool()) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgDiscoveryTracermetadataModel(out *jwriter.Writer, in model.TracerMetadata) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"schema_version\":" + out.RawString(prefix[1:]) + out.Uint8(uint8(in.SchemaVersion)) + } + if in.RuntimeID != "" { + const prefix string = ",\"runtime_id\":" + out.RawString(prefix) + out.String(string(in.RuntimeID)) + } + { + const prefix string = ",\"tracer_language\":" + out.RawString(prefix) + out.String(string(in.TracerLanguage)) + } + { + const prefix string = ",\"tracer_version\":" + out.RawString(prefix) + out.String(string(in.TracerVersion)) + } + { + const prefix string = ",\"hostname\":" + out.RawString(prefix) + out.String(string(in.Hostname)) + } + if in.ServiceName != "" { + const prefix string = ",\"service_name\":" + out.RawString(prefix) + out.String(string(in.ServiceName)) + } + if in.ServiceEnv != "" { + const prefix string = ",\"service_env\":" + out.RawString(prefix) + out.String(string(in.ServiceEnv)) + } + if in.ServiceVersion != "" { + const prefix string = ",\"service_version\":" + out.RawString(prefix) + out.String(string(in.ServiceVersion)) + } + if in.ProcessTags != "" { + const prefix string = ",\"process_tags\":" + out.RawString(prefix) + out.String(string(in.ProcessTags)) + } + if in.ContainerID != "" { + const prefix string = ",\"container_id\":" + out.RawString(prefix) + out.String(string(in.ContainerID)) + } + if in.LogsCollected { + const prefix string = ",\"logs_collected\":" + out.RawString(prefix) + out.Bool(bool(in.LogsCollected)) + } + out.RawByte('}') +} func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers17(in *jlexer.Lexer, out *SyscallSerializer) { isTopLevel := in.IsStart() if in.IsNull() { @@ -3084,13 +3208,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers18( out.CapEffective = (out.CapEffective)[:0] } for !in.IsDelim(']') { - var v32 string + var v30 string if in.IsNull() { in.Skip() } else { - v32 = string(in.String()) + v30 = string(in.String()) } - out.CapEffective = append(out.CapEffective, v32) + out.CapEffective = append(out.CapEffective, v30) in.WantComma() } in.Delim(']') @@ -3111,13 +3235,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers18( out.CapPermitted = (out.CapPermitted)[:0] } for !in.IsDelim(']') { - var v33 string + var v31 string if in.IsNull() { in.Skip() } else { - v33 = string(in.String()) + v31 = string(in.String()) } - out.CapPermitted = append(out.CapPermitted, v33) + out.CapPermitted = append(out.CapPermitted, v31) in.WantComma() } in.Delim(']') @@ -3225,11 +3349,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers18( out.RawString("null") } else { out.RawByte('[') - for v34, v35 := range in.CapEffective { - if v34 > 0 { + for v32, v33 := range in.CapEffective { + if v32 > 0 { out.RawByte(',') } - out.String(string(v35)) + out.String(string(v33)) } out.RawByte(']') } @@ -3241,11 +3365,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers18( out.RawString("null") } else { out.RawByte('[') - for v36, v37 := range in.CapPermitted { - if v36 > 0 { + for v34, v35 := range in.CapPermitted { + if v34 > 0 { out.RawByte(',') } - out.String(string(v37)) + out.String(string(v35)) } out.RawByte(']') } @@ -3749,13 +3873,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers23( out.Argv = (out.Argv)[:0] } for !in.IsDelim(']') { - var v38 string + var v36 string if in.IsNull() { in.Skip() } else { - v38 = string(in.String()) + v36 = string(in.String()) } - out.Argv = append(out.Argv, v38) + out.Argv = append(out.Argv, v36) in.WantComma() } in.Delim(']') @@ -3803,11 +3927,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers23( out.RawString(prefix) { out.RawByte('[') - for v39, v40 := range in.Argv { - if v39 > 0 { + for v37, v38 := range in.Argv { + if v37 > 0 { out.RawByte(',') } - out.String(string(v40)) + out.String(string(v38)) } out.RawByte(']') } @@ -4056,13 +4180,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers26( out.K8SGroups = (out.K8SGroups)[:0] } for !in.IsDelim(']') { - var v41 string + var v39 string if in.IsNull() { in.Skip() } else { - v41 = string(in.String()) + v39 = string(in.String()) } - out.K8SGroups = append(out.K8SGroups, v41) + out.K8SGroups = append(out.K8SGroups, v39) in.WantComma() } in.Delim(']') @@ -4080,34 +4204,34 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers26( for !in.IsDelim('}') { key := string(in.String()) in.WantColon() - var v42 []string + var v40 []string if in.IsNull() { in.Skip() - v42 = nil + v40 = nil } else { in.Delim('[') - if v42 == nil { + if v40 == nil { if !in.IsDelim(']') { - v42 = make([]string, 0, 4) + v40 = make([]string, 0, 4) } else { - v42 = []string{} + v40 = []string{} } } else { - v42 = (v42)[:0] + v40 = (v40)[:0] } for !in.IsDelim(']') { - var v43 string + var v41 string if in.IsNull() { in.Skip() } else { - v43 = string(in.String()) + v41 = string(in.String()) } - v42 = append(v42, v43) + v40 = append(v40, v41) in.WantComma() } in.Delim(']') } - (out.K8SExtra)[key] = v42 + (out.K8SExtra)[key] = v40 in.WantComma() } in.Delim('}') @@ -4162,11 +4286,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers26( } { out.RawByte('[') - for v44, v45 := range in.K8SGroups { - if v44 > 0 { + for v42, v43 := range in.K8SGroups { + if v42 > 0 { out.RawByte(',') } - out.String(string(v45)) + out.String(string(v43)) } out.RawByte(']') } @@ -4181,24 +4305,24 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers26( } { out.RawByte('{') - v46First := true - for v46Name, v46Value := range in.K8SExtra { - if v46First { - v46First = false + v44First := true + for v44Name, v44Value := range in.K8SExtra { + if v44First { + v44First = false } else { out.RawByte(',') } - out.String(string(v46Name)) + out.String(string(v44Name)) out.RawByte(':') - if v46Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { + if v44Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 { out.RawString("null") } else { out.RawByte('[') - for v47, v48 := range v46Value { - if v47 > 0 { + for v45, v46 := range v44Value { + if v45 > 0 { out.RawByte(',') } - out.String(string(v48)) + out.String(string(v46)) } out.RawByte(']') } @@ -4370,13 +4494,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers27( out.Flags = (out.Flags)[:0] } for !in.IsDelim(']') { - var v49 string + var v47 string if in.IsNull() { in.Skip() } else { - v49 = string(in.String()) + v47 = string(in.String()) } - out.Flags = append(out.Flags, v49) + out.Flags = append(out.Flags, v47) in.WantComma() } in.Delim(']') @@ -4487,13 +4611,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers27( out.Hashes = (out.Hashes)[:0] } for !in.IsDelim(']') { - var v50 string + var v48 string if in.IsNull() { in.Skip() } else { - v50 = string(in.String()) + v48 = string(in.String()) } - out.Hashes = append(out.Hashes, v50) + out.Hashes = append(out.Hashes, v48) in.WantComma() } in.Delim(']') @@ -4704,11 +4828,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers27( out.RawString(prefix) { out.RawByte('[') - for v51, v52 := range in.Flags { - if v51 > 0 { + for v49, v50 := range in.Flags { + if v49 > 0 { out.RawByte(',') } - out.String(string(v52)) + out.String(string(v50)) } out.RawByte(']') } @@ -4768,11 +4892,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers27( out.RawString(prefix) { out.RawByte('[') - for v53, v54 := range in.Hashes { - if v53 > 0 { + for v51, v52 := range in.Hashes { + if v51 > 0 { out.RawByte(',') } - out.String(string(v54)) + out.String(string(v52)) } out.RawByte(']') } @@ -5172,13 +5296,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers29( out.Flags = (out.Flags)[:0] } for !in.IsDelim(']') { - var v55 string + var v53 string if in.IsNull() { in.Skip() } else { - v55 = string(in.String()) + v53 = string(in.String()) } - out.Flags = append(out.Flags, v55) + out.Flags = append(out.Flags, v53) in.WantComma() } in.Delim(']') @@ -5289,13 +5413,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers29( out.Hashes = (out.Hashes)[:0] } for !in.IsDelim(']') { - var v56 string + var v54 string if in.IsNull() { in.Skip() } else { - v56 = string(in.String()) + v54 = string(in.String()) } - out.Hashes = append(out.Hashes, v56) + out.Hashes = append(out.Hashes, v54) in.WantComma() } in.Delim(']') @@ -5546,11 +5670,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers29( out.RawString(prefix) { out.RawByte('[') - for v57, v58 := range in.Flags { - if v57 > 0 { + for v55, v56 := range in.Flags { + if v55 > 0 { out.RawByte(',') } - out.String(string(v58)) + out.String(string(v56)) } out.RawByte(']') } @@ -5610,11 +5734,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers29( out.RawString(prefix) { out.RawByte('[') - for v59, v60 := range in.Hashes { - if v59 > 0 { + for v57, v58 := range in.Hashes { + if v57 > 0 { out.RawByte(',') } - out.String(string(v60)) + out.String(string(v58)) } out.RawByte(']') } @@ -5991,9 +6115,9 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers30( *out.SyscallsEventSerializer = (*out.SyscallsEventSerializer)[:0] } for !in.IsDelim(']') { - var v61 SyscallSerializer - easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers17(in, &v61) - *out.SyscallsEventSerializer = append(*out.SyscallsEventSerializer, v61) + var v59 SyscallSerializer + easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers17(in, &v59) + *out.SyscallsEventSerializer = append(*out.SyscallsEventSerializer, v59) in.WantComma() } in.Delim(']') @@ -6421,11 +6545,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers30( out.RawString("null") } else { out.RawByte('[') - for v62, v63 := range *in.SyscallsEventSerializer { - if v62 > 0 { + for v60, v61 := range *in.SyscallsEventSerializer { + if v60 > 0 { out.RawByte(',') } - easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers17(out, v63) + easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers17(out, v61) } out.RawByte(']') } @@ -6778,13 +6902,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers32( out.CapEffective = (out.CapEffective)[:0] } for !in.IsDelim(']') { - var v64 string + var v62 string if in.IsNull() { in.Skip() } else { - v64 = string(in.String()) + v62 = string(in.String()) } - out.CapEffective = append(out.CapEffective, v64) + out.CapEffective = append(out.CapEffective, v62) in.WantComma() } in.Delim(']') @@ -6805,13 +6929,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers32( out.CapPermitted = (out.CapPermitted)[:0] } for !in.IsDelim(']') { - var v65 string + var v63 string if in.IsNull() { in.Skip() } else { - v65 = string(in.String()) + v63 = string(in.String()) } - out.CapPermitted = append(out.CapPermitted, v65) + out.CapPermitted = append(out.CapPermitted, v63) in.WantComma() } in.Delim(']') @@ -6902,11 +7026,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers32( out.RawString("null") } else { out.RawByte('[') - for v66, v67 := range in.CapEffective { - if v66 > 0 { + for v64, v65 := range in.CapEffective { + if v64 > 0 { out.RawByte(',') } - out.String(string(v67)) + out.String(string(v65)) } out.RawByte(']') } @@ -6918,11 +7042,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers32( out.RawString("null") } else { out.RawByte('[') - for v68, v69 := range in.CapPermitted { - if v68 > 0 { + for v66, v67 := range in.CapPermitted { + if v66 > 0 { out.RawByte(',') } - out.String(string(v69)) + out.String(string(v67)) } out.RawByte(']') } @@ -6975,13 +7099,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers33( out.Hostnames = (out.Hostnames)[:0] } for !in.IsDelim(']') { - var v70 string + var v68 string if in.IsNull() { in.Skip() } else { - v70 = string(in.String()) + v68 = string(in.String()) } - out.Hostnames = append(out.Hostnames, v70) + out.Hostnames = append(out.Hostnames, v68) in.WantComma() } in.Delim(']') @@ -7018,11 +7142,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers33( out.RawString("null") } else { out.RawByte('[') - for v71, v72 := range in.Hostnames { - if v71 > 0 { + for v69, v70 := range in.Hostnames { + if v69 > 0 { out.RawByte(',') } - out.String(string(v72)) + out.String(string(v70)) } out.RawByte(']') } @@ -7074,13 +7198,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers34( out.CapEffective = (out.CapEffective)[:0] } for !in.IsDelim(']') { - var v73 string + var v71 string if in.IsNull() { in.Skip() } else { - v73 = string(in.String()) + v71 = string(in.String()) } - out.CapEffective = append(out.CapEffective, v73) + out.CapEffective = append(out.CapEffective, v71) in.WantComma() } in.Delim(']') @@ -7101,13 +7225,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers34( out.CapPermitted = (out.CapPermitted)[:0] } for !in.IsDelim(']') { - var v74 string + var v72 string if in.IsNull() { in.Skip() } else { - v74 = string(in.String()) + v72 = string(in.String()) } - out.CapPermitted = append(out.CapPermitted, v74) + out.CapPermitted = append(out.CapPermitted, v72) in.WantComma() } in.Delim(']') @@ -7133,11 +7257,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers34( out.RawString("null") } else { out.RawByte('[') - for v75, v76 := range in.CapEffective { - if v75 > 0 { + for v73, v74 := range in.CapEffective { + if v73 > 0 { out.RawByte(',') } - out.String(string(v76)) + out.String(string(v74)) } out.RawByte(']') } @@ -7149,11 +7273,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers34( out.RawString("null") } else { out.RawByte('[') - for v77, v78 := range in.CapPermitted { - if v77 > 0 { + for v75, v76 := range in.CapPermitted { + if v75 > 0 { out.RawByte(',') } - out.String(string(v78)) + out.String(string(v76)) } out.RawByte(']') } @@ -7200,13 +7324,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers35( out.CapsAttempted = (out.CapsAttempted)[:0] } for !in.IsDelim(']') { - var v79 string + var v77 string if in.IsNull() { in.Skip() } else { - v79 = string(in.String()) + v77 = string(in.String()) } - out.CapsAttempted = append(out.CapsAttempted, v79) + out.CapsAttempted = append(out.CapsAttempted, v77) in.WantComma() } in.Delim(']') @@ -7227,13 +7351,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers35( out.CapsUsed = (out.CapsUsed)[:0] } for !in.IsDelim(']') { - var v80 string + var v78 string if in.IsNull() { in.Skip() } else { - v80 = string(in.String()) + v78 = string(in.String()) } - out.CapsUsed = append(out.CapsUsed, v80) + out.CapsUsed = append(out.CapsUsed, v78) in.WantComma() } in.Delim(']') @@ -7258,11 +7382,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers35( out.RawString(prefix[1:]) { out.RawByte('[') - for v81, v82 := range in.CapsAttempted { - if v81 > 0 { + for v79, v80 := range in.CapsAttempted { + if v79 > 0 { out.RawByte(',') } - out.String(string(v82)) + out.String(string(v80)) } out.RawByte(']') } @@ -7277,11 +7401,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers35( } { out.RawByte('[') - for v83, v84 := range in.CapsUsed { - if v83 > 0 { + for v81, v82 := range in.CapsUsed { + if v81 > 0 { out.RawByte(',') } - out.String(string(v84)) + out.String(string(v82)) } out.RawByte(']') } @@ -7490,13 +7614,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers38( out.Helpers = (out.Helpers)[:0] } for !in.IsDelim(']') { - var v85 string + var v83 string if in.IsNull() { in.Skip() } else { - v85 = string(in.String()) + v83 = string(in.String()) } - out.Helpers = append(out.Helpers, v85) + out.Helpers = append(out.Helpers, v83) in.WantComma() } in.Delim(']') @@ -7561,11 +7685,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers38( } { out.RawByte('[') - for v86, v87 := range in.Helpers { - if v86 > 0 { + for v84, v85 := range in.Helpers { + if v84 > 0 { out.RawByte(',') } - out.String(string(v87)) + out.String(string(v85)) } out.RawByte(']') } @@ -7826,13 +7950,13 @@ func easyjsonDdc0fdbeDecodeGithubComDataDogDatadogAgentPkgSecuritySerializers42( out.Hostnames = (out.Hostnames)[:0] } for !in.IsDelim(']') { - var v88 string + var v86 string if in.IsNull() { in.Skip() } else { - v88 = string(in.String()) + v86 = string(in.String()) } - out.Hostnames = append(out.Hostnames, v88) + out.Hostnames = append(out.Hostnames, v86) in.WantComma() } in.Delim(']') @@ -7863,11 +7987,11 @@ func easyjsonDdc0fdbeEncodeGithubComDataDogDatadogAgentPkgSecuritySerializers42( out.RawString("null") } else { out.RawByte('[') - for v89, v90 := range in.Hostnames { - if v89 > 0 { + for v87, v88 := range in.Hostnames { + if v87 > 0 { out.RawByte(',') } - out.String(string(v90)) + out.String(string(v88)) } out.RawByte(']') } diff --git a/pkg/security/tests/tracer_memfd_test.go b/pkg/security/tests/tracer_memfd_test.go index 241e666664d0c6..9cfcc79f39cbeb 100644 --- a/pkg/security/tests/tracer_memfd_test.go +++ b/pkg/security/tests/tracer_memfd_test.go @@ -19,6 +19,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + tracermetadata "github.com/DataDog/datadog-agent/pkg/discovery/tracermetadata/model" "github.com/DataDog/datadog-agent/pkg/security/ebpf/kernel" "github.com/DataDog/datadog-agent/pkg/security/secl/model" "github.com/DataDog/datadog-agent/pkg/security/serializers" @@ -29,7 +30,7 @@ import ( type tracerMemfdConsumer struct { capturedPid atomic.Uint32 capturedFd atomic.Uint32 - capturedTags []string + capturedMetadata tracermetadata.TracerMetadata capturedSerializedJSON []byte capturedMutex sync.Mutex eventReceived atomic.Bool @@ -71,7 +72,7 @@ func (c *tracerMemfdConsumer) HandleEvent(event any) { c.capturedPid.Store(ev.pid) c.capturedFd.Store(ev.fd) c.capturedMutex.Lock() - c.capturedTags = ev.tracerTags + c.capturedMetadata = ev.tracerMetadata c.capturedSerializedJSON = ev.serializedJSON c.capturedMutex.Unlock() c.eventReceived.Store(true) @@ -81,7 +82,7 @@ func (c *tracerMemfdConsumer) HandleEvent(event any) { type tracerMemfdEvent struct { pid uint32 fd uint32 - tracerTags []string + tracerMetadata tracermetadata.TracerMetadata serializedJSON []byte } @@ -92,15 +93,9 @@ func (c *tracerMemfdConsumer) Copy(ev *model.Event) any { } event := &tracerMemfdEvent{ - pid: ev.GetProcessPid(), - fd: ev.TracerMemfdSeal.Fd, - } - - // Copy the TracerTags using the getter - tracerTags := ev.GetProcessTracerTags() - if len(tracerTags) > 0 { - event.tracerTags = make([]string, len(tracerTags)) - copy(event.tracerTags, tracerTags) + pid: ev.GetProcessPid(), + fd: ev.TracerMemfdSeal.Fd, + tracerMetadata: ev.GetProcessTracerMetadata(), } // Serialize the event to JSON for validation @@ -153,22 +148,17 @@ func TestTracerMemfd(t *testing.T) { require.NotZero(t, capturedFd, "fd should be non-zero") require.Greater(t, capturedFd, uint32(2), "fd should be > 2 (stdin/stdout/stderr)") - // Verify tracer tags from ProcessCacheEntry + // Verify tracer metadata from ProcessCacheEntry consumer.capturedMutex.Lock() - tracerTags := consumer.capturedTags + tmeta := consumer.capturedMetadata consumer.capturedMutex.Unlock() - require.NotEmpty(t, tracerTags, "TracerTags should not be empty") - - // Verify expected tags from the msgp-encoded metadata - expectedTags := []string{ - "tracer_service_name:test-service", - "tracer_service_env:test-env", - "tracer_service_version:1.0.0", - "custom.tag:value", - } + require.NotEqual(t, tracermetadata.TracerMetadata{}, tmeta, "TracerMetadata should not be empty") - require.ElementsMatch(t, tracerTags, expectedTags, "TracerTags") + assert.Equal(t, "test-service", tmeta.ServiceName, "ServiceName mismatch") + assert.Equal(t, "test-env", tmeta.ServiceEnv, "ServiceEnv mismatch") + assert.Equal(t, "1.0.0", tmeta.ServiceVersion, "ServiceVersion mismatch") + assert.Contains(t, tmeta.ProcessTags, "custom.tag:value", "ProcessTags should contain custom.tag") }) test.RunMultiMode(t, "validate-tracer-serialization", func(t *testing.T, _ wrapperType, cmd func(bin string, args []string, envs []string) *exec.Cmd) { @@ -198,9 +188,9 @@ func TestTracerMemfd(t *testing.T) { tracerData, ok := processData["tracer"].(map[string]interface{}) require.True(t, ok, "tracer field should be present in serialized process, got: %v", processData) - assert.Equal(t, "test-service", tracerData["tracer_service_name"], "tracer_service_name mismatch") - assert.Equal(t, "test-env", tracerData["tracer_service_env"], "tracer_service_env mismatch") - assert.Equal(t, "1.0.0", tracerData["tracer_service_version"], "tracer_service_version mismatch") - assert.Equal(t, "value", tracerData["custom.tag"], "custom.tag mismatch") + assert.Equal(t, "test-service", tracerData["service_name"], "service_name mismatch") + assert.Equal(t, "test-env", tracerData["service_env"], "service_env mismatch") + assert.Equal(t, "1.0.0", tracerData["service_version"], "service_version mismatch") + assert.Contains(t, tracerData["process_tags"], "custom.tag:value", "process_tags should contain custom.tag:value") }) }