Skip to content

Commit 41a8a2c

Browse files
committed
C-WCOW: Move securitycontext dir to securitypolicy pkg
Signed-off-by: Mahati Chamarthy <mahati.chamarthy@gmail.com>
1 parent 2d63e5a commit 41a8a2c

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
@@ -370,47 +370,9 @@ func (h *Host) CreateContainer(ctx context.Context, id string, settings *prot.VM
370370
settings.OCISpecification.Process.Capabilities = capsToKeep
371371
}
372372

373-
// Write security policy, signed UVM reference and host AMD certificate to
374-
// container's rootfs, so that application and sidecar containers can have
375-
// access to it. The security policy is required by containers which need to
376-
// extract init-time claims found in the security policy. The directory path
377-
// containing the files is exposed via UVM_SECURITY_CONTEXT_DIR env var.
378-
// It may be an error to have a security policy but not expose it to the
379-
// container as in that case it can never be checked as correct by a verifier.
380373
if oci.ParseAnnotationsBool(ctx, settings.OCISpecification.Annotations, annotations.LCOWSecurityPolicyEnv, true) {
381-
encodedPolicy := h.securityOptions.PolicyEnforcer.EncodedSecurityPolicy()
382-
hostAMDCert := settings.OCISpecification.Annotations[annotations.LCOWHostAMDCertificate]
383-
if len(encodedPolicy) > 0 || len(hostAMDCert) > 0 || len(h.securityOptions.UvmReferenceInfo) > 0 {
384-
// Use os.MkdirTemp to make sure that the directory is unique.
385-
securityContextDir, err := os.MkdirTemp(settings.OCISpecification.Root.Path, securitypolicy.SecurityContextDirTemplate)
386-
if err != nil {
387-
return nil, fmt.Errorf("failed to create security context directory: %w", err)
388-
}
389-
// Make sure that files inside directory are readable
390-
if err := os.Chmod(securityContextDir, 0755); err != nil {
391-
return nil, fmt.Errorf("failed to chmod security context directory: %w", err)
392-
}
393-
394-
if len(encodedPolicy) > 0 {
395-
if err := writeFileInDir(securityContextDir, securitypolicy.PolicyFilename, []byte(encodedPolicy), 0744); err != nil {
396-
return nil, fmt.Errorf("failed to write security policy: %w", err)
397-
}
398-
}
399-
if len(h.securityOptions.UvmReferenceInfo) > 0 {
400-
if err := writeFileInDir(securityContextDir, securitypolicy.ReferenceInfoFilename, []byte(h.securityOptions.UvmReferenceInfo), 0744); err != nil {
401-
return nil, fmt.Errorf("failed to write UVM reference info: %w", err)
402-
}
403-
}
404-
405-
if len(hostAMDCert) > 0 {
406-
if err := writeFileInDir(securityContextDir, securitypolicy.HostAMDCertFilename, []byte(hostAMDCert), 0744); err != nil {
407-
return nil, fmt.Errorf("failed to write host AMD certificate: %w", err)
408-
}
409-
}
410-
411-
containerCtxDir := fmt.Sprintf("/%s", filepath.Base(securityContextDir))
412-
secCtxEnv := fmt.Sprintf("UVM_SECURITY_CONTEXT_DIR=%s", containerCtxDir)
413-
settings.OCISpecification.Process.Env = append(settings.OCISpecification.Process.Env, secCtxEnv)
374+
if err := h.securityOptions.WriteSecurityContextDir(settings.OCISpecification); err != nil {
375+
return nil, fmt.Errorf("failed to write security context dir: %w", err)
414376
}
415377
}
416378

@@ -1141,17 +1103,3 @@ func processOCIEnvToParam(envs []string) map[string]string {
11411103
func isPrivilegedContainerCreationRequest(ctx context.Context, spec *specs.Spec) bool {
11421104
return oci.ParseAnnotationsBool(ctx, spec.Annotations, annotations.LCOWPrivileged, false)
11431105
}
1144-
1145-
func writeFileInDir(dir string, filename string, data []byte, perm os.FileMode) error {
1146-
st, err := os.Stat(dir)
1147-
if err != nil {
1148-
return err
1149-
}
1150-
1151-
if !st.IsDir() {
1152-
return fmt.Errorf("not a directory %q", dir)
1153-
}
1154-
1155-
targetFilename := filepath.Join(dir, filename)
1156-
return os.WriteFile(targetFilename, data, perm)
1157-
}

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)