Skip to content
4 changes: 2 additions & 2 deletions cmd/gcs-sidecar/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/Microsoft/hcsshim/internal/gcs/prot"
shimlog "github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/pspdriver"
"github.com/Microsoft/hcsshim/pkg/amdsevsnp"
"github.com/Microsoft/hcsshim/pkg/securitypolicy"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
Expand Down Expand Up @@ -217,7 +217,7 @@ func main() {
return
}

if err := pspdriver.StartPSPDriver(ctx); err != nil {
if err := amdsevsnp.StartPSPDriver(ctx); err != nil {
// When error happens, pspdriver.GetPspDriverError() returns true.
// In that case, gcs-sidecar should keep the initial "deny" policy
// and reject all requests from the host.
Expand Down
6 changes: 1 addition & 5 deletions internal/gcs-sidecar/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ type Bridge struct {
// and send responses back to hcsshim respectively.
sendToGCSCh chan request
sendToShimCh chan bridgeResponse

// logging target
logWriter io.Writer
}

// SequenceID is used to correlate requests and responses.
Expand Down Expand Up @@ -81,7 +78,7 @@ type request struct {
}

func NewBridge(shimConn io.ReadWriteCloser, inboxGCSConn io.ReadWriteCloser, initialEnforcer securitypolicy.SecurityPolicyEnforcer, logWriter io.Writer) *Bridge {
hostState := NewHost(initialEnforcer)
hostState := NewHost(initialEnforcer, logWriter)
return &Bridge{
pending: make(map[sequenceID]chan *prot.ContainerExecuteProcessResponse),
rpcHandlerList: make(map[prot.RPCProc]HandlerFunc),
Expand All @@ -90,7 +87,6 @@ func NewBridge(shimConn io.ReadWriteCloser, inboxGCSConn io.ReadWriteCloser, ini
inboxGCSConn: inboxGCSConn,
sendToGCSCh: make(chan request),
sendToShimCh: make(chan bridgeResponse),
logWriter: logWriter,
}
}

Expand Down
59 changes: 26 additions & 33 deletions internal/gcs-sidecar/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ import (
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/oc"
oci "github.com/Microsoft/hcsshim/internal/oci"
"github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
"github.com/Microsoft/hcsshim/internal/protocol/guestresource"
"github.com/Microsoft/hcsshim/internal/windevice"
"github.com/Microsoft/hcsshim/pkg/annotations"
"github.com/Microsoft/hcsshim/pkg/cimfs"
"github.com/Microsoft/hcsshim/pkg/securitypolicy"
"github.com/pkg/errors"
Expand Down Expand Up @@ -80,15 +82,12 @@ func (b *Bridge) createContainer(req *request) (err error) {
user := securitypolicy.IDName{
Name: spec.Process.User.Username,
}
_, _, _, err := b.hostState.securityPolicyEnforcer.EnforceCreateContainerPolicyV2(req.ctx, containerID, spec.Process.Args, spec.Process.Env, spec.Process.Cwd, spec.Mounts, user, nil)
_, _, _, err := b.hostState.securityOptions.PolicyEnforcer.EnforceCreateContainerPolicyV2(req.ctx, containerID, spec.Process.Args, spec.Process.Env, spec.Process.Cwd, spec.Mounts, user, nil)

if err != nil {
return fmt.Errorf("CreateContainer operation is denied by policy: %w", err)
}

if err := b.hostState.SetupSecurityContextDir(ctx, &spec); err != nil {
return err
}
commandLine := len(spec.Process.Args) > 0
c := &Container{
id: containerID,
Expand All @@ -109,6 +108,13 @@ func (b *Bridge) createContainer(req *request) (err error) {
}
}(err)

if oci.ParseAnnotationsBool(ctx, spec.Annotations, annotations.WCOWSecurityPolicyEnv, true) {
if err := b.hostState.securityOptions.WriteSecurityContextDir(&spec); err != nil {
return fmt.Errorf("failed to write security context dir: %w", err)
}
cwcowHostedSystemConfig.Spec = spec
}

// Strip the spec field
hostedSystemBytes, err := json.Marshal(cwcowHostedSystem)

Expand Down Expand Up @@ -151,20 +157,6 @@ func (b *Bridge) createContainer(req *request) (err error) {
return nil
}

func writeFileInDir(dir string, filename string, data []byte, perm os.FileMode) error {
st, err := os.Stat(dir)
if err != nil {
return err
}

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

targetFilename := filepath.Join(dir, filename)
return os.WriteFile(targetFilename, data, perm)
}

// processParamEnvToOCIEnv converts an Environment field from ProcessParameters
// (a map from environment variable to value) into an array of environment
// variable assignments (where each is in the form "<variable>=<value>") which
Expand Down Expand Up @@ -203,7 +195,7 @@ func (b *Bridge) shutdownGraceful(req *request) (err error) {
return fmt.Errorf("failed to unmarshal shutdownGraceful: %w", err)
}

err = b.hostState.securityPolicyEnforcer.EnforceShutdownContainerPolicy(req.ctx, r.ContainerID)
err = b.hostState.securityOptions.PolicyEnforcer.EnforceShutdownContainerPolicy(req.ctx, r.ContainerID)
if err != nil {
return fmt.Errorf("rpcShudownGraceful operation not allowed: %w", err)
}
Expand Down Expand Up @@ -247,7 +239,7 @@ func (b *Bridge) executeProcess(req *request) (err error) {

if containerID == UVMContainerID {
log.G(req.ctx).Tracef("Enforcing policy on external exec process")
_, _, err := b.hostState.securityPolicyEnforcer.EnforceExecExternalProcessPolicy(
_, _, err := b.hostState.securityOptions.PolicyEnforcer.EnforceExecExternalProcessPolicy(
req.ctx,
commandLine,
processParamEnvToOCIEnv(processParams.Environment),
Expand Down Expand Up @@ -279,7 +271,7 @@ func (b *Bridge) executeProcess(req *request) (err error) {
Name: processParams.User,
}
log.G(req.ctx).Tracef("Enforcing policy on exec in container")
_, _, _, err = b.hostState.securityPolicyEnforcer.
_, _, _, err = b.hostState.securityOptions.PolicyEnforcer.
EnforceExecInContainerPolicyV2(
req.ctx,
containerID,
Expand Down Expand Up @@ -385,7 +377,7 @@ func (b *Bridge) signalProcess(req *request) (err error) {
WindowsSignal: wcowOptions.Signal,
WindowsCommand: commandLine,
}
err = b.hostState.securityPolicyEnforcer.EnforceSignalContainerProcessPolicyV2(req.ctx, containerID, opts)
err = b.hostState.securityOptions.PolicyEnforcer.EnforceSignalContainerProcessPolicyV2(req.ctx, containerID, opts)
if err != nil {
return err
}
Expand Down Expand Up @@ -414,7 +406,7 @@ func (b *Bridge) getProperties(req *request) (err error) {
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()

if err := b.hostState.securityPolicyEnforcer.EnforceGetPropertiesPolicy(req.ctx); err != nil {
if err := b.hostState.securityOptions.PolicyEnforcer.EnforceGetPropertiesPolicy(req.ctx); err != nil {
return errors.Wrapf(err, "get properties denied due to policy")
}

Expand Down Expand Up @@ -552,11 +544,14 @@ func (b *Bridge) modifySettings(req *request) (err error) {
log.G(ctx).Tracef("hcsschema.MappedDirectory { %v }", settings)

case guestresource.ResourceTypeSecurityPolicy:
securityPolicyRequest := modifyGuestSettingsRequest.Settings.(*guestresource.WCOWConfidentialOptions)
securityPolicyRequest := modifyGuestSettingsRequest.Settings.(*guestresource.ConfidentialOptions)
log.G(ctx).Tracef("WCOWConfidentialOptions: { %v}", securityPolicyRequest)
err := b.hostState.SetWCOWConfidentialUVMOptions(req.ctx, securityPolicyRequest, b.logWriter)
err := b.hostState.securityOptions.SetConfidentialOptions(ctx,
securityPolicyRequest.EnforcerType,
securityPolicyRequest.EncodedSecurityPolicy,
securityPolicyRequest.EncodedUVMReference)
if err != nil {
return errors.Wrap(err, "error creating enforcer")
return errors.Wrap(err, "Failed to set Confidentia UVM Options")
}
// Send response back to shim
resp := &prot.ResponseBase{
Expand All @@ -569,12 +564,11 @@ func (b *Bridge) modifySettings(req *request) (err error) {
}
return nil
case guestresource.ResourceTypePolicyFragment:
//Note: Reusing the same type LCOWSecurityPolicyFragment for CWCOW.
r, ok := modifyGuestSettingsRequest.Settings.(*guestresource.LCOWSecurityPolicyFragment)
r, ok := modifyGuestSettingsRequest.Settings.(*guestresource.SecurityPolicyFragment)
if !ok {
return errors.New("the request settings are not of type LCOWSecurityPolicyFragment")
return errors.New("the request settings are not of type SecurityPolicyFragment")
}
return b.hostState.InjectFragment(ctx, r)
return b.hostState.securityOptions.InjectFragment(ctx, r)
case guestresource.ResourceTypeWCOWBlockCims:
// This is request to mount the merged cim at given volumeGUID
if modifyGuestSettingsRequest.RequestType == guestrequest.RequestTypeRemove {
Expand All @@ -588,7 +582,6 @@ func (b *Bridge) modifySettings(req *request) (err error) {
// The block device takes some time to show up. Wait for a few seconds.
time.Sleep(2 * time.Second)

//TODO(Mahati) : test and verify CIM hashes
var layerCIMs []*cimfs.BlockCIM
layerHashes := make([]string, len(wcowBlockCimMounts.BlockCIMs))
layerDigests := make([][]byte, len(wcowBlockCimMounts.BlockCIMs))
Expand Down Expand Up @@ -624,7 +617,7 @@ func (b *Bridge) modifySettings(req *request) (err error) {
hashesToVerify = layerHashes[1:]
}

err := b.hostState.securityPolicyEnforcer.EnforceVerifiedCIMsPolicy(req.ctx, containerID, hashesToVerify)
err := b.hostState.securityOptions.PolicyEnforcer.EnforceVerifiedCIMsPolicy(req.ctx, containerID, hashesToVerify)
if err != nil {
return errors.Wrap(err, "CIM mount is denied by policy")
}
Expand Down Expand Up @@ -664,7 +657,7 @@ func (b *Bridge) modifySettings(req *request) (err error) {
containerID, settings.CombinedLayers.ContainerRootPath, settings.CombinedLayers.Layers, settings.CombinedLayers.ScratchPath)

//Since unencrypted scratch is not an option, always pass true
if err := b.hostState.securityPolicyEnforcer.EnforceScratchMountPolicy(ctx, settings.CombinedLayers.ContainerRootPath, true); err != nil {
if err := b.hostState.securityOptions.PolicyEnforcer.EnforceScratchMountPolicy(ctx, settings.CombinedLayers.ContainerRootPath, true); err != nil {
return fmt.Errorf("scratch mounting denied by policy: %w", err)
}
// The following two folders are expected to be present in the scratch.
Expand Down
Loading