merged to dunfell

Bruce


In message: [meta-virtualization][dunfell][PATCH] kubernetes: Backport fix for 
CVE-2021-25735 and CVE-2021-25737
on 27/09/2023 Vijay Anusuri via lists.yoctoproject.org wrote:

> From: Vijay Anusuri <[email protected]>
> 
> Upstream-commit:
> https://github.com/kubernetes/kubernetes/commit/e612ebfdff22e4bd27ad8345f7c82f074bfedf26
> &
> https://github.com/kubernetes/kubernetes/commit/d57f0641d60b73934ebc2cdf4b6a63182217d10c
> & 
> https://github.com/kubernetes/kubernetes/commit/901e8e07e1f031456ecd7fefce965aaa05916825
> 
> Signed-off-by: Vijay Anusuri <[email protected]>
> ---
>  .../kubernetes/CVE-2021-25735-pre1.patch      | 613 ++++++++++++++++++
>  .../kubernetes/CVE-2021-25735.patch           | 535 +++++++++++++++
>  .../kubernetes/CVE-2021-25737.patch           | 128 ++++
>  .../kubernetes/kubernetes_git.bb              |   3 +
>  4 files changed, 1279 insertions(+)
>  create mode 100644 
> recipes-containers/kubernetes/kubernetes/CVE-2021-25735-pre1.patch
>  create mode 100644 
> recipes-containers/kubernetes/kubernetes/CVE-2021-25735.patch
>  create mode 100644 
> recipes-containers/kubernetes/kubernetes/CVE-2021-25737.patch
> 
> diff --git 
> a/recipes-containers/kubernetes/kubernetes/CVE-2021-25735-pre1.patch 
> b/recipes-containers/kubernetes/kubernetes/CVE-2021-25735-pre1.patch
> new file mode 100644
> index 00000000..2066188a
> --- /dev/null
> +++ b/recipes-containers/kubernetes/kubernetes/CVE-2021-25735-pre1.patch
> @@ -0,0 +1,613 @@
> +From e612ebfdff22e4bd27ad8345f7c82f074bfedf26 Mon Sep 17 00:00:00 2001
> +From: wojtekt <[email protected]>
> +Date: Tue, 26 Nov 2019 13:29:26 +0100
> +Subject: [PATCH] Immutable field and validation
> +
> +Upstream-Status: Backport 
> [https://github.com/kubernetes/kubernetes/commit/e612ebfdff22e4bd27ad8345f7c82f074bfedf26]
> +CVE: CVE-2021-25735 #Dependency Patch1
> +Signed-off-by: Vijay Anusuri <[email protected]>
> +---
> + pkg/apis/core/types.go                        |  12 +
> + pkg/apis/core/validation/validation.go        |  24 +-
> + pkg/apis/core/validation/validation_test.go   | 209 ++++++++++++++++--
> + pkg/features/kube_features.go                 |   7 +
> + pkg/registry/core/configmap/strategy.go       |  28 ++-
> + pkg/registry/core/secret/strategy.go          |  17 ++
> + staging/src/k8s.io/api/core/v1/types.go       |  16 ++
> + .../k8sdeps/transformer/hash/hash.go          |  20 +-
> + .../k8sdeps/transformer/hash/hash_test.go     |   4 +-
> + .../src/k8s.io/kubectl/pkg/util/hash/hash.go  |  20 +-
> + .../k8s.io/kubectl/pkg/util/hash/hash_test.go |   4 +-
> + 11 files changed, 322 insertions(+), 39 deletions(-)
> +
> +diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go
> +index 74d22ae973e87..c5ada193effc4 100644
> +--- a/src/import/pkg/apis/core/types.go
> ++++ b/src/import/pkg/apis/core/types.go
> +@@ -4735,6 +4735,12 @@ type Secret struct {
> +     // +optional
> +     metav1.ObjectMeta
> + 
> ++    // Immutable field, if set, ensures that data stored in the Secret 
> cannot
> ++    // be updated (only object metadata can be modified).
> ++    // This is an alpha field enabled by ImmutableEphemeralVolumes feature 
> gate.
> ++    // +optional
> ++    Immutable *bool
> ++
> +     // Data contains the secret data. Each key must consist of alphanumeric
> +     // characters, '-', '_' or '.'. The serialized form of the secret data 
> is a
> +     // base64 encoded string, representing the arbitrary (possibly 
> non-string)
> +@@ -4857,6 +4863,12 @@ type ConfigMap struct {
> +     // +optional
> +     metav1.ObjectMeta
> + 
> ++    // Immutable field, if set, ensures that data stored in the ConfigMap 
> cannot
> ++    // be updated (only object metadata can be modified).
> ++    // This is an alpha field enabled by ImmutableEphemeralVolumes feature 
> gate.
> ++    // +optional
> ++    Immutable *bool
> ++
> +     // Data contains the configuration data.
> +     // Each key must consist of alphanumeric characters, '-', '_' or '.'.
> +     // Values with non-UTF-8 byte sequences must use the BinaryData field.
> +diff --git a/pkg/apis/core/validation/validation.go 
> b/pkg/apis/core/validation/validation.go
> +index 4ad241c745b7d..8e3cfd9d9e423 100644
> +--- a/src/import/pkg/apis/core/validation/validation.go
> ++++ b/src/import/pkg/apis/core/validation/validation.go
> +@@ -5005,6 +5005,16 @@ func ValidateSecretUpdate(newSecret, oldSecret 
> *core.Secret) field.ErrorList {
> +     }
> + 
> +     allErrs = append(allErrs, ValidateImmutableField(newSecret.Type, 
> oldSecret.Type, field.NewPath("type"))...)
> ++    if oldSecret.Immutable != nil && *oldSecret.Immutable {
> ++            if !reflect.DeepEqual(newSecret.Immutable, oldSecret.Immutable) 
> {
> ++                    allErrs = append(allErrs, 
> field.Forbidden(field.NewPath("immutable"), "field is immutable when 
> `immutable` is set"))
> ++            }
> ++            if !reflect.DeepEqual(newSecret.Data, oldSecret.Data) {
> ++                    allErrs = append(allErrs, 
> field.Forbidden(field.NewPath("data"), "field is immutable when `immutable` 
> is set"))
> ++            }
> ++            // We don't validate StringData, as it was already converted 
> back to Data
> ++            // before validation is happening.
> ++    }
> + 
> +     allErrs = append(allErrs, ValidateSecret(newSecret)...)
> +     return allErrs
> +@@ -5051,8 +5061,20 @@ func ValidateConfigMap(cfg *core.ConfigMap) 
> field.ErrorList {
> + func ValidateConfigMapUpdate(newCfg, oldCfg *core.ConfigMap) 
> field.ErrorList {
> +     allErrs := field.ErrorList{}
> +     allErrs = append(allErrs, ValidateObjectMetaUpdate(&newCfg.ObjectMeta, 
> &oldCfg.ObjectMeta, field.NewPath("metadata"))...)
> +-    allErrs = append(allErrs, ValidateConfigMap(newCfg)...)
> + 
> ++    if oldCfg.Immutable != nil && *oldCfg.Immutable {
> ++            if !reflect.DeepEqual(newCfg.Immutable, oldCfg.Immutable) {
> ++                    allErrs = append(allErrs, 
> field.Forbidden(field.NewPath("immutable"), "field is immutable when 
> `immutable` is set"))
> ++            }
> ++            if !reflect.DeepEqual(newCfg.Data, oldCfg.Data) {
> ++                    allErrs = append(allErrs, 
> field.Forbidden(field.NewPath("data"), "field is immutable when `immutable` 
> is set"))
> ++            }
> ++            if !reflect.DeepEqual(newCfg.BinaryData, oldCfg.BinaryData) {
> ++                    allErrs = append(allErrs, 
> field.Forbidden(field.NewPath("binaryData"), "field is immutable when 
> `immutable` is set"))
> ++            }
> ++    }
> ++
> ++    allErrs = append(allErrs, ValidateConfigMap(newCfg)...)
> +     return allErrs
> + }
> + 
> +diff --git a/pkg/apis/core/validation/validation_test.go 
> b/pkg/apis/core/validation/validation_test.go
> +index 8ba68da00fe05..de8c1d49fc196 100644
> +--- a/src/import/pkg/apis/core/validation/validation_test.go
> ++++ b/src/import/pkg/apis/core/validation/validation_test.go
> +@@ -13117,6 +13117,104 @@ func TestValidateSecret(t *testing.T) {
> +     }
> + }
> + 
> ++func TestValidateSecretUpdate(t *testing.T) {
> ++    validSecret := func() core.Secret {
> ++            return core.Secret{
> ++                    ObjectMeta: metav1.ObjectMeta{
> ++                            Name:            "foo",
> ++                            Namespace:       "bar",
> ++                            ResourceVersion: "20",
> ++                    },
> ++                    Data: map[string][]byte{
> ++                            "data-1": []byte("bar"),
> ++                    },
> ++            }
> ++    }
> ++
> ++    falseVal := false
> ++    trueVal := true
> ++
> ++    secret := validSecret()
> ++    immutableSecret := validSecret()
> ++    immutableSecret.Immutable = &trueVal
> ++    mutableSecret := validSecret()
> ++    mutableSecret.Immutable = &falseVal
> ++
> ++    secretWithData := validSecret()
> ++    secretWithData.Data["data-2"] = []byte("baz")
> ++    immutableSecretWithData := validSecret()
> ++    immutableSecretWithData.Immutable = &trueVal
> ++    immutableSecretWithData.Data["data-2"] = []byte("baz")
> ++
> ++    secretWithChangedData := validSecret()
> ++    secretWithChangedData.Data["data-1"] = []byte("foo")
> ++    immutableSecretWithChangedData := validSecret()
> ++    immutableSecretWithChangedData.Immutable = &trueVal
> ++    immutableSecretWithChangedData.Data["data-1"] = []byte("foo")
> ++
> ++    tests := []struct {
> ++            name      string
> ++            oldSecret core.Secret
> ++            newSecret core.Secret
> ++            valid     bool
> ++    }{
> ++            {
> ++                    name:      "mark secret immutable",
> ++                    oldSecret: secret,
> ++                    newSecret: immutableSecret,
> ++                    valid:     true,
> ++            },
> ++            {
> ++                    name:      "revert immutable secret",
> ++                    oldSecret: immutableSecret,
> ++                    newSecret: secret,
> ++                    valid:     false,
> ++            },
> ++            {
> ++                    name:      "makr immutable secret mutable",
> ++                    oldSecret: immutableSecret,
> ++                    newSecret: mutableSecret,
> ++                    valid:     false,
> ++            },
> ++            {
> ++                    name:      "add data in secret",
> ++                    oldSecret: secret,
> ++                    newSecret: secretWithData,
> ++                    valid:     true,
> ++            },
> ++            {
> ++                    name:      "add data in immutable secret",
> ++                    oldSecret: immutableSecret,
> ++                    newSecret: immutableSecretWithData,
> ++                    valid:     false,
> ++            },
> ++            {
> ++                    name:      "change data in secret",
> ++                    oldSecret: secret,
> ++                    newSecret: secretWithChangedData,
> ++                    valid:     true,
> ++            },
> ++            {
> ++                    name:      "change data in immutable secret",
> ++                    oldSecret: immutableSecret,
> ++                    newSecret: immutableSecretWithChangedData,
> ++                    valid:     false,
> ++            },
> ++    }
> ++
> ++    for _, tc := range tests {
> ++            t.Run(tc.name, func(t *testing.T) {
> ++                    errs := ValidateSecretUpdate(&tc.newSecret, 
> &tc.oldSecret)
> ++                    if tc.valid && len(errs) > 0 {
> ++                            t.Errorf("Unexpected error: %v", errs)
> ++                    }
> ++                    if !tc.valid && len(errs) == 0 {
> ++                            t.Errorf("Unexpected lack of error")
> ++                    }
> ++            })
> ++    }
> ++}
> ++
> + func TestValidateDockerConfigSecret(t *testing.T) {
> +     validDockerSecret := func() core.Secret {
> +             return core.Secret{
> +@@ -13731,40 +13829,105 @@ func TestValidateConfigMapUpdate(t *testing.T) {
> +                     Data: data,
> +             }
> +     }
> ++    validConfigMap := func() core.ConfigMap {
> ++            return newConfigMap("1", "validname", "validdns", 
> map[string]string{"key": "value"})
> ++    }
> + 
> +-    var (
> +-            validConfigMap = newConfigMap("1", "validname", "validns", 
> map[string]string{"key": "value"})
> +-            noVersion      = newConfigMap("", "validname", "validns", 
> map[string]string{"key": "value"})
> +-    )
> ++    falseVal := false
> ++    trueVal := true
> ++
> ++    configMap := validConfigMap()
> ++    immutableConfigMap := validConfigMap()
> ++    immutableConfigMap.Immutable = &trueVal
> ++    mutableConfigMap := validConfigMap()
> ++    mutableConfigMap.Immutable = &falseVal
> ++
> ++    configMapWithData := validConfigMap()
> ++    configMapWithData.Data["key-2"] = "value-2"
> ++    immutableConfigMapWithData := validConfigMap()
> ++    immutableConfigMapWithData.Immutable = &trueVal
> ++    immutableConfigMapWithData.Data["key-2"] = "value-2"
> ++
> ++    configMapWithChangedData := validConfigMap()
> ++    configMapWithChangedData.Data["key"] = "foo"
> ++    immutableConfigMapWithChangedData := validConfigMap()
> ++    immutableConfigMapWithChangedData.Immutable = &trueVal
> ++    immutableConfigMapWithChangedData.Data["key"] = "foo"
> ++
> ++    noVersion := newConfigMap("", "validname", "validns", 
> map[string]string{"key": "value"})
> + 
> +     cases := []struct {
> +-            name    string
> +-            newCfg  core.ConfigMap
> +-            oldCfg  core.ConfigMap
> +-            isValid bool
> ++            name   string
> ++            newCfg core.ConfigMap
> ++            oldCfg core.ConfigMap
> ++            valid  bool
> +     }{
> +             {
> +-                    name:    "valid",
> +-                    newCfg:  validConfigMap,
> +-                    oldCfg:  validConfigMap,
> +-                    isValid: true,
> ++                    name:   "valid",
> ++                    newCfg: configMap,
> ++                    oldCfg: configMap,
> ++                    valid:  true,
> +             },
> +             {
> +-                    name:    "invalid",
> +-                    newCfg:  noVersion,
> +-                    oldCfg:  validConfigMap,
> +-                    isValid: false,
> ++                    name:   "invalid",
> ++                    newCfg: noVersion,
> ++                    oldCfg: configMap,
> ++                    valid:  false,
> ++            },
> ++            {
> ++                    name:   "mark configmap immutable",
> ++                    oldCfg: configMap,
> ++                    newCfg: immutableConfigMap,
> ++                    valid:  true,
> ++            },
> ++            {
> ++                    name:   "revert immutable configmap",
> ++                    oldCfg: immutableConfigMap,
> ++                    newCfg: configMap,
> ++                    valid:  false,
> ++            },
> ++            {
> ++                    name:   "mark immutable configmap mutable",
> ++                    oldCfg: immutableConfigMap,
> ++                    newCfg: mutableConfigMap,
> ++                    valid:  false,
> ++            },
> ++            {
> ++                    name:   "add data in configmap",
> ++                    oldCfg: configMap,
> ++                    newCfg: configMapWithData,
> ++                    valid:  true,
> ++            },
> ++            {
> ++                    name:   "add data in immutable configmap",
> ++                    oldCfg: immutableConfigMap,
> ++                    newCfg: immutableConfigMapWithData,
> ++                    valid:  false,
> ++            },
> ++            {
> ++                    name:   "change data in configmap",
> ++                    oldCfg: configMap,
> ++                    newCfg: configMapWithChangedData,
> ++                    valid:  true,
> ++            },
> ++            {
> ++                    name:   "change data in immutable configmap",
> ++                    oldCfg: immutableConfigMap,
> ++                    newCfg: immutableConfigMapWithChangedData,
> ++                    valid:  false,
> +             },
> +     }
> + 
> +     for _, tc := range cases {
> +-            errs := ValidateConfigMapUpdate(&tc.newCfg, &tc.oldCfg)
> +-            if tc.isValid && len(errs) > 0 {
> +-                    t.Errorf("%v: unexpected error: %v", tc.name, errs)
> +-            }
> +-            if !tc.isValid && len(errs) == 0 {
> +-                    t.Errorf("%v: unexpected non-error", tc.name)
> +-            }
> ++            t.Run(tc.name, func(t *testing.T) {
> ++                    errs := ValidateConfigMapUpdate(&tc.newCfg, &tc.oldCfg)
> ++                    if tc.valid && len(errs) > 0 {
> ++                            t.Errorf("Unexpected error: %v", errs)
> ++                    }
> ++                    if !tc.valid && len(errs) == 0 {
> ++                            t.Errorf("Unexpected lack of error")
> ++                    }
> ++            })
> +     }
> + }
> + 
> +diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go
> +index 309dbb2955663..00da711112d71 100644
> +--- a/src/import/pkg/features/kube_features.go
> ++++ b/src/import/pkg/features/kube_features.go
> +@@ -548,6 +548,12 @@ const (
> +     //
> +     // Enables topology aware service routing
> +     ServiceTopology featuregate.Feature = "ServiceTopology"
> ++
> ++    // owner: @wojtek-t
> ++    // alpha: v1.18
> ++    //
> ++    // Enables a feature to make secrets and configmaps data immutable.
> ++    ImmutableEphemeralVolumes featuregate.Feature = 
> "ImmutableEphemeralVolumes"
> + )
> + 
> + func init() {
> +@@ -634,6 +640,7 @@ var defaultKubernetesFeatureGates = 
> map[featuregate.Feature]featuregate.FeatureS
> +     AllowInsecureBackendProxy:                      {Default: true, 
> PreRelease: featuregate.Beta},
> +     PodDisruptionBudget:                            {Default: true, 
> PreRelease: featuregate.Beta},
> +     ServiceTopology:                                {Default: false, 
> PreRelease: featuregate.Alpha},
> ++    ImmutableEphemeralVolumes:                      {Default: false, 
> PreRelease: featuregate.Alpha},
> + 
> +     // inherited features from generic apiserver, relisted here to get a 
> conflict if it is changed
> +     // unintentionally on either side:
> +diff --git a/pkg/registry/core/configmap/strategy.go 
> b/pkg/registry/core/configmap/strategy.go
> +index 4f8bf42e3bd60..d592c181c0c2e 100644
> +--- a/src/import/pkg/registry/core/configmap/strategy.go
> ++++ b/src/import/pkg/registry/core/configmap/strategy.go
> +@@ -28,9 +28,11 @@ import (
> +     "k8s.io/apiserver/pkg/registry/rest"
> +     pkgstorage "k8s.io/apiserver/pkg/storage"
> +     "k8s.io/apiserver/pkg/storage/names"
> ++    utilfeature "k8s.io/apiserver/pkg/util/feature"
> +     "k8s.io/kubernetes/pkg/api/legacyscheme"
> +     api "k8s.io/kubernetes/pkg/apis/core"
> +     "k8s.io/kubernetes/pkg/apis/core/validation"
> ++    "k8s.io/kubernetes/pkg/features"
> + )
> + 
> + // strategy implements behavior for ConfigMap objects
> +@@ -54,7 +56,8 @@ func (strategy) NamespaceScoped() bool {
> + }
> + 
> + func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
> +-    _ = obj.(*api.ConfigMap)
> ++    configMap := obj.(*api.ConfigMap)
> ++    dropDisabledFields(configMap, nil)
> + }
> + 
> + func (strategy) Validate(ctx context.Context, obj runtime.Object) 
> field.ErrorList {
> +@@ -72,12 +75,9 @@ func (strategy) AllowCreateOnUpdate() bool {
> + }
> + 
> + func (strategy) PrepareForUpdate(ctx context.Context, newObj, oldObj 
> runtime.Object) {
> +-    _ = oldObj.(*api.ConfigMap)
> +-    _ = newObj.(*api.ConfigMap)
> +-}
> +-
> +-func (strategy) AllowUnconditionalUpdate() bool {
> +-    return true
> ++    oldConfigMap := oldObj.(*api.ConfigMap)
> ++    newConfigMap := newObj.(*api.ConfigMap)
> ++    dropDisabledFields(newConfigMap, oldConfigMap)
> + }
> + 
> + func (strategy) ValidateUpdate(ctx context.Context, newObj, oldObj 
> runtime.Object) field.ErrorList {
> +@@ -86,6 +86,20 @@ func (strategy) ValidateUpdate(ctx context.Context, 
> newObj, oldObj runtime.Objec
> +     return validation.ValidateConfigMapUpdate(newCfg, oldCfg)
> + }
> + 
> ++func isImmutableInUse(configMap *api.ConfigMap) bool {
> ++    return configMap != nil && configMap.Immutable != nil
> ++}
> ++
> ++func dropDisabledFields(configMap *api.ConfigMap, oldConfigMap 
> *api.ConfigMap) {
> ++    if 
> !utilfeature.DefaultFeatureGate.Enabled(features.ImmutableEphemeralVolumes) 
> && !isImmutableInUse(oldConfigMap) {
> ++            configMap.Immutable = nil
> ++    }
> ++}
> ++
> ++func (strategy) AllowUnconditionalUpdate() bool {
> ++    return true
> ++}
> ++
> + // GetAttrs returns labels and fields of a given object for filtering 
> purposes.
> + func GetAttrs(obj runtime.Object) (labels.Set, fields.Set, error) {
> +     configMap, ok := obj.(*api.ConfigMap)
> +diff --git a/pkg/registry/core/secret/strategy.go 
> b/pkg/registry/core/secret/strategy.go
> +index 1701805065e6c..0d5908d8975f1 100644
> +--- a/src/import/pkg/registry/core/secret/strategy.go
> ++++ b/src/import/pkg/registry/core/secret/strategy.go
> +@@ -29,9 +29,11 @@ import (
> +     "k8s.io/apiserver/pkg/registry/rest"
> +     pkgstorage "k8s.io/apiserver/pkg/storage"
> +     "k8s.io/apiserver/pkg/storage/names"
> ++    utilfeature "k8s.io/apiserver/pkg/util/feature"
> +     "k8s.io/kubernetes/pkg/api/legacyscheme"
> +     api "k8s.io/kubernetes/pkg/apis/core"
> +     "k8s.io/kubernetes/pkg/apis/core/validation"
> ++    "k8s.io/kubernetes/pkg/features"
> + )
> + 
> + // strategy implements behavior for Secret objects
> +@@ -53,6 +55,8 @@ func (strategy) NamespaceScoped() bool {
> + }
> + 
> + func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
> ++    secret := obj.(*api.Secret)
> ++    dropDisabledFields(secret, nil)
> + }
> + 
> + func (strategy) Validate(ctx context.Context, obj runtime.Object) 
> field.ErrorList {
> +@@ -67,12 +71,25 @@ func (strategy) AllowCreateOnUpdate() bool {
> + }
> + 
> + func (strategy) PrepareForUpdate(ctx context.Context, obj, old 
> runtime.Object) {
> ++    newSecret := obj.(*api.Secret)
> ++    oldSecret := old.(*api.Secret)
> ++    dropDisabledFields(newSecret, oldSecret)
> + }
> + 
> + func (strategy) ValidateUpdate(ctx context.Context, obj, old 
> runtime.Object) field.ErrorList {
> +     return validation.ValidateSecretUpdate(obj.(*api.Secret), 
> old.(*api.Secret))
> + }
> + 
> ++func isImmutableInUse(secret *api.Secret) bool {
> ++    return secret != nil && secret.Immutable != nil
> ++}
> ++
> ++func dropDisabledFields(secret *api.Secret, oldSecret *api.Secret) {
> ++    if 
> !utilfeature.DefaultFeatureGate.Enabled(features.ImmutableEphemeralVolumes) 
> && !isImmutableInUse(oldSecret) {
> ++            secret.Immutable = nil
> ++    }
> ++}
> ++
> + func (strategy) AllowUnconditionalUpdate() bool {
> +     return true
> + }
> +diff --git a/staging/src/k8s.io/api/core/v1/types.go 
> b/staging/src/k8s.io/api/core/v1/types.go
> +index a78372aeaffa7..1e3aa51730427 100644
> +--- a/src/import/staging/src/k8s.io/api/core/v1/types.go
> ++++ b/src/import/staging/src/k8s.io/api/core/v1/types.go
> +@@ -5424,6 +5424,14 @@ type Secret struct {
> +     // +optional
> +     metav1.ObjectMeta `json:"metadata,omitempty" 
> protobuf:"bytes,1,opt,name=metadata"`
> + 
> ++    // Immutable, if set to true, ensures that data stored in the Secret 
> cannot
> ++    // be updated (only object metadata can be modified).
> ++    // If not set to true, the field can be modified at any time.
> ++    // Defaulted to nil.
> ++    // This is an alpha field enabled by ImmutableEphemeralVolumes feature 
> gate.
> ++    // +optional
> ++    Immutable *bool `json:"immutable,omitempty"`
> ++
> +     // Data contains the secret data. Each key must consist of alphanumeric
> +     // characters, '-', '_' or '.'. The serialized form of the secret data 
> is a
> +     // base64 encoded string, representing the arbitrary (possibly 
> non-string)
> +@@ -5557,6 +5565,14 @@ type ConfigMap struct {
> +     // +optional
> +     metav1.ObjectMeta `json:"metadata,omitempty" 
> protobuf:"bytes,1,opt,name=metadata"`
> + 
> ++    // Immutable, if set to true, ensures that data stored in the ConfigMap 
> cannot
> ++    // be updated (only object metadata can be modified).
> ++    // If not set to true, the field can be modified at any time.
> ++    // Defaulted to nil.
> ++    // This is an alpha field enabled by ImmutableEphemeralVolumes feature 
> gate.
> ++    // +optional
> ++    Immutable *bool `json:"immutable,omitempty"`
> ++
> +     // Data contains the configuration data.
> +     // Each key must consist of alphanumeric characters, '-', '_' or '.'.
> +     // Values with non-UTF-8 byte sequences must use the BinaryData field.
> +diff --git 
> a/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash.go
>  
> b/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash.go
> +index 17e24ff3e6443..85bf1e731c3fb 100644
> +--- 
> a/src/import/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash.go
> ++++ 
> b/src/import/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash.go
> +@@ -90,7 +90,14 @@ func SecretHash(sec *v1.Secret) (string, error) {
> + // Data, Kind, and Name are taken into account.
> + func encodeConfigMap(cm *v1.ConfigMap) (string, error) {
> +     // json.Marshal sorts the keys in a stable order in the encoding
> +-    m := map[string]interface{}{"kind": "ConfigMap", "name": cm.Name, 
> "data": cm.Data}
> ++    m := map[string]interface{}{
> ++            "kind": "ConfigMap",
> ++            "name": cm.Name,
> ++            "data": cm.Data,
> ++    }
> ++    if cm.Immutable != nil {
> ++            m["immutable"] = *cm.Immutable
> ++    }
> +     if len(cm.BinaryData) > 0 {
> +             m["binaryData"] = cm.BinaryData
> +     }
> +@@ -105,7 +112,16 @@ func encodeConfigMap(cm *v1.ConfigMap) (string, error) {
> + // Data, Kind, Name, and Type are taken into account.
> + func encodeSecret(sec *v1.Secret) (string, error) {
> +     // json.Marshal sorts the keys in a stable order in the encoding
> +-    data, err := json.Marshal(map[string]interface{}{"kind": "Secret", 
> "type": sec.Type, "name": sec.Name, "data": sec.Data})
> ++    m := map[string]interface{}{
> ++            "kind": "Secret",
> ++            "type": sec.Type,
> ++            "name": sec.Name,
> ++            "data": sec.Data,
> ++    }
> ++    if sec.Immutable != nil {
> ++            m["immutable"] = *sec.Immutable
> ++    }
> ++    data, err := json.Marshal(m)
> +     if err != nil {
> +             return "", err
> +     }
> +diff --git 
> a/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash_test.go
>  
> b/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash_test.go
> +index 2d336f35a824e..144fe444e4cac 100644
> +--- 
> a/src/import/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash_test.go
> ++++ 
> b/src/import/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps/transformer/hash/hash_test.go
> +@@ -178,8 +178,8 @@ not their metadata (e.g. the Data of a ConfigMap, but 
> nothing in ObjectMeta).
> +             obj      interface{}
> +             expect   int
> +     }{
> +-            {"ConfigMap", v1.ConfigMap{}, 4},
> +-            {"Secret", v1.Secret{}, 5},
> ++            {"ConfigMap", v1.ConfigMap{}, 5},
> ++            {"Secret", v1.Secret{}, 6},
> +     }
> +     for _, c := range cases {
> +             val := reflect.ValueOf(c.obj)
> +diff --git a/staging/src/k8s.io/kubectl/pkg/util/hash/hash.go 
> b/staging/src/k8s.io/kubectl/pkg/util/hash/hash.go
> +index de0036245d2f1..1b20f384b7098 100644
> +--- a/src/import/staging/src/k8s.io/kubectl/pkg/util/hash/hash.go
> ++++ b/src/import/staging/src/k8s.io/kubectl/pkg/util/hash/hash.go
> +@@ -56,7 +56,14 @@ func SecretHash(sec *v1.Secret) (string, error) {
> + // Data, Kind, and Name are taken into account.
> + func encodeConfigMap(cm *v1.ConfigMap) (string, error) {
> +     // json.Marshal sorts the keys in a stable order in the encoding
> +-    m := map[string]interface{}{"kind": "ConfigMap", "name": cm.Name, 
> "data": cm.Data}
> ++    m := map[string]interface{}{
> ++            "kind": "ConfigMap",
> ++            "name": cm.Name,
> ++            "data": cm.Data,
> ++    }
> ++    if cm.Immutable != nil {
> ++            m["immutable"] = *cm.Immutable
> ++    }
> +     if len(cm.BinaryData) > 0 {
> +             m["binaryData"] = cm.BinaryData
> +     }
> +@@ -70,8 +77,17 @@ func encodeConfigMap(cm *v1.ConfigMap) (string, error) {
> + // encodeSecret encodes a Secret.
> + // Data, Kind, Name, and Type are taken into account.
> + func encodeSecret(sec *v1.Secret) (string, error) {
> ++    m := map[string]interface{}{
> ++            "kind": "Secret",
> ++            "type": sec.Type,
> ++            "name": sec.Name,
> ++            "data": sec.Data,
> ++    }
> ++    if sec.Immutable != nil {
> ++            m["immutable"] = *sec.Immutable
> ++    }
> +     // json.Marshal sorts the keys in a stable order in the encoding
> +-    data, err := json.Marshal(map[string]interface{}{"kind": "Secret", 
> "type": sec.Type, "name": sec.Name, "data": sec.Data})
> ++    data, err := json.Marshal(m)
> +     if err != nil {
> +             return "", err
> +     }
> +diff --git a/staging/src/k8s.io/kubectl/pkg/util/hash/hash_test.go 
> b/staging/src/k8s.io/kubectl/pkg/util/hash/hash_test.go
> +index f527a98a2026c..455459c3b3df5 100644
> +--- a/src/import/staging/src/k8s.io/kubectl/pkg/util/hash/hash_test.go
> ++++ b/src/import/staging/src/k8s.io/kubectl/pkg/util/hash/hash_test.go
> +@@ -164,8 +164,8 @@ not their metadata (e.g. the Data of a ConfigMap, but 
> nothing in ObjectMeta).
> +             obj      interface{}
> +             expect   int
> +     }{
> +-            {"ConfigMap", v1.ConfigMap{}, 4},
> +-            {"Secret", v1.Secret{}, 5},
> ++            {"ConfigMap", v1.ConfigMap{}, 5},
> ++            {"Secret", v1.Secret{}, 6},
> +     }
> +     for _, c := range cases {
> +             val := reflect.ValueOf(c.obj)
> diff --git a/recipes-containers/kubernetes/kubernetes/CVE-2021-25735.patch 
> b/recipes-containers/kubernetes/kubernetes/CVE-2021-25735.patch
> new file mode 100644
> index 00000000..dce50f3e
> --- /dev/null
> +++ b/recipes-containers/kubernetes/kubernetes/CVE-2021-25735.patch
> @@ -0,0 +1,535 @@
> +From 7d4efe7ad8cf06c0c1d6092cf1f77964edb8016f Mon Sep 17 00:00:00 2001
> +From: David Eads <[email protected]>
> +Date: Fri, 29 Jan 2021 13:47:31 -0500
> +Subject: [PATCH 1/8] tweak validation to avoid mutation
> +
> +Upstream-Status: Backport 
> [https://github.com/kubernetes/kubernetes/commit/d57f0641d60b73934ebc2cdf4b6a63182217d10c]
> +CVE: CVE-2021-25735
> +Signed-off-by: Vijay Anusuri <[email protected]>
> +---
> + pkg/apis/core/validation/validation.go | 46 +++++++++-----------------
> + 1 file changed, 15 insertions(+), 31 deletions(-)
> +
> +diff --git a/pkg/apis/core/validation/validation.go 
> b/pkg/apis/core/validation/validation.go
> +index 8e3cfd9d9e4..89e5b5811c4 100644
> +--- a/src/import/pkg/apis/core/validation/validation.go
> ++++ b/src/import/pkg/apis/core/validation/validation.go
> +@@ -29,8 +29,6 @@ import (
> +     "unicode"
> +     "unicode/utf8"
> + 
> +-    "k8s.io/klog"
> +-
> +     "k8s.io/api/core/v1"
> +     apiequality "k8s.io/apimachinery/pkg/api/equality"
> +     "k8s.io/apimachinery/pkg/api/resource"
> +@@ -4530,11 +4528,8 @@ func ValidateNodeUpdate(node, oldNode *core.Node) 
> field.ErrorList {
> +             addresses[address] = true
> +     }
> + 
> +-    if len(oldNode.Spec.PodCIDRs) == 0 {
> +-            // Allow the controller manager to assign a CIDR to a node if 
> it doesn't have one.
> +-            //this is a no op for a string slice.
> +-            oldNode.Spec.PodCIDRs = node.Spec.PodCIDRs
> +-    } else {
> ++    // Allow the controller manager to assign a CIDR to a node if it 
> doesn't have one.
> ++    if len(oldNode.Spec.PodCIDRs) > 0 {
> +             // compare the entire slice
> +             if len(oldNode.Spec.PodCIDRs) != len(node.Spec.PodCIDRs) {
> +                     allErrs = append(allErrs, 
> field.Forbidden(field.NewPath("spec", "podCIDRs"), "node updates may not 
> change podCIDR except from \"\" to valid"))
> +@@ -4548,46 +4543,35 @@ func ValidateNodeUpdate(node, oldNode *core.Node) 
> field.ErrorList {
> +     }
> + 
> +     // Allow controller manager updating provider ID when not set
> +-    if len(oldNode.Spec.ProviderID) == 0 {
> +-            oldNode.Spec.ProviderID = node.Spec.ProviderID
> +-    } else {
> +-            if oldNode.Spec.ProviderID != node.Spec.ProviderID {
> +-                    allErrs = append(allErrs, 
> field.Forbidden(field.NewPath("spec", "providerID"), "node updates may not 
> change providerID except from \"\" to valid"))
> +-            }
> ++    if len(oldNode.Spec.ProviderID) > 0 && oldNode.Spec.ProviderID != 
> node.Spec.ProviderID {
> ++            allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", 
> "providerID"), "node updates may not change providerID except from \"\" to 
> valid"))
> +     }
> + 
> +     if node.Spec.ConfigSource != nil {
> +             allErrs = append(allErrs, 
> validateNodeConfigSourceSpec(node.Spec.ConfigSource, field.NewPath("spec", 
> "configSource"))...)
> +     }
> +-    oldNode.Spec.ConfigSource = node.Spec.ConfigSource
> +     if node.Status.Config != nil {
> +             allErrs = append(allErrs, 
> validateNodeConfigStatus(node.Status.Config, field.NewPath("status", 
> "config"))...)
> +     }
> +-    oldNode.Status.Config = node.Status.Config
> +-
> +-    // TODO: move reset function to its own location
> +-    // Ignore metadata changes now that they have been tested
> +-    oldNode.ObjectMeta = node.ObjectMeta
> +-    // Allow users to update capacity
> +-    oldNode.Status.Capacity = node.Status.Capacity
> +-    // Allow users to unschedule node
> +-    oldNode.Spec.Unschedulable = node.Spec.Unschedulable
> +-    // Clear status
> +-    oldNode.Status = node.Status
> + 
> +     // update taints
> +     if len(node.Spec.Taints) > 0 {
> +             allErrs = append(allErrs, validateNodeTaints(node.Spec.Taints, 
> fldPath.Child("taints"))...)
> +     }
> +-    oldNode.Spec.Taints = node.Spec.Taints
> + 
> +-    // We made allowed changes to oldNode, and now we compare oldNode to 
> node. Any remaining differences indicate changes to protected fields.
> +-    // TODO: Add a 'real' error type for this error and provide print 
> actual diffs.
> +-    if !apiequality.Semantic.DeepEqual(oldNode, node) {
> +-            klog.V(4).Infof("Update failed validation %#v vs %#v", oldNode, 
> node)
> +-            allErrs = append(allErrs, field.Forbidden(field.NewPath(""), 
> "node updates may only change labels, taints, or capacity (or configSource, 
> if the DynamicKubeletConfig feature gate is enabled)"))
> ++    if node.Spec.DoNotUseExternalID != oldNode.Spec.DoNotUseExternalID {
> ++            allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", 
> "externalID"), "may not be updated"))
> +     }
> + 
> ++    // status and metadata are allowed change (barring restrictions above), 
> so separately test spec field.
> ++    // spec only has a few fields, so check the ones we don't allow changing
> ++    //  1. PodCIDRs - immutable after first set - checked above
> ++    //  2. ProviderID - immutable after first set - checked above
> ++    //  3. Unschedulable - allowed to change
> ++    //  4. Taints - allowed to change
> ++    //  5. ConfigSource - allowed to change (and checked above)
> ++    //  6. DoNotUseExternalID - immutable - checked above
> ++
> +     return allErrs
> + }
> + 
> +-- 
> +2.25.1
> +
> +
> +From 0ef8605f4535713f17ede4bcf162ad513cbf6900 Mon Sep 17 00:00:00 2001
> +From: David Eads <[email protected]>
> +Date: Mon, 15 Feb 2021 16:21:42 -0500
> +Subject: [PATCH 2/8] remove unnecessary mutations in validation
> +
> +These mutations are already done in the strategy
> +---
> + pkg/apis/core/validation/validation.go | 22 ++--------------------
> + 1 file changed, 2 insertions(+), 20 deletions(-)
> +
> +diff --git a/pkg/apis/core/validation/validation.go 
> b/pkg/apis/core/validation/validation.go
> +index 89e5b5811c4..3381f2a37c2 100644
> +--- a/src/import/pkg/apis/core/validation/validation.go
> ++++ b/src/import/pkg/apis/core/validation/validation.go
> +@@ -1874,13 +1874,11 @@ func ValidatePersistentVolumeUpdate(newPv, oldPv 
> *core.PersistentVolume) field.E
> + }
> + 
> + // ValidatePersistentVolumeStatusUpdate tests to see if the status update 
> is legal for an end user to make.
> +-// newPv is updated with fields that cannot be changed.
> + func ValidatePersistentVolumeStatusUpdate(newPv, oldPv 
> *core.PersistentVolume) field.ErrorList {
> +     allErrs := ValidateObjectMetaUpdate(&newPv.ObjectMeta, 
> &oldPv.ObjectMeta, field.NewPath("metadata"))
> +     if len(newPv.ResourceVersion) == 0 {
> +             allErrs = append(allErrs, 
> field.Required(field.NewPath("resourceVersion"), ""))
> +     }
> +-    newPv.Spec = oldPv.Spec
> +     return allErrs
> + }
> + 
> +@@ -2026,7 +2024,6 @@ func ValidatePersistentVolumeClaimStatusUpdate(newPvc, 
> oldPvc *core.PersistentVo
> +     for r, qty := range newPvc.Status.Capacity {
> +             allErrs = append(allErrs, validateBasicResource(qty, 
> capPath.Key(string(r)))...)
> +     }
> +-    newPvc.Spec = oldPvc.Spec
> +     return allErrs
> + }
> + 
> +@@ -3795,8 +3792,7 @@ func ValidateContainerStateTransition(newStatuses, 
> oldStatuses []core.ContainerS
> +     return allErrs
> + }
> + 
> +-// ValidatePodStatusUpdate tests to see if the update is legal for an end 
> user to make. newPod is updated with fields
> +-// that cannot be changed.
> ++// ValidatePodStatusUpdate tests to see if the update is legal for an end 
> user to make.
> + func ValidatePodStatusUpdate(newPod, oldPod *core.Pod) field.ErrorList {
> +     fldPath := field.NewPath("metadata")
> +     allErrs := ValidateObjectMetaUpdate(&newPod.ObjectMeta, 
> &oldPod.ObjectMeta, fldPath)
> +@@ -3819,9 +3815,6 @@ func ValidatePodStatusUpdate(newPod, oldPod *core.Pod) 
> field.ErrorList {
> +     allErrs = append(allErrs, 
> ValidateContainerStateTransition(newPod.Status.ContainerStatuses, 
> oldPod.Status.ContainerStatuses, fldPath.Child("containerStatuses"), 
> oldPod.Spec.RestartPolicy)...)
> +     allErrs = append(allErrs, 
> ValidateContainerStateTransition(newPod.Status.InitContainerStatuses, 
> oldPod.Status.InitContainerStatuses, fldPath.Child("initContainerStatuses"), 
> oldPod.Spec.RestartPolicy)...)
> + 
> +-    // For status update we ignore changes to pod spec.
> +-    newPod.Spec = oldPod.Spec
> +-
> +     return allErrs
> + }
> + 
> +@@ -5287,7 +5280,6 @@ func ValidateResourceQuantityValue(resource string, 
> value resource.Quantity, fld
> + }
> + 
> + // ValidateResourceQuotaUpdate tests to see if the update is legal for an 
> end user to make.
> +-// newResourceQuota is updated with fields that cannot be changed.
> + func ValidateResourceQuotaUpdate(newResourceQuota, oldResourceQuota 
> *core.ResourceQuota) field.ErrorList {
> +     allErrs := ValidateObjectMetaUpdate(&newResourceQuota.ObjectMeta, 
> &oldResourceQuota.ObjectMeta, field.NewPath("metadata"))
> +     allErrs = append(allErrs, 
> ValidateResourceQuotaSpec(&newResourceQuota.Spec, field.NewPath("spec"))...)
> +@@ -5306,12 +5298,10 @@ func ValidateResourceQuotaUpdate(newResourceQuota, 
> oldResourceQuota *core.Resour
> +             allErrs = append(allErrs, field.Invalid(fldPath, 
> newResourceQuota.Spec.Scopes, fieldImmutableErrorMsg))
> +     }
> + 
> +-    newResourceQuota.Status = oldResourceQuota.Status
> +     return allErrs
> + }
> + 
> + // ValidateResourceQuotaStatusUpdate tests to see if the status update is 
> legal for an end user to make.
> +-// newResourceQuota is updated with fields that cannot be changed.
> + func ValidateResourceQuotaStatusUpdate(newResourceQuota, oldResourceQuota 
> *core.ResourceQuota) field.ErrorList {
> +     allErrs := ValidateObjectMetaUpdate(&newResourceQuota.ObjectMeta, 
> &oldResourceQuota.ObjectMeta, field.NewPath("metadata"))
> +     if len(newResourceQuota.ResourceVersion) == 0 {
> +@@ -5329,7 +5319,6 @@ func 
> ValidateResourceQuotaStatusUpdate(newResourceQuota, oldResourceQuota *core.
> +             allErrs = append(allErrs, 
> ValidateResourceQuotaResourceName(string(k), resPath)...)
> +             allErrs = append(allErrs, 
> ValidateResourceQuantityValue(string(k), v, resPath)...)
> +     }
> +-    newResourceQuota.Spec = oldResourceQuota.Spec
> +     return allErrs
> + }
> + 
> +@@ -5362,19 +5351,14 @@ func validateKubeFinalizerName(stringValue string, 
> fldPath *field.Path) field.Er
> + }
> + 
> + // ValidateNamespaceUpdate tests to make sure a namespace update can be 
> applied.
> +-// newNamespace is updated with fields that cannot be changed
> + func ValidateNamespaceUpdate(newNamespace *core.Namespace, oldNamespace 
> *core.Namespace) field.ErrorList {
> +     allErrs := ValidateObjectMetaUpdate(&newNamespace.ObjectMeta, 
> &oldNamespace.ObjectMeta, field.NewPath("metadata"))
> +-    newNamespace.Spec.Finalizers = oldNamespace.Spec.Finalizers
> +-    newNamespace.Status = oldNamespace.Status
> +     return allErrs
> + }
> + 
> +-// ValidateNamespaceStatusUpdate tests to see if the update is legal for an 
> end user to make. newNamespace is updated with fields
> +-// that cannot be changed.
> ++// ValidateNamespaceStatusUpdate tests to see if the update is legal for an 
> end user to make.
> + func ValidateNamespaceStatusUpdate(newNamespace, oldNamespace 
> *core.Namespace) field.ErrorList {
> +     allErrs := ValidateObjectMetaUpdate(&newNamespace.ObjectMeta, 
> &oldNamespace.ObjectMeta, field.NewPath("metadata"))
> +-    newNamespace.Spec = oldNamespace.Spec
> +     if newNamespace.DeletionTimestamp.IsZero() {
> +             if newNamespace.Status.Phase != core.NamespaceActive {
> +                     allErrs = append(allErrs, 
> field.Invalid(field.NewPath("status", "Phase"), newNamespace.Status.Phase, 
> "may only be 'Active' if `deletionTimestamp` is empty"))
> +@@ -5388,7 +5372,6 @@ func ValidateNamespaceStatusUpdate(newNamespace, 
> oldNamespace *core.Namespace) f
> + }
> + 
> + // ValidateNamespaceFinalizeUpdate tests to see if the update is legal for 
> an end user to make.
> +-// newNamespace is updated with fields that cannot be changed.
> + func ValidateNamespaceFinalizeUpdate(newNamespace, oldNamespace 
> *core.Namespace) field.ErrorList {
> +     allErrs := ValidateObjectMetaUpdate(&newNamespace.ObjectMeta, 
> &oldNamespace.ObjectMeta, field.NewPath("metadata"))
> + 
> +@@ -5397,7 +5380,6 @@ func ValidateNamespaceFinalizeUpdate(newNamespace, 
> oldNamespace *core.Namespace)
> +             idxPath := fldPath.Index(i)
> +             allErrs = append(allErrs, 
> validateFinalizerName(string(newNamespace.Spec.Finalizers[i]), idxPath)...)
> +     }
> +-    newNamespace.Status = oldNamespace.Status
> +     return allErrs
> + }
> + 
> +-- 
> +2.25.1
> +
> +
> +From 198ac41f97e11140b634274e34f0102e33806145 Mon Sep 17 00:00:00 2001
> +From: David Eads <[email protected]>
> +Date: Mon, 15 Feb 2021 16:55:41 -0500
> +Subject: [PATCH 3/8] move secret mutation from validation to prepareforupdate
> +
> +---
> + pkg/apis/core/validation/validation.go | 4 ----
> + pkg/registry/core/secret/strategy.go   | 6 ++++++
> + 2 files changed, 6 insertions(+), 4 deletions(-)
> +
> +diff --git a/pkg/apis/core/validation/validation.go 
> b/pkg/apis/core/validation/validation.go
> +index 3381f2a37c2..9775b268e90 100644
> +--- a/src/import/pkg/apis/core/validation/validation.go
> ++++ b/src/import/pkg/apis/core/validation/validation.go
> +@@ -4977,10 +4977,6 @@ func ValidateSecret(secret *core.Secret) 
> field.ErrorList {
> + func ValidateSecretUpdate(newSecret, oldSecret *core.Secret) 
> field.ErrorList {
> +     allErrs := ValidateObjectMetaUpdate(&newSecret.ObjectMeta, 
> &oldSecret.ObjectMeta, field.NewPath("metadata"))
> + 
> +-    if len(newSecret.Type) == 0 {
> +-            newSecret.Type = oldSecret.Type
> +-    }
> +-
> +     allErrs = append(allErrs, ValidateImmutableField(newSecret.Type, 
> oldSecret.Type, field.NewPath("type"))...)
> +     if oldSecret.Immutable != nil && *oldSecret.Immutable {
> +             if !reflect.DeepEqual(newSecret.Immutable, oldSecret.Immutable) 
> {
> +diff --git a/pkg/registry/core/secret/strategy.go 
> b/pkg/registry/core/secret/strategy.go
> +index 0d5908d8975..aad00387ac1 100644
> +--- a/src/import/pkg/registry/core/secret/strategy.go
> ++++ b/src/import/pkg/registry/core/secret/strategy.go
> +@@ -73,6 +73,12 @@ func (strategy) AllowCreateOnUpdate() bool {
> + func (strategy) PrepareForUpdate(ctx context.Context, obj, old 
> runtime.Object) {
> +     newSecret := obj.(*api.Secret)
> +     oldSecret := old.(*api.Secret)
> ++
> ++    // this is weird, but consistent with what the validatedUpdate function 
> used to do.
> ++    if len(newSecret.Type) == 0 {
> ++            newSecret.Type = oldSecret.Type
> ++    }
> ++
> +     dropDisabledFields(newSecret, oldSecret)
> + }
> + 
> +-- 
> +2.25.1
> +
> +
> +From 7973d58ea8fe93c2be920a766c7c5d6a4a2529e6 Mon Sep 17 00:00:00 2001
> +From: David Eads <[email protected]>
> +Date: Mon, 15 Feb 2021 17:18:11 -0500
> +Subject: [PATCH 4/8] add markers for inspected validation mutation hits
> +
> +---
> + pkg/apis/core/validation/validation.go                 | 10 +++++-----
> + .../pkg/apis/apiextensions/validation/validation.go    |  2 +-
> + 2 files changed, 6 insertions(+), 6 deletions(-)
> +
> +diff --git a/pkg/apis/core/validation/validation.go 
> b/pkg/apis/core/validation/validation.go
> +index 9775b268e90..6f634db468e 100644
> +--- a/src/import/pkg/apis/core/validation/validation.go
> ++++ b/src/import/pkg/apis/core/validation/validation.go
> +@@ -1953,7 +1953,7 @@ func ValidatePersistentVolumeClaimUpdate(newPvc, 
> oldPvc *core.PersistentVolumeCl
> +     // Claims are immutable in order to enforce quota, range limits, etc. 
> without gaming the system.
> +     if len(oldPvc.Spec.VolumeName) == 0 {
> +             // volumeName changes are allowed once.
> +-            oldPvcClone.Spec.VolumeName = newPvcClone.Spec.VolumeName
> ++            oldPvcClone.Spec.VolumeName = newPvcClone.Spec.VolumeName // 
> +k8s:verify-mutation:reason=clone
> +     }
> + 
> +     if validateStorageClassUpgrade(oldPvcClone.Annotations, 
> newPvcClone.Annotations,
> +@@ -1969,7 +1969,7 @@ func ValidatePersistentVolumeClaimUpdate(newPvc, 
> oldPvc *core.PersistentVolumeCl
> +     if 
> utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes) {
> +             // lets make sure storage values are same.
> +             if newPvc.Status.Phase == core.ClaimBound && 
> newPvcClone.Spec.Resources.Requests != nil {
> +-                    newPvcClone.Spec.Resources.Requests["storage"] = 
> oldPvc.Spec.Resources.Requests["storage"]
> ++                    newPvcClone.Spec.Resources.Requests["storage"] = 
> oldPvc.Spec.Resources.Requests["storage"] // +k8s:verify-mutation:reason=clone
> +             }
> + 
> +             oldSize := oldPvc.Spec.Resources.Requests["storage"]
> +@@ -2317,13 +2317,13 @@ func GetVolumeMountMap(mounts []core.VolumeMount) 
> map[string]string {
> + }
> + 
> + func GetVolumeDeviceMap(devices []core.VolumeDevice) map[string]string {
> +-    voldevices := make(map[string]string)
> ++    volDevices := make(map[string]string)
> + 
> +     for _, dev := range devices {
> +-            voldevices[dev.Name] = dev.DevicePath
> ++            volDevices[dev.Name] = dev.DevicePath
> +     }
> + 
> +-    return voldevices
> ++    return volDevices
> + }
> + 
> + func ValidateVolumeMounts(mounts []core.VolumeMount, voldevices 
> map[string]string, volumes map[string]core.VolumeSource, container 
> *core.Container, fldPath *field.Path) field.ErrorList {
> +diff --git 
> a/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go
>  
> b/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go
> +index f570dd82a4b..2bc72643c85 100644
> +--- 
> a/src/import/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go
> ++++ 
> b/src/import/staging/src/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/validation/validation.go
> +@@ -1304,7 +1304,7 @@ func validateAPIApproval(newCRD, oldCRD 
> *apiextensions.CustomResourceDefinition,
> +     var oldApprovalState *apihelpers.APIApprovalState
> +     if oldCRD != nil {
> +             t, _ := apihelpers.GetAPIApprovalState(oldCRD.Annotations)
> +-            oldApprovalState = &t
> ++            oldApprovalState = &t // +k8s:verify-mutation:reason=clone
> +     }
> +     newApprovalState, reason := 
> apihelpers.GetAPIApprovalState(newCRD.Annotations)
> + 
> +-- 
> +2.25.1
> +
> +
> +From 0b8dcbecdc093829aaccee7bf541ef8cae7f3848 Mon Sep 17 00:00:00 2001
> +From: David Eads <[email protected]>
> +Date: Mon, 15 Feb 2021 17:33:34 -0500
> +Subject: [PATCH 5/8] remove pod toleration toleration seconds mutation
> +
> +---
> + pkg/apis/core/validation/validation.go | 16 ++++++++--------
> + 1 file changed, 8 insertions(+), 8 deletions(-)
> +
> +diff --git a/pkg/apis/core/validation/validation.go 
> b/pkg/apis/core/validation/validation.go
> +index 6f634db468e..4226047775b 100644
> +--- a/src/import/pkg/apis/core/validation/validation.go
> ++++ b/src/import/pkg/apis/core/validation/validation.go
> +@@ -2967,10 +2967,11 @@ func validateOnlyAddedTolerations(newTolerations 
> []core.Toleration, oldToleratio
> +     allErrs := field.ErrorList{}
> +     for _, old := range oldTolerations {
> +             found := false
> +-            old.TolerationSeconds = nil
> +-            for _, new := range newTolerations {
> +-                    new.TolerationSeconds = nil
> +-                    if reflect.DeepEqual(old, new) {
> ++            oldTolerationClone := old.DeepCopy()
> ++            for _, newToleration := range newTolerations {
> ++                    // assign to our clone before doing a deep equal so we 
> can allow tolerationseconds to change.
> ++                    oldTolerationClone.TolerationSeconds = 
> newToleration.TolerationSeconds // +k8s:verify-mutation:reason=clone
> ++                    if reflect.DeepEqual(*oldTolerationClone, 
> newToleration) {
> +                             found = true
> +                             break
> +                     }
> +@@ -3730,6 +3731,9 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod) 
> field.ErrorList {
> +             allErrs = append(allErrs, 
> field.Invalid(specPath.Child("activeDeadlineSeconds"), 
> newPod.Spec.ActiveDeadlineSeconds, "must not update from a positive integer 
> to nil value"))
> +     }
> + 
> ++    // Allow only additions to tolerations updates.
> ++    allErrs = append(allErrs, 
> validateOnlyAddedTolerations(newPod.Spec.Tolerations, 
> oldPod.Spec.Tolerations, specPath.Child("tolerations"))...)
> ++
> +     // handle updateable fields by munging those fields prior to deep equal 
> comparison.
> +     mungedPod := *newPod
> +     // munge spec.containers[*].image
> +@@ -3753,10 +3757,6 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod) 
> field.ErrorList {
> +             mungedPod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds
> +     }
> + 
> +-    // Allow only additions to tolerations updates.
> +-    mungedPod.Spec.Tolerations = oldPod.Spec.Tolerations
> +-    allErrs = append(allErrs, 
> validateOnlyAddedTolerations(newPod.Spec.Tolerations, 
> oldPod.Spec.Tolerations, specPath.Child("tolerations"))...)
> +-
> +     if !apiequality.Semantic.DeepEqual(mungedPod.Spec, oldPod.Spec) {
> +             // This diff isn't perfect, but it's a helluva lot better an 
> "I'm not going to tell you what the difference is".
> +             //TODO: Pinpoint the specific field that causes the invalid 
> error after we have strategic merge diff
> +-- 
> +2.25.1
> +
> +
> +From db5696ebe654a487c0216bd0646ffb9872bac39a Mon Sep 17 00:00:00 2001
> +From: David Eads <[email protected]>
> +Date: Mon, 15 Feb 2021 17:43:57 -0500
> +Subject: [PATCH 6/8] full deepcopy on munged pod spec
> +
> +---
> + pkg/apis/core/validation/validation.go | 30 ++++++++++++++++----------
> + 1 file changed, 19 insertions(+), 11 deletions(-)
> +
> +diff --git a/pkg/apis/core/validation/validation.go 
> b/pkg/apis/core/validation/validation.go
> +index 4226047775b..d6eb9fe56f4 100644
> +--- a/src/import/pkg/apis/core/validation/validation.go
> ++++ b/src/import/pkg/apis/core/validation/validation.go
> +@@ -3734,33 +3734,41 @@ func ValidatePodUpdate(newPod, oldPod *core.Pod) 
> field.ErrorList {
> +     // Allow only additions to tolerations updates.
> +     allErrs = append(allErrs, 
> validateOnlyAddedTolerations(newPod.Spec.Tolerations, 
> oldPod.Spec.Tolerations, specPath.Child("tolerations"))...)
> + 
> ++    // the last thing to check is pod spec equality.  If the pod specs are 
> equal, then we can simply return the errors we have
> ++    // so far and save the cost of a deep copy.
> ++    if apiequality.Semantic.DeepEqual(newPod.Spec, oldPod.Spec) {
> ++            return allErrs
> ++    }
> ++
> +     // handle updateable fields by munging those fields prior to deep equal 
> comparison.
> +-    mungedPod := *newPod
> ++    mungedPodSpec := *newPod.Spec.DeepCopy()
> +     // munge spec.containers[*].image
> +     var newContainers []core.Container
> +-    for ix, container := range mungedPod.Spec.Containers {
> +-            container.Image = oldPod.Spec.Containers[ix].Image
> ++    for ix, container := range mungedPodSpec.Containers {
> ++            container.Image = oldPod.Spec.Containers[ix].Image // 
> +k8s:verify-mutation:reason=clone
> +             newContainers = append(newContainers, container)
> +     }
> +-    mungedPod.Spec.Containers = newContainers
> ++    mungedPodSpec.Containers = newContainers
> +     // munge spec.initContainers[*].image
> +     var newInitContainers []core.Container
> +-    for ix, container := range mungedPod.Spec.InitContainers {
> +-            container.Image = oldPod.Spec.InitContainers[ix].Image
> ++    for ix, container := range mungedPodSpec.InitContainers {
> ++            container.Image = oldPod.Spec.InitContainers[ix].Image // 
> +k8s:verify-mutation:reason=clone
> +             newInitContainers = append(newInitContainers, container)
> +     }
> +-    mungedPod.Spec.InitContainers = newInitContainers
> ++    mungedPodSpec.InitContainers = newInitContainers
> +     // munge spec.activeDeadlineSeconds
> +-    mungedPod.Spec.ActiveDeadlineSeconds = nil
> ++    mungedPodSpec.ActiveDeadlineSeconds = nil
> +     if oldPod.Spec.ActiveDeadlineSeconds != nil {
> +             activeDeadlineSeconds := *oldPod.Spec.ActiveDeadlineSeconds
> +-            mungedPod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds
> ++            mungedPodSpec.ActiveDeadlineSeconds = &activeDeadlineSeconds
> +     }
> ++    // tolerations are checked before the deep copy, so munge those too
> ++    mungedPodSpec.Tolerations = oldPod.Spec.Tolerations // 
> +k8s:verify-mutation:reason=clone
> + 
> +-    if !apiequality.Semantic.DeepEqual(mungedPod.Spec, oldPod.Spec) {
> ++    if !apiequality.Semantic.DeepEqual(mungedPodSpec, oldPod.Spec) {
> +             // This diff isn't perfect, but it's a helluva lot better an 
> "I'm not going to tell you what the difference is".
> +             //TODO: Pinpoint the specific field that causes the invalid 
> error after we have strategic merge diff
> +-            specDiff := diff.ObjectDiff(mungedPod.Spec, oldPod.Spec)
> ++            specDiff := diff.ObjectDiff(mungedPodSpec, oldPod.Spec)
> +             allErrs = append(allErrs, field.Forbidden(specPath, 
> fmt.Sprintf("pod updates may not change fields other than 
> `spec.containers[*].image`, `spec.initContainers[*].image`, 
> `spec.activeDeadlineSeconds` or `spec.tolerations` (only additions to 
> existing tolerations)\n%v", specDiff)))
> +     }
> + 
> +-- 
> +2.25.1
> +
> +
> +From 888666d4d5b96328f7e9d96c0946e9d7c8222f81 Mon Sep 17 00:00:00 2001
> +From: David Eads <[email protected]>
> +Date: Wed, 17 Feb 2021 10:51:38 -0500
> +Subject: [PATCH 7/8] deepcopy statefulsets
> +
> +---
> + pkg/apis/apps/validation/validation.go | 20 +++++++-------------
> + 1 file changed, 7 insertions(+), 13 deletions(-)
> +
> +diff --git a/pkg/apis/apps/validation/validation.go 
> b/pkg/apis/apps/validation/validation.go
> +index 6ac73cb6b7e..03e0d2024dd 100644
> +--- a/src/import/pkg/apis/apps/validation/validation.go
> ++++ b/src/import/pkg/apis/apps/validation/validation.go
> +@@ -144,21 +144,15 @@ func ValidateStatefulSet(statefulSet 
> *apps.StatefulSet) field.ErrorList {
> + func ValidateStatefulSetUpdate(statefulSet, oldStatefulSet 
> *apps.StatefulSet) field.ErrorList {
> +     allErrs := 
> apivalidation.ValidateObjectMetaUpdate(&statefulSet.ObjectMeta, 
> &oldStatefulSet.ObjectMeta, field.NewPath("metadata"))
> + 
> +-    restoreReplicas := statefulSet.Spec.Replicas
> +-    statefulSet.Spec.Replicas = oldStatefulSet.Spec.Replicas
> +-
> +-    restoreTemplate := statefulSet.Spec.Template
> +-    statefulSet.Spec.Template = oldStatefulSet.Spec.Template
> +-
> +-    restoreStrategy := statefulSet.Spec.UpdateStrategy
> +-    statefulSet.Spec.UpdateStrategy = oldStatefulSet.Spec.UpdateStrategy
> +-
> +-    if !apiequality.Semantic.DeepEqual(statefulSet.Spec, 
> oldStatefulSet.Spec) {
> ++    // statefulset updates aren't super common and general updates are 
> likely to be touching spec, so we'll do this
> ++    // deep copy right away.  This avoids mutating our inputs
> ++    newStatefulSetClone := statefulSet.DeepCopy()
> ++    newStatefulSetClone.Spec.Replicas = oldStatefulSet.Spec.Replicas        
>      // +k8s:verify-mutation:reason=clone
> ++    newStatefulSetClone.Spec.Template = oldStatefulSet.Spec.Template        
>      // +k8s:verify-mutation:reason=clone
> ++    newStatefulSetClone.Spec.UpdateStrategy = 
> oldStatefulSet.Spec.UpdateStrategy // +k8s:verify-mutation:reason=clone
> ++    if !apiequality.Semantic.DeepEqual(newStatefulSetClone.Spec, 
> oldStatefulSet.Spec) {
> +             allErrs = append(allErrs, 
> field.Forbidden(field.NewPath("spec"), "updates to statefulset spec for 
> fields other than 'replicas', 'template', and 'updateStrategy' are 
> forbidden"))
> +     }
> +-    statefulSet.Spec.Replicas = restoreReplicas
> +-    statefulSet.Spec.Template = restoreTemplate
> +-    statefulSet.Spec.UpdateStrategy = restoreStrategy
> + 
> +     allErrs = append(allErrs, 
> apivalidation.ValidateNonnegativeField(int64(statefulSet.Spec.Replicas), 
> field.NewPath("spec", "replicas"))...)
> +     return allErrs
> +-- 
> +2.25.1
> +
> +
> +From bfbe634654ae1ac86033b69703ed78ade5d605ea Mon Sep 17 00:00:00 2001
> +From: David Eads <[email protected]>
> +Date: Wed, 17 Mar 2021 09:12:42 -0400
> +Subject: [PATCH 8/8] bazel
> +
> +---
> + pkg/apis/core/validation/BUILD | 1 -
> + 1 file changed, 1 deletion(-)
> +
> +diff --git a/pkg/apis/core/validation/BUILD b/pkg/apis/core/validation/BUILD
> +index 2db631180e6..00649a3a52c 100644
> +--- a/src/import/pkg/apis/core/validation/BUILD
> ++++ b/src/import/pkg/apis/core/validation/BUILD
> +@@ -40,7 +40,6 @@ go_library(
> +         
> "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
> +         
> "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
> +         
> "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
> +-        "//vendor/k8s.io/klog:go_default_library",
> +         "//vendor/k8s.io/utils/net:go_default_library",
> +     ],
> + )
> +-- 
> +2.25.1
> +
> diff --git a/recipes-containers/kubernetes/kubernetes/CVE-2021-25737.patch 
> b/recipes-containers/kubernetes/kubernetes/CVE-2021-25737.patch
> new file mode 100644
> index 00000000..d1a97971
> --- /dev/null
> +++ b/recipes-containers/kubernetes/kubernetes/CVE-2021-25737.patch
> @@ -0,0 +1,128 @@
> +From 901e8e07e1f031456ecd7fefce965aaa05916825 Mon Sep 17 00:00:00 2001
> +From: Rob Scott <[email protected]>
> +Date: Fri, 9 Apr 2021 15:24:17 -0700
> +Subject: [PATCH] Updating EndpointSlice validation to match Endpoints
> + validation
> +
> +Upstream-Status: Backport 
> [https://github.com/kubernetes/kubernetes/commit/901e8e07e1f031456ecd7fefce965aaa05916825]
> +CVE: CVE-2021-25737
> +Signed-off-by: Vijay Anusuri <[email protected]>
> +---
> + pkg/apis/core/validation/validation.go        | 18 ++++++----
> + pkg/apis/discovery/validation/validation.go   |  2 ++
> + .../discovery/validation/validation_test.go   | 34 +++++++++++++++++--
> + 3 files changed, 45 insertions(+), 9 deletions(-)
> +
> +diff --git a/pkg/apis/core/validation/validation.go 
> b/pkg/apis/core/validation/validation.go
> +index 3daeb139d590d..c65cdd40f9061 100644
> +--- a/src/import/pkg/apis/core/validation/validation.go
> ++++ b/src/import/pkg/apis/core/validation/validation.go
> +@@ -4014,7 +4014,7 @@ func ValidateService(service *core.Service, 
> allowAppProtocol bool) field.ErrorLi
> +                             allErrs = append(allErrs, 
> field.Invalid(idxPath, ip, msgs[i]))
> +                     }
> +             } else {
> +-                    allErrs = append(allErrs, validateNonSpecialIP(ip, 
> idxPath)...)
> ++                    allErrs = append(allErrs, ValidateNonSpecialIP(ip, 
> idxPath)...)
> +             }
> +     }
> + 
> +@@ -5572,15 +5572,19 @@ func validateEndpointAddress(address 
> *core.EndpointAddress, fldPath *field.Path)
> +                     allErrs = append(allErrs, 
> field.Invalid(fldPath.Child("nodeName"), *address.NodeName, msg))
> +             }
> +     }
> +-    allErrs = append(allErrs, validateNonSpecialIP(address.IP, 
> fldPath.Child("ip"))...)
> ++    allErrs = append(allErrs, ValidateNonSpecialIP(address.IP, 
> fldPath.Child("ip"))...)
> +     return allErrs
> + }
> + 
> +-func validateNonSpecialIP(ipAddress string, fldPath *field.Path) 
> field.ErrorList {
> +-    // We disallow some IPs as endpoints or external-ips.  Specifically,
> +-    // unspecified and loopback addresses are nonsensical and link-local
> +-    // addresses tend to be used for node-centric purposes (e.g. metadata
> +-    // service).
> ++// ValidateNonSpecialIP is used to validate Endpoints, EndpointSlices, and
> ++// external IPs. Specifically, this disallows unspecified and loopback 
> addresses
> ++// are nonsensical and link-local addresses tend to be used for node-centric
> ++// purposes (e.g. metadata service).
> ++//
> ++// IPv6 references
> ++// - 
> https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
> ++// - 
> https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml
> ++func ValidateNonSpecialIP(ipAddress string, fldPath *field.Path) 
> field.ErrorList {
> +     allErrs := field.ErrorList{}
> +     ip := net.ParseIP(ipAddress)
> +     if ip == nil {
> +diff --git a/pkg/apis/discovery/validation/validation.go 
> b/pkg/apis/discovery/validation/validation.go
> +index 810f2ca124d57..3aa5128359d7f 100644
> +--- a/src/import/pkg/apis/discovery/validation/validation.go
> ++++ b/src/import/pkg/apis/discovery/validation/validation.go
> +@@ -103,8 +103,10 @@ func validateEndpoints(endpoints []discovery.Endpoint, 
> addrType discovery.Addres
> +                             }
> +                     case discovery.AddressTypeIPv4:
> +                             allErrs = append(allErrs, 
> validation.IsValidIPv4Address(addressPath.Index(i), address)...)
> ++                            allErrs = append(allErrs, 
> apivalidation.ValidateNonSpecialIP(address, addressPath.Index(i))...)
> +                     case discovery.AddressTypeIPv6:
> +                             allErrs = append(allErrs, 
> validation.IsValidIPv6Address(addressPath.Index(i), address)...)
> ++                            allErrs = append(allErrs, 
> apivalidation.ValidateNonSpecialIP(address, addressPath.Index(i))...)
> +                     case discovery.AddressTypeFQDN:
> +                             allErrs = append(allErrs, 
> validation.IsFullyQualifiedDomainName(addressPath.Index(i), address)...)
> +                     }
> +diff --git a/pkg/apis/discovery/validation/validation_test.go 
> b/pkg/apis/discovery/validation/validation_test.go
> +index 060545f93ab31..3c8a5465128a9 100644
> +--- a/src/import/pkg/apis/discovery/validation/validation_test.go
> ++++ b/src/import/pkg/apis/discovery/validation/validation_test.go
> +@@ -390,7 +390,7 @@ func TestValidateEndpointSlice(t *testing.T) {
> +                     },
> +             },
> +             "bad-ipv4": {
> +-                    expectedErrors: 2,
> ++                    expectedErrors: 3,
> +                     endpointSlice: &discovery.EndpointSlice{
> +                             ObjectMeta:  standardMeta,
> +                             AddressType: discovery.AddressTypeIPv4,
> +@@ -405,7 +405,7 @@ func TestValidateEndpointSlice(t *testing.T) {
> +                     },
> +             },
> +             "bad-ipv6": {
> +-                    expectedErrors: 2,
> ++                    expectedErrors: 4,
> +                     endpointSlice: &discovery.EndpointSlice{
> +                             ObjectMeta:  standardMeta,
> +                             AddressType: discovery.AddressTypeIPv6,
> +@@ -454,6 +454,36 @@ func TestValidateEndpointSlice(t *testing.T) {
> +                     expectedErrors: 3,
> +                     endpointSlice:  &discovery.EndpointSlice{},
> +             },
> ++            "special-ipv4": {
> ++                    expectedErrors: 1,
> ++                    endpointSlice: &discovery.EndpointSlice{
> ++                            ObjectMeta:  standardMeta,
> ++                            AddressType: discovery.AddressTypeIPv4,
> ++                            Ports: []discovery.EndpointPort{{
> ++                                    Name:     utilpointer.StringPtr("http"),
> ++                                    Protocol: protocolPtr(api.ProtocolTCP),
> ++                            }},
> ++                            Endpoints: []discovery.Endpoint{{
> ++                                    Addresses: []string{"127.0.0.1"},
> ++                                    Hostname:  
> utilpointer.StringPtr("valid-123"),
> ++                            }},
> ++                    },
> ++            },
> ++            "special-ipv6": {
> ++                    expectedErrors: 1,
> ++                    endpointSlice: &discovery.EndpointSlice{
> ++                            ObjectMeta:  standardMeta,
> ++                            AddressType: discovery.AddressTypeIPv6,
> ++                            Ports: []discovery.EndpointPort{{
> ++                                    Name:     utilpointer.StringPtr("http"),
> ++                                    Protocol: protocolPtr(api.ProtocolTCP),
> ++                            }},
> ++                            Endpoints: []discovery.Endpoint{{
> ++                                    Addresses: 
> []string{"fe80::9656:d028:8652:66b6"},
> ++                                    Hostname:  
> utilpointer.StringPtr("valid-123"),
> ++                            }},
> ++                    },
> ++            },
> +     }
> + 
> +     for name, testCase := range testCases {
> diff --git a/recipes-containers/kubernetes/kubernetes_git.bb 
> b/recipes-containers/kubernetes/kubernetes_git.bb
> index 2b0bfb7a..be3d7dbe 100644
> --- a/recipes-containers/kubernetes/kubernetes_git.bb
> +++ b/recipes-containers/kubernetes/kubernetes_git.bb
> @@ -14,6 +14,9 @@ SRC_URI = 
> "git://github.com/kubernetes/kubernetes.git;branch=release-1.17;name=k
>             file://CVE-2020-8564.patch \
>             file://CVE-2020-8565.patch \
>             file://CVE-2020-8566.patch \
> +           file://CVE-2021-25735-pre1.patch \
> +           file://CVE-2021-25735.patch \
> +           file://CVE-2021-25737.patch \
>            "
>  
>  DEPENDS += "rsync-native \
> -- 
> 2.25.1
> 

> 
> 
> 

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#8333): 
https://lists.yoctoproject.org/g/meta-virtualization/message/8333
Mute This Topic: https://lists.yoctoproject.org/mt/101614699/21656
Group Owner: [email protected]
Unsubscribe: 
https://lists.yoctoproject.org/g/meta-virtualization/leave/6693005/21656/1014668956/xyzzy
 [[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to