Skip to content

Commit 87e9fc9

Browse files
committed
C-WCOW: Move securitycontext dir to securitypolicy pkg
Signed-off-by: Mahati Chamarthy <mahati.chamarthy@gmail.com>
1 parent 113f3fe commit 87e9fc9

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

134-
if len(encodedPolicy) > 0 {
135-
if err := writeFileInDir(securityContextDir, securitypolicy.PolicyFilename, []byte(encodedPolicy), 0777); err != nil {
136-
return fmt.Errorf("failed to write security policy: %w", err)
137-
}
138-
}
139-
if len(b.hostState.securityOptions.UvmReferenceInfo) > 0 {
140-
if err := writeFileInDir(securityContextDir, securitypolicy.ReferenceInfoFilename, []byte(b.hostState.securityOptions.UvmReferenceInfo), 0777); err != nil {
141-
return fmt.Errorf("failed to write UVM reference info: %w", err)
142-
}
143-
}
144-
145-
if len(hostAMDCert) > 0 {
146-
if err := writeFileInDir(securityContextDir, securitypolicy.HostAMDCertFilename, []byte(hostAMDCert), 0777); err != nil {
147-
return fmt.Errorf("failed to write host AMD certificate: %w", err)
148-
}
149-
}
150-
151-
containerCtxDir := fmt.Sprintf("/%s", filepath.Base(securityContextDir))
152-
secCtxEnv := fmt.Sprintf("UVM_SECURITY_CONTEXT_DIR=%s", containerCtxDir)
153-
spec.Process.Env = append(spec.Process.Env, secCtxEnv)
114+
if oci.ParseAnnotationsBool(ctx, spec.Annotations, annotations.WCOWSecurityPolicyEnv, true) {
115+
if err := b.hostState.securityOptions.WriteSecurityContextDir(&spec); err != nil {
116+
return fmt.Errorf("failed to write security context dir: %w", err)
154117
}
118+
cwcowHostedSystemConfig.Spec = spec
155119
}
156120

157121
// Strip the spec field
@@ -196,20 +160,6 @@ func (b *Bridge) createContainer(req *request) (err error) {
196160
return nil
197161
}
198162

199-
func writeFileInDir(dir string, filename string, data []byte, perm os.FileMode) error {
200-
st, err := os.Stat(dir)
201-
if err != nil {
202-
return err
203-
}
204-
205-
if !st.IsDir() {
206-
return fmt.Errorf("not a directory %q", dir)
207-
}
208-
209-
targetFilename := filepath.Join(dir, filename)
210-
return os.WriteFile(targetFilename, data, perm)
211-
}
212-
213163
// processParamEnvToOCIEnv converts an Environment field from ProcessParameters
214164
// (a map from environment variable to value) into an array of environment
215165
// 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
@@ -538,47 +538,9 @@ func (h *Host) CreateContainer(ctx context.Context, id string, settings *prot.VM
538538
settings.OCISpecification.Process.Capabilities = capsToKeep
539539
}
540540

541-
// Write security policy, signed UVM reference and host AMD certificate to
542-
// container's rootfs, so that application and sidecar containers can have
543-
// access to it. The security policy is required by containers which need to
544-
// extract init-time claims found in the security policy. The directory path
545-
// containing the files is exposed via UVM_SECURITY_CONTEXT_DIR env var.
546-
// It may be an error to have a security policy but not expose it to the
547-
// container as in that case it can never be checked as correct by a verifier.
548541
if oci.ParseAnnotationsBool(ctx, settings.OCISpecification.Annotations, annotations.LCOWSecurityPolicyEnv, true) {
549-
encodedPolicy := h.securityOptions.PolicyEnforcer.EncodedSecurityPolicy()
550-
hostAMDCert := settings.OCISpecification.Annotations[annotations.LCOWHostAMDCertificate]
551-
if len(encodedPolicy) > 0 || len(hostAMDCert) > 0 || len(h.securityOptions.UvmReferenceInfo) > 0 {
552-
// Use os.MkdirTemp to make sure that the directory is unique.
553-
securityContextDir, err := os.MkdirTemp(settings.OCISpecification.Root.Path, securitypolicy.SecurityContextDirTemplate)
554-
if err != nil {
555-
return nil, fmt.Errorf("failed to create security context directory: %w", err)
556-
}
557-
// Make sure that files inside directory are readable
558-
if err := os.Chmod(securityContextDir, 0755); err != nil {
559-
return nil, fmt.Errorf("failed to chmod security context directory: %w", err)
560-
}
561-
562-
if len(encodedPolicy) > 0 {
563-
if err := writeFileInDir(securityContextDir, securitypolicy.PolicyFilename, []byte(encodedPolicy), 0744); err != nil {
564-
return nil, fmt.Errorf("failed to write security policy: %w", err)
565-
}
566-
}
567-
if len(h.securityOptions.UvmReferenceInfo) > 0 {
568-
if err := writeFileInDir(securityContextDir, securitypolicy.ReferenceInfoFilename, []byte(h.securityOptions.UvmReferenceInfo), 0744); err != nil {
569-
return nil, fmt.Errorf("failed to write UVM reference info: %w", err)
570-
}
571-
}
572-
573-
if len(hostAMDCert) > 0 {
574-
if err := writeFileInDir(securityContextDir, securitypolicy.HostAMDCertFilename, []byte(hostAMDCert), 0744); err != nil {
575-
return nil, fmt.Errorf("failed to write host AMD certificate: %w", err)
576-
}
577-
}
578-
579-
containerCtxDir := fmt.Sprintf("/%s", filepath.Base(securityContextDir))
580-
secCtxEnv := fmt.Sprintf("UVM_SECURITY_CONTEXT_DIR=%s", containerCtxDir)
581-
settings.OCISpecification.Process.Env = append(settings.OCISpecification.Process.Env, secCtxEnv)
542+
if err := h.securityOptions.WriteSecurityContextDir(settings.OCISpecification); err != nil {
543+
return nil, fmt.Errorf("failed to write security context dir: %w", err)
582544
}
583545
}
584546

@@ -1320,20 +1282,6 @@ func isPrivilegedContainerCreationRequest(ctx context.Context, spec *specs.Spec)
13201282
return oci.ParseAnnotationsBool(ctx, spec.Annotations, annotations.LCOWPrivileged, false)
13211283
}
13221284

1323-
func writeFileInDir(dir string, filename string, data []byte, perm os.FileMode) error {
1324-
st, err := os.Stat(dir)
1325-
if err != nil {
1326-
return err
1327-
}
1328-
1329-
if !st.IsDir() {
1330-
return fmt.Errorf("not a directory %q", dir)
1331-
}
1332-
1333-
targetFilename := filepath.Join(dir, filename)
1334-
return os.WriteFile(targetFilename, data, perm)
1335-
}
1336-
13371285
// Virtual Pod Management Methods
13381286

13391287
// 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)