From 4aaf4e80ebf354d33f293f8355782e534ad9c610 Mon Sep 17 00:00:00 2001 From: Charly Molter Date: Tue, 12 Nov 2024 12:38:30 +0100 Subject: [PATCH] fix(kuma-cp): avoid concurrent access on resource meta (#11997) There were some places where labels on meta weren't not cloned when duplicating the meta. Walked the code for odd usages of `GetLabels()`. See also https://github.com/kumahq/kuma/issues/11886 Signed-off-by: Charly Molter Signed-off-by: Mike Beaumont Co-authored-by: Mike Beaumont --- pkg/kds/util/meta.go | 8 -------- pkg/kds/util/resource.go | 9 +++++++-- pkg/plugins/resources/memory/store.go | 5 +++-- pkg/plugins/resources/remote/store.go | 5 +++-- pkg/plugins/secrets/k8s/store.go | 1 + 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pkg/kds/util/meta.go b/pkg/kds/util/meta.go index 8ba29d994ebe..fb703424a322 100644 --- a/pkg/kds/util/meta.go +++ b/pkg/kds/util/meta.go @@ -53,14 +53,6 @@ func CloneResourceMeta(m model.ResourceMeta, fs ...CloneResourceMetaOpt) model.R return meta } -func kumaResourceMetaToResourceMeta(meta *mesh_proto.KumaResource_Meta) model.ResourceMeta { - return &resourceMeta{ - name: meta.Name, - mesh: meta.Mesh, - labels: meta.GetLabels(), - } -} - func (r *resourceMeta) GetName() string { return r.name } diff --git a/pkg/kds/util/resource.go b/pkg/kds/util/resource.go index 45df2526416b..aec6b9f8f584 100644 --- a/pkg/kds/util/resource.go +++ b/pkg/kds/util/resource.go @@ -2,6 +2,7 @@ package util import ( "fmt" + "maps" "strings" envoy_sd "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" @@ -65,7 +66,7 @@ func ToEnvoyResources(rlist model.ResourceList) ([]envoy_types.Resource, error) Meta: &mesh_proto.KumaResource_Meta{ Name: r.GetMeta().GetName(), Mesh: r.GetMeta().GetMesh(), - Labels: r.GetMeta().GetLabels(), + Labels: maps.Clone(r.GetMeta().GetLabels()), Version: "", }, Spec: pbany, @@ -152,7 +153,11 @@ func toResources(resourceType model.ResourceType, krs []*mesh_proto.KumaResource return nil, err } } - obj.SetMeta(kumaResourceMetaToResourceMeta(kr.Meta)) + obj.SetMeta(&resourceMeta{ + name: kr.GetMeta().GetName(), + mesh: kr.GetMeta().GetMesh(), + labels: maps.Clone(kr.GetMeta().GetLabels()), + }) if err := list.AddItem(obj); err != nil { return nil, err } diff --git a/pkg/plugins/resources/memory/store.go b/pkg/plugins/resources/memory/store.go index 92dcb42cac4b..3e30d1855155 100644 --- a/pkg/plugins/resources/memory/store.go +++ b/pkg/plugins/resources/memory/store.go @@ -3,6 +3,7 @@ package memory import ( "context" "fmt" + "maps" "strconv" "strings" "sync" @@ -131,7 +132,7 @@ func (c *memoryStore) Create(_ context.Context, r core_model.Resource, fs ...sto Version: initialVersion(), CreationTime: opts.CreationTime, ModificationTime: opts.CreationTime, - Labels: opts.Labels, + Labels: maps.Clone(opts.Labels), } // fill the meta @@ -185,7 +186,7 @@ func (c *memoryStore) Update(_ context.Context, r core_model.Resource, fs ...sto meta.Version = meta.Version.Next() meta.ModificationTime = opts.ModificationTime if opts.ModifyLabels { - meta.Labels = opts.Labels + meta.Labels = maps.Clone(opts.Labels) } r.SetMeta(meta) diff --git a/pkg/plugins/resources/remote/store.go b/pkg/plugins/resources/remote/store.go index 564293d0be8f..72a91eb2cf28 100644 --- a/pkg/plugins/resources/remote/store.go +++ b/pkg/plugins/resources/remote/store.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "io" + "maps" "net/http" "strconv" @@ -42,7 +43,7 @@ func (s *remoteStore) Create(ctx context.Context, res model.Resource, fs ...stor Type: string(res.Descriptor().Name), Name: opts.Name, Mesh: opts.Mesh, - Labels: opts.Labels, + Labels: maps.Clone(opts.Labels), } if err := s.upsert(ctx, res, meta); err != nil { return err @@ -56,7 +57,7 @@ func (s *remoteStore) Update(ctx context.Context, res model.Resource, fs ...stor Type: string(res.Descriptor().Name), Name: res.GetMeta().GetName(), Mesh: res.GetMeta().GetMesh(), - Labels: opts.Labels, + Labels: maps.Clone(opts.Labels), } if err := s.upsert(ctx, res, meta); err != nil { return err diff --git a/pkg/plugins/secrets/k8s/store.go b/pkg/plugins/secrets/k8s/store.go index d3f0f492af6f..97cabd54bb52 100644 --- a/pkg/plugins/secrets/k8s/store.go +++ b/pkg/plugins/secrets/k8s/store.go @@ -114,6 +114,7 @@ func (s *KubernetesStore) Update(ctx context.Context, r core_model.Resource, fs } func setLabelsAnnotationsAndMesh(s *kube_core.Secret, mesh string, labels map[string]string) { + labels = maps.Clone(labels) if labels == nil { labels = map[string]string{} }