Skip to content

Commit

Permalink
pr feedback: put measurement files into unique directory
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim An <maksiman@microsoft.com>
  • Loading branch information
anmaxvl committed Apr 4, 2023
1 parent c3577f5 commit 354520c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 62 deletions.
44 changes: 21 additions & 23 deletions internal/guest/runtime/hcsv2/uvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,22 +423,22 @@ func (h *Host) CreateContainer(ctx context.Context, id string, settings *prot.VM
}

// Write security policy, signed UVM reference and host AMD certificate to
// container's rootfs, so that application and
// Export security policy and signed UVM reference info as one of the
// process's environment variables so that application and sidecar
// containers can have access to it. The security policy is required
// by containers which need to extract init-time claims found in the
// security policy.
//
// We append the variable after the security policy enforcing logic
// completes to bypass it; the security policy variable cannot be included
// in the security policy as its value is not available security policy
// construction time.

// It may be an error to have a security policy but not expose it to the container as
// in that case it can never be checked as correct by a verifier.
// container's rootfs, so that application and sidecar containers can have
// access to it. The security policy is required by containers which need to
// extract init-time claims found in the security policy. The directory path
// containing the files is exposed via UVM_SECURITY_CONTEXT_DIR env var.
// It may be an error to have a security policy but not expose it to the
// container as in that case it can never be checked as correct by a verifier.
if oci.ParseAnnotationsBool(ctx, settings.OCISpecification.Annotations, annotations.UVMSecurityPolicyEnv, true) {
securityContextDir := filepath.Join(settings.OCISpecification.Root.Path, securitypolicy.SecurityContextMountPath)
securityContextDir, err := os.MkdirTemp(settings.OCISpecification.Root.Path, securitypolicy.SecurityContextDirTemplate)
if err != nil {
return nil, fmt.Errorf("failed to create security context directory: %w", err)
}
// Make sure it's readable
if err := os.Chmod(securityContextDir, 0744); err != nil {
return nil, fmt.Errorf("failed to chmod security context directory: %w", err)
}

encodedPolicy := h.securityPolicyEnforcer.EncodedSecurityPolicy()
if len(encodedPolicy) > 0 {
if _, err := writeFileInDir(securityContextDir, securitypolicy.PolicyFilename,
Expand All @@ -461,7 +461,8 @@ func (h *Host) CreateContainer(ctx context.Context, id string, settings *prot.VM
}

if len(encodedPolicy) > 0 || len(h.uvmReferenceInfo) > 0 || len(hostAMDCert) > 0 {
secCtxEnv := fmt.Sprintf("UVM_SECURITY_CONTEXT_DIR=%s", securitypolicy.SecurityContextMountPath)
containerCtxDir := fmt.Sprintf("/%s", filepath.Base(securityContextDir))
secCtxEnv := fmt.Sprintf("UVM_SECURITY_CONTEXT_DIR=%s", containerCtxDir)
settings.OCISpecification.Process.Env = append(settings.OCISpecification.Process.Env, secCtxEnv)
}
}
Expand Down Expand Up @@ -1135,13 +1136,10 @@ func isPrivilegedContainerCreationRequest(ctx context.Context, spec *specs.Spec)
func writeFileInDir(dir string, filename string, content io.Reader) (int64, error) {
st, err := os.Stat(dir)
if err != nil {
if !os.IsNotExist(err) {
return 0, err
}
if err := os.MkdirAll(dir, 0700); err != nil {
return 0, err
}
} else if !st.IsDir() {
return 0, err
}

if !st.IsDir() {
return 0, fmt.Errorf("not a directory %q", dir)
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/securitypolicy/securitypolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ const (
const plan9Prefix = "plan9://"

const (
SecurityContextMountPath = "/tmp/security-context"
PolicyFilename = "security-policy-base64"
HostAMDCertFilename = "host-amd-cert-base64"
ReferenceInfoFilename = "reference-info-base64"
SecurityContextDirTemplate = "security-context-*"
PolicyFilename = "security-policy-base64"
HostAMDCertFilename = "host-amd-cert-base64"
ReferenceInfoFilename = "reference-info-base64"
)

// PolicyConfig contains toml or JSON config for security policy.
Expand Down
44 changes: 9 additions & 35 deletions test/cri-containerd/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"encoding/base64"
"fmt"
"os"
"path"
"path/filepath"
"strconv"
"strings"
Expand Down Expand Up @@ -774,24 +773,14 @@ func Test_RunContainer_WithPolicy_And_SecurityPolicyEnv_Annotation(t *testing.T)
defer cancel()

alpineCmd := []string{"ash", "-c", "sleep 10"}

listDirCmd := []string{"ls", "-l", securitypolicy.SecurityContextMountPath}
// Make sure these are linux paths
catPolicyCmd := []string{"cat", path.Join(securitypolicy.SecurityContextMountPath, securitypolicy.PolicyFilename)}
catCertCmd := []string{"cat", path.Join(securitypolicy.SecurityContextMountPath, securitypolicy.HostAMDCertFilename)}
listDirCmd := []string{"ash", "-c", fmt.Sprintf("ls -l /%s", securitypolicy.SecurityContextDirTemplate)}
opts := []securitypolicy.ContainerConfigOpt{
securitypolicy.WithCommand(alpineCmd),
securitypolicy.WithAllowStdioAccess(true),
securitypolicy.WithExecProcesses([]securitypolicy.ExecProcessConfig{
{
Command: listDirCmd,
},
{
Command: catPolicyCmd,
},
{
Command: catCertCmd,
},
}),
}
for _, config := range []struct {
Expand Down Expand Up @@ -845,38 +834,23 @@ func Test_RunContainer_WithPolicy_And_SecurityPolicyEnv_Annotation(t *testing.T)
ContainerId: containerID,
Cmd: listDirCmd,
})
stdout := string(r.Stdout)
if setPolicyEnv {
if r.ExitCode != 0 {
t.Log(string(r.Stderr))
t.Fatalf("unexpected exec exit code: %d", r.ExitCode)
}

// validate content of the policy file
r2 := execSync(t, client, ctx, &runtime.ExecSyncRequest{
ContainerId: containerID,
Cmd: catPolicyCmd,
})
r2stdout := string(r2.Stdout)
if r2stdout != config.policy {
t.Log(config.policy)
t.Log(r2stdout)
t.Fatal("supplied policy is different from the one written in file")
if !strings.Contains(stdout, securitypolicy.PolicyFilename) {
t.Log(stdout)
t.Fatalf("security policy file not found: %s", securitypolicy.PolicyFilename)
}

// validate content of AMD cert file
r3 := execSync(t, client, ctx, &runtime.ExecSyncRequest{
ContainerId: containerID,
Cmd: catCertCmd,
})
r3stdout := string(r3.Stdout)
if r3stdout != certValue {
t.Log(certValue)
t.Log(r3stdout)
t.Fatal("supplied cert is different from the one written in file")
if !strings.Contains(stdout, securitypolicy.HostAMDCertFilename) {
t.Log(stdout)
t.Fatalf("AMD certificate file not found: %s", securitypolicy.HostAMDCertFilename)
}
} else {
if r.ExitCode != 1 {
t.Log(string(r.Stdout))
t.Log(stdout)
t.Fatalf("unexpected exec exit code: %d", r.ExitCode)
}
if !strings.Contains(string(r.Stderr), "No such file") {
Expand Down

0 comments on commit 354520c

Please sign in to comment.