diff --git a/deploy/chart/templates/0000_50_olm_07-olm-operator.deployment.yaml b/deploy/chart/templates/0000_50_olm_07-olm-operator.deployment.yaml index f2c7bd8ab2..139f295195 100644 --- a/deploy/chart/templates/0000_50_olm_07-olm-operator.deployment.yaml +++ b/deploy/chart/templates/0000_50_olm_07-olm-operator.deployment.yaml @@ -22,9 +22,7 @@ spec: seccompProfile: type: RuntimeDefault serviceAccountName: olm-operator-serviceaccount - {{- if or .Values.olm.tlsSecret .Values.olm.clientCASecret }} volumes: - {{- end }} {{- if .Values.olm.tlsSecret }} - name: srv-cert secret: @@ -35,15 +33,16 @@ spec: secret: secretName: {{ .Values.olm.clientCASecret }} {{- end }} + - name: tmpfs + emptyDir: {} containers: - name: olm-operator securityContext: allowPrivilegeEscalation: false + readOnlyRootFilesystem: true capabilities: drop: [ "ALL" ] - {{- if or .Values.olm.tlsSecret .Values.olm.clientCASecret }} volumeMounts: - {{- end }} {{- if .Values.olm.tlsSecret }} - name: srv-cert mountPath: "/srv-cert" @@ -54,6 +53,8 @@ spec: mountPath: "/profile-collector-cert" readOnly: true {{- end }} + - name: tmpfs + mountPath: /tmp command: - /bin/olm args: diff --git a/deploy/chart/templates/0000_50_olm_08-catalog-operator.deployment.yaml b/deploy/chart/templates/0000_50_olm_08-catalog-operator.deployment.yaml index eea8046cea..7b27706a74 100644 --- a/deploy/chart/templates/0000_50_olm_08-catalog-operator.deployment.yaml +++ b/deploy/chart/templates/0000_50_olm_08-catalog-operator.deployment.yaml @@ -22,9 +22,7 @@ spec: seccompProfile: type: RuntimeDefault serviceAccountName: olm-operator-serviceaccount - {{- if or .Values.catalog.tlsSecret .Values.catalog.clientCASecret }} volumes: - {{- end }} {{- if .Values.catalog.tlsSecret }} - name: srv-cert secret: @@ -35,15 +33,16 @@ spec: secret: secretName: {{ .Values.catalog.clientCASecret }} {{- end }} + - name: tmpfs + emptyDir: {} containers: - name: catalog-operator securityContext: allowPrivilegeEscalation: false + readOnlyRootFilesystem: true capabilities: drop: [ "ALL" ] - {{- if or .Values.catalog.tlsSecret .Values.catalog.clientCASecret }} volumeMounts: - {{- end }} {{- if .Values.catalog.tlsSecret }} - name: srv-cert mountPath: "/srv-cert" @@ -54,6 +53,8 @@ spec: mountPath: "/profile-collector-cert" readOnly: true {{- end }} + - name: tmpfs + mountPath: /tmp command: - /bin/catalog args: diff --git a/deploy/chart/templates/_packageserver.deployment-spec.yaml b/deploy/chart/templates/_packageserver.deployment-spec.yaml index ebf710787c..d3c791df4a 100644 --- a/deploy/chart/templates/_packageserver.deployment-spec.yaml +++ b/deploy/chart/templates/_packageserver.deployment-spec.yaml @@ -31,6 +31,7 @@ spec: - name: packageserver securityContext: allowPrivilegeEscalation: false + readOnlyRootFilesystem: true capabilities: drop: [ "ALL" ] command: diff --git a/pkg/controller/bundle/bundle_unpacker.go b/pkg/controller/bundle/bundle_unpacker.go index 698119af6f..263e77c5b4 100644 --- a/pkg/controller/bundle/bundle_unpacker.go +++ b/pkg/controller/bundle/bundle_unpacker.go @@ -154,6 +154,7 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -180,6 +181,7 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -209,6 +211,7 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, diff --git a/pkg/controller/bundle/bundle_unpacker_test.go b/pkg/controller/bundle/bundle_unpacker_test.go index 312037bf2a..f9ec614d5c 100644 --- a/pkg/controller/bundle/bundle_unpacker_test.go +++ b/pkg/controller/bundle/bundle_unpacker_test.go @@ -308,6 +308,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -334,6 +335,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -363,6 +365,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -524,6 +527,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -550,6 +554,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -579,6 +584,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -780,6 +786,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -806,6 +813,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -835,6 +843,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -1031,6 +1040,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -1057,6 +1067,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -1086,6 +1097,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -1252,6 +1264,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -1278,6 +1291,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -1307,6 +1321,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -1486,6 +1501,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -1512,6 +1528,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -1541,6 +1558,7 @@ func TestConfigMapUnpacker(t *testing.T) { }, SecurityContext: &corev1.SecurityContext{ AllowPrivilegeEscalation: ptr.To(bool(false)), + ReadOnlyRootFilesystem: ptr.To(true), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, diff --git a/pkg/controller/operators/catalog/operator_test.go b/pkg/controller/operators/catalog/operator_test.go index 00a6e48d9a..5d17ec8b73 100644 --- a/pkg/controller/operators/catalog/operator_test.go +++ b/pkg/controller/operators/catalog/operator_test.go @@ -863,7 +863,7 @@ func TestSyncCatalogSourcesSecurityPolicy(t *testing.T) { RunAsUser: ptr.To(int64(1001)), }, pod.Spec.SecurityContext) require.Equal(t, &corev1.SecurityContext{ - ReadOnlyRootFilesystem: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), AllowPrivilegeEscalation: ptr.To(false), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, diff --git a/pkg/controller/registry/reconciler/reconciler.go b/pkg/controller/registry/reconciler/reconciler.go index c0ac7d9283..22ca1504d4 100644 --- a/pkg/controller/registry/reconciler/reconciler.go +++ b/pkg/controller/registry/reconciler/reconciler.go @@ -293,6 +293,9 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img s Args: []string{"/bin/copy-content", fmt.Sprintf("%s/copy-content", utilitiesPath)}, VolumeMounts: []corev1.VolumeMount{utilitiesVolumeMount}, TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError, + SecurityContext: &corev1.SecurityContext{ + ReadOnlyRootFilesystem: ptr.To(true), + }, }, corev1.Container{ Name: "extract-content", Image: img, @@ -301,8 +304,12 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img s Args: extractArgs, VolumeMounts: []corev1.VolumeMount{utilitiesVolumeMount, contentVolumeMount}, TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError, + SecurityContext: &corev1.SecurityContext{ + ReadOnlyRootFilesystem: ptr.To(true), + }, }) + pod.Spec.Containers[0].SecurityContext.ReadOnlyRootFilesystem = ptr.To(true) pod.Spec.Containers[0].Image = opmImg pod.Spec.Containers[0].Command = []string{"/bin/opm"} pod.Spec.Containers[0].ImagePullPolicy = image.InferImagePullPolicy(opmImg) @@ -356,6 +363,16 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img s } func addSecurityContext(pod *corev1.Pod, runAsUser int64) { + pod.Spec.SecurityContext = &corev1.PodSecurityContext{ + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + } + if runAsUser > 0 { + pod.Spec.SecurityContext.RunAsUser = &runAsUser + pod.Spec.SecurityContext.RunAsNonRoot = ptr.To(true) + } + for i := range pod.Spec.InitContainers { if pod.Spec.InitContainers[i].SecurityContext == nil { pod.Spec.InitContainers[i].SecurityContext = &corev1.SecurityContext{} @@ -374,16 +391,6 @@ func addSecurityContext(pod *corev1.Pod, runAsUser int64) { Drop: []corev1.Capability{"ALL"}, } } - - pod.Spec.SecurityContext = &corev1.PodSecurityContext{ - SeccompProfile: &corev1.SeccompProfile{ - Type: corev1.SeccompProfileTypeRuntimeDefault, - }, - } - if runAsUser > 0 { - pod.Spec.SecurityContext.RunAsUser = &runAsUser - pod.Spec.SecurityContext.RunAsNonRoot = ptr.To(true) - } } // getDefaultPodContextConfig returns Restricted if the defaultNamespace has the 'pod-security.kubernetes.io/enforce' label set to 'restricted', diff --git a/pkg/controller/registry/reconciler/reconciler_test.go b/pkg/controller/registry/reconciler/reconciler_test.go index 9b8eed6443..61adddf891 100644 --- a/pkg/controller/registry/reconciler/reconciler_test.go +++ b/pkg/controller/registry/reconciler/reconciler_test.go @@ -506,7 +506,7 @@ func TestPodExtractContent(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ GenerateName: "test-", Namespace: "testns", - Labels: map[string]string{"olm.pod-spec-hash": "3sDLk8MMNptrqUfdnruY2gUi1g8O4wpMWC6Q52", "olm.managed": "true"}, + Labels: map[string]string{"olm.pod-spec-hash": "2ZOz2dIc08OnA6K8YLykbH5TuFNbwrpktFugq3", "olm.managed": "true"}, Annotations: map[string]string{"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"}, }, Spec: corev1.PodSpec{ @@ -553,7 +553,7 @@ func TestPodExtractContent(t *testing.T) { SecurityContext: &corev1.SecurityContext{ Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}, AllowPrivilegeEscalation: ptr.To(false), - ReadOnlyRootFilesystem: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), }, TerminationMessagePolicy: "FallbackToLogsOnError", }, @@ -589,7 +589,7 @@ func TestPodExtractContent(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ GenerateName: "test-", Namespace: "testns", - Labels: map[string]string{"olm.pod-spec-hash": "1X4YqbfXuc9SB9ztW03WNOyanr9aIhKfijeBHH", "olm.managed": "true"}, + Labels: map[string]string{"olm.pod-spec-hash": "aeGb70iG9mui6QaqbaM6RAJG5fNVrXUjiEzEb7", "olm.managed": "true"}, Annotations: map[string]string{"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"}, }, Spec: corev1.PodSpec{ @@ -612,6 +612,7 @@ func TestPodExtractContent(t *testing.T) { SecurityContext: &corev1.SecurityContext{ Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}, AllowPrivilegeEscalation: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), }, VolumeMounts: []corev1.VolumeMount{{Name: "utilities", MountPath: "/utilities"}}, TerminationMessagePolicy: "FallbackToLogsOnError", @@ -630,6 +631,7 @@ func TestPodExtractContent(t *testing.T) { SecurityContext: &corev1.SecurityContext{ Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}, AllowPrivilegeEscalation: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), }, VolumeMounts: []corev1.VolumeMount{ {Name: "utilities", MountPath: "/utilities"}, @@ -683,7 +685,7 @@ func TestPodExtractContent(t *testing.T) { SecurityContext: &corev1.SecurityContext{ Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}, AllowPrivilegeEscalation: ptr.To(false), - ReadOnlyRootFilesystem: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), }, TerminationMessagePolicy: "FallbackToLogsOnError", VolumeMounts: []corev1.VolumeMount{{Name: "catalog-content", MountPath: "/extracted-catalog"}}, @@ -719,7 +721,7 @@ func TestPodExtractContent(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ GenerateName: "test-", Namespace: "testns", - Labels: map[string]string{"olm.pod-spec-hash": "cO4moUo3vz6jZlcoBcxY4BB8o8a4E7m5GXCzI", "olm.managed": "true"}, + Labels: map[string]string{"olm.pod-spec-hash": "bhL1lOcUJhtisRddUp8tRQupbIii64C6qz9drn", "olm.managed": "true"}, Annotations: map[string]string{"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"}, }, Spec: corev1.PodSpec{ @@ -742,6 +744,7 @@ func TestPodExtractContent(t *testing.T) { SecurityContext: &corev1.SecurityContext{ Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}, AllowPrivilegeEscalation: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), }, VolumeMounts: []corev1.VolumeMount{{Name: "utilities", MountPath: "/utilities"}}, TerminationMessagePolicy: "FallbackToLogsOnError", @@ -758,6 +761,7 @@ func TestPodExtractContent(t *testing.T) { SecurityContext: &corev1.SecurityContext{ Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}, AllowPrivilegeEscalation: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), }, VolumeMounts: []corev1.VolumeMount{ {Name: "utilities", MountPath: "/utilities"}, @@ -811,7 +815,7 @@ func TestPodExtractContent(t *testing.T) { SecurityContext: &corev1.SecurityContext{ Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}}, AllowPrivilegeEscalation: ptr.To(false), - ReadOnlyRootFilesystem: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), }, TerminationMessagePolicy: "FallbackToLogsOnError", VolumeMounts: []corev1.VolumeMount{{Name: "catalog-content", MountPath: "/extracted-catalog"}}, @@ -1017,7 +1021,7 @@ func TestPodContainerSecurityContext(t *testing.T) { Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, - ReadOnlyRootFilesystem: ptr.To(false), // Reflecting expected 'restricted' settings + ReadOnlyRootFilesystem: ptr.To(true), // Reflecting expected 'restricted' settings }, expectedSecurityContext: &corev1.PodSecurityContext{ SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault}, @@ -1052,7 +1056,7 @@ func TestPodContainerSecurityContext(t *testing.T) { Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, - ReadOnlyRootFilesystem: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), }, expectedSecurityContext: &corev1.PodSecurityContext{ SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault}, @@ -1107,7 +1111,7 @@ func TestPodContainerSecurityContext(t *testing.T) { }, namespacePodSecurityConfig: v1alpha1.Legacy, // set to the opposite of the config to catch possible errors expectedContainerSecurityContext: &corev1.SecurityContext{ - ReadOnlyRootFilesystem: ptr.To(false), + ReadOnlyRootFilesystem: ptr.To(true), AllowPrivilegeEscalation: ptr.To(false), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"},