Skip to content

Commit 9be1fad

Browse files
committed
C-WCOW: Move securitycontext dir to securitypolicy pkg
Signed-off-by: Mahati Chamarthy <[email protected]>
1 parent 231e08c commit 9be1fad

File tree

3 files changed

+68
-108
lines changed

3 files changed

+68
-108
lines changed

internal/gcs-sidecar/handlers.go

Lines changed: 4 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -104,48 +104,12 @@ func (b *Bridge) createContainer(req *request) (err error) {
104104
b.hostState.RemoveContainer(ctx, containerID)
105105
}
106106
}(err)
107-
// Write security policy, signed UVM reference and host AMD certificate to
108-
// container's rootfs, so that application and sidecar containers can have
109-
// access to it. The security policy is required by containers which need to
110-
// extract init-time claims found in the security policy. The directory path
111-
// containing the files is exposed via UVM_SECURITY_CONTEXT_DIR env var.
112-
// It may be an error to have a security policy but not expose it to the
113-
// container as in that case it can never be checked as correct by a verifier.
114-
if oci.ParseAnnotationsBool(ctx, spec.Annotations, annotations.WCOWSecurityPolicyEnv, true) {
115-
encodedPolicy := b.hostState.securityOptions.PolicyEnforcer.EncodedSecurityPolicy()
116-
hostAMDCert := spec.Annotations[annotations.WCOWHostAMDCertificate]
117-
if len(encodedPolicy) > 0 || len(hostAMDCert) > 0 || len(b.hostState.securityOptions.UvmReferenceInfo) > 0 {
118-
// Use os.MkdirTemp to make sure that the directory is unique.
119-
securityContextDir, err := os.MkdirTemp(spec.Root.Path, securitypolicy.SecurityContextDirTemplate)
120-
if err != nil {
121-
return fmt.Errorf("failed to create security context directory: %w", err)
122-
}
123-
// Make sure that files inside directory are readable
124-
if err := os.Chmod(securityContextDir, 0755); err != nil {
125-
return fmt.Errorf("failed to chmod security context directory: %w", err)
126-
}
127107

128-
if len(encodedPolicy) > 0 {
129-
if err := writeFileInDir(securityContextDir, securitypolicy.PolicyFilename, []byte(encodedPolicy), 0777); err != nil {
130-
return fmt.Errorf("failed to write security policy: %w", err)
131-
}
132-
}
133-
if len(b.hostState.securityOptions.UvmReferenceInfo) > 0 {
134-
if err := writeFileInDir(securityContextDir, securitypolicy.ReferenceInfoFilename, []byte(b.hostState.securityOptions.UvmReferenceInfo), 0777); err != nil {
135-
return fmt.Errorf("failed to write UVM reference info: %w", err)
136-
}
137-
}
138-
139-
if len(hostAMDCert) > 0 {
140-
if err := writeFileInDir(securityContextDir, securitypolicy.HostAMDCertFilename, []byte(hostAMDCert), 0777); err != nil {
141-
return fmt.Errorf("failed to write host AMD certificate: %w", err)
142-
}
143-
}
144-
145-
containerCtxDir := fmt.Sprintf("/%s", filepath.Base(securityContextDir))
146-
secCtxEnv := fmt.Sprintf("UVM_SECURITY_CONTEXT_DIR=%s", containerCtxDir)
147-
spec.Process.Env = append(spec.Process.Env, secCtxEnv)
108+
if oci.ParseAnnotationsBool(ctx, spec.Annotations, annotations.WCOWSecurityPolicyEnv, true) {
109+
if err := b.hostState.securityOptions.WriteSecurityContextDir(&spec); err != nil {
110+
return fmt.Errorf("failed to write security context dir: %w", err)
148111
}
112+
cwcowHostedSystemConfig.Spec = spec
149113
}
150114

151115
// Strip the spec field
@@ -190,20 +154,6 @@ func (b *Bridge) createContainer(req *request) (err error) {
190154
return nil
191155
}
192156

193-
func writeFileInDir(dir string, filename string, data []byte, perm os.FileMode) error {
194-
st, err := os.Stat(dir)
195-
if err != nil {
196-
return err
197-
}
198-
199-
if !st.IsDir() {
200-
return fmt.Errorf("not a directory %q", dir)
201-
}
202-
203-
targetFilename := filepath.Join(dir, filename)
204-
return os.WriteFile(targetFilename, data, perm)
205-
}
206-
207157
// processParamEnvToOCIEnv converts an Environment field from ProcessParameters
208158
// (a map from environment variable to value) into an array of environment
209159
// variable assignments (where each is in the form "<variable>=<value>") which

internal/guest/runtime/hcsv2/uvm.go

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -481,47 +481,9 @@ func (h *Host) CreateContainer(ctx context.Context, id string, settings *prot.VM
481481
settings.OCISpecification.Process.Capabilities = capsToKeep
482482
}
483483

484-
// Write security policy, signed UVM reference and host AMD certificate to
485-
// container's rootfs, so that application and sidecar containers can have
486-
// access to it. The security policy is required by containers which need to
487-
// extract init-time claims found in the security policy. The directory path
488-
// containing the files is exposed via UVM_SECURITY_CONTEXT_DIR env var.
489-
// It may be an error to have a security policy but not expose it to the
490-
// container as in that case it can never be checked as correct by a verifier.
491484
if oci.ParseAnnotationsBool(ctx, settings.OCISpecification.Annotations, annotations.LCOWSecurityPolicyEnv, true) {
492-
encodedPolicy := h.securityOptions.PolicyEnforcer.EncodedSecurityPolicy()
493-
hostAMDCert := settings.OCISpecification.Annotations[annotations.LCOWHostAMDCertificate]
494-
if len(encodedPolicy) > 0 || len(hostAMDCert) > 0 || len(h.securityOptions.UvmReferenceInfo) > 0 {
495-
// Use os.MkdirTemp to make sure that the directory is unique.
496-
securityContextDir, err := os.MkdirTemp(settings.OCISpecification.Root.Path, securitypolicy.SecurityContextDirTemplate)
497-
if err != nil {
498-
return nil, fmt.Errorf("failed to create security context directory: %w", err)
499-
}
500-
// Make sure that files inside directory are readable
501-
if err := os.Chmod(securityContextDir, 0755); err != nil {
502-
return nil, fmt.Errorf("failed to chmod security context directory: %w", err)
503-
}
504-
505-
if len(encodedPolicy) > 0 {
506-
if err := writeFileInDir(securityContextDir, securitypolicy.PolicyFilename, []byte(encodedPolicy), 0744); err != nil {
507-
return nil, fmt.Errorf("failed to write security policy: %w", err)
508-
}
509-
}
510-
if len(h.securityOptions.UvmReferenceInfo) > 0 {
511-
if err := writeFileInDir(securityContextDir, securitypolicy.ReferenceInfoFilename, []byte(h.securityOptions.UvmReferenceInfo), 0744); err != nil {
512-
return nil, fmt.Errorf("failed to write UVM reference info: %w", err)
513-
}
514-
}
515-
516-
if len(hostAMDCert) > 0 {
517-
if err := writeFileInDir(securityContextDir, securitypolicy.HostAMDCertFilename, []byte(hostAMDCert), 0744); err != nil {
518-
return nil, fmt.Errorf("failed to write host AMD certificate: %w", err)
519-
}
520-
}
521-
522-
containerCtxDir := fmt.Sprintf("/%s", filepath.Base(securityContextDir))
523-
secCtxEnv := fmt.Sprintf("UVM_SECURITY_CONTEXT_DIR=%s", containerCtxDir)
524-
settings.OCISpecification.Process.Env = append(settings.OCISpecification.Process.Env, secCtxEnv)
485+
if err := h.securityOptions.WriteSecurityContextDir(settings.OCISpecification); err != nil {
486+
return nil, fmt.Errorf("failed to write security context dir: %w", err)
525487
}
526488
}
527489

@@ -1254,20 +1216,6 @@ func isPrivilegedContainerCreationRequest(ctx context.Context, spec *specs.Spec)
12541216
return oci.ParseAnnotationsBool(ctx, spec.Annotations, annotations.LCOWPrivileged, false)
12551217
}
12561218

1257-
func writeFileInDir(dir string, filename string, data []byte, perm os.FileMode) error {
1258-
st, err := os.Stat(dir)
1259-
if err != nil {
1260-
return err
1261-
}
1262-
1263-
if !st.IsDir() {
1264-
return fmt.Errorf("not a directory %q", dir)
1265-
}
1266-
1267-
targetFilename := filepath.Join(dir, filename)
1268-
return os.WriteFile(targetFilename, data, perm)
1269-
}
1270-
12711219
// Virtual Pod Management Methods
12721220

12731221
// InitializeVirtualPodSupport sets up the parent cgroup for virtual pods

pkg/securitypolicy/securitypolicy_options.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
didx509resolver "github.com/Microsoft/didx509go/pkg/did-x509-resolver"
1616
"github.com/Microsoft/hcsshim/internal/log"
1717
"github.com/Microsoft/hcsshim/internal/protocol/guestresource"
18+
"github.com/Microsoft/hcsshim/pkg/annotations"
19+
"github.com/opencontainers/runtime-spec/specs-go"
1820
"github.com/pkg/errors"
1921
"github.com/sirupsen/logrus"
2022
)
@@ -147,3 +149,63 @@ func (s *SecurityOptions) InjectFragment(ctx context.Context, fragment *guestres
147149
}
148150
return nil
149151
}
152+
153+
func writeFileInDir(dir string, filename string, data []byte, perm os.FileMode) error {
154+
st, err := os.Stat(dir)
155+
if err != nil {
156+
return err
157+
}
158+
159+
if !st.IsDir() {
160+
return fmt.Errorf("not a directory %q", dir)
161+
}
162+
163+
targetFilename := filepath.Join(dir, filename)
164+
return os.WriteFile(targetFilename, data, perm)
165+
}
166+
167+
// Write security policy, signed UVM reference and host AMD certificate to
168+
// container's rootfs, so that application and sidecar containers can have
169+
// access to it. The security policy is required by containers which need to
170+
// extract init-time claims found in the security policy. The directory path
171+
// containing the files is exposed via UVM_SECURITY_CONTEXT_DIR env var.
172+
// It may be an error to have a security policy but not expose it to the
173+
// container as in that case it can never be checked as correct by a verifier.
174+
func (s *SecurityOptions) WriteSecurityContextDir(spec *specs.Spec) error {
175+
encodedPolicy := s.PolicyEnforcer.EncodedSecurityPolicy()
176+
hostAMDCert := spec.Annotations[annotations.WCOWHostAMDCertificate]
177+
if len(encodedPolicy) > 0 || len(hostAMDCert) > 0 || len(s.UvmReferenceInfo) > 0 {
178+
// Use os.MkdirTemp to make sure that the directory is unique.
179+
securityContextDir, err := os.MkdirTemp(spec.Root.Path, SecurityContextDirTemplate)
180+
if err != nil {
181+
return fmt.Errorf("failed to create security context directory: %w", err)
182+
}
183+
// Make sure that files inside directory are readable
184+
if err := os.Chmod(securityContextDir, 0755); err != nil {
185+
return fmt.Errorf("failed to chmod security context directory: %w", err)
186+
}
187+
188+
if len(encodedPolicy) > 0 {
189+
if err := writeFileInDir(securityContextDir, PolicyFilename, []byte(encodedPolicy), 0777); err != nil {
190+
return fmt.Errorf("failed to write security policy: %w", err)
191+
}
192+
}
193+
if len(s.UvmReferenceInfo) > 0 {
194+
if err := writeFileInDir(securityContextDir, ReferenceInfoFilename, []byte(s.UvmReferenceInfo), 0777); err != nil {
195+
return fmt.Errorf("failed to write UVM reference info: %w", err)
196+
}
197+
}
198+
199+
if len(hostAMDCert) > 0 {
200+
if err := writeFileInDir(securityContextDir, HostAMDCertFilename, []byte(hostAMDCert), 0777); err != nil {
201+
return fmt.Errorf("failed to write host AMD certificate: %w", err)
202+
}
203+
}
204+
205+
containerCtxDir := fmt.Sprintf("/%s", filepath.Base(securityContextDir))
206+
secCtxEnv := fmt.Sprintf("UVM_SECURITY_CONTEXT_DIR=%s", containerCtxDir)
207+
spec.Process.Env = append(spec.Process.Env, secCtxEnv)
208+
209+
}
210+
return nil
211+
}

0 commit comments

Comments
 (0)