@@ -12,6 +12,8 @@ import (
1212 "strings"
1313 "time"
1414
15+ "regexp"
16+
1517 "github.com/Microsoft/hcsshim/hcn"
1618 "github.com/Microsoft/hcsshim/internal/bridgeutils/commonutils"
1719 "github.com/Microsoft/hcsshim/internal/fsformatter"
@@ -37,6 +39,8 @@ const (
3739 UVMContainerID = "00000000-0000-0000-0000-000000000000"
3840)
3941
42+ var volumeGUIDRe = regexp .MustCompile (`^\\\\\?\\Volume\{([0-9A-Fa-f\-]+)\}\\Files$` )
43+
4044// - Handler functions handle the incoming message requests. It
4145// also enforces security policy for confidential cwcow containers.
4246// - These handler functions may do some additional processing before
@@ -544,6 +548,14 @@ func (b *Bridge) lifecycleNotification(req *request) (err error) {
544548 return nil
545549}
546550
551+ func volumeGUIDFromLayerPath (p string ) (string , bool ) {
552+ m := volumeGUIDRe .FindStringSubmatch (p )
553+ if len (m ) != 2 {
554+ return "" , false
555+ }
556+ return m [1 ], true
557+ }
558+
547559func (b * Bridge ) modifySettings (req * request ) (err error ) {
548560 ctx , span := oc .StartSpan (req .ctx , "sidecar::modifySettings" )
549561 defer span .End ()
@@ -676,6 +688,20 @@ func (b *Bridge) modifySettings(req *request) (err error) {
676688 return errors .Wrap (err , "CIM mount is denied by policy" )
677689 }
678690
691+ // Volume GUID from request
692+ volGUID := wcowBlockCimMounts .VolumeGUID .String ()
693+
694+ // Cache hashes along with volGUID
695+ b .hostState .blockCIMVolumeHashes [volGUID ] = hashesToVerify
696+
697+ // Store the containerID (associated with volGUID) to mark that hashes are verified for this container
698+ if _ , ok := b .hostState .blockCIMVolumeContainers [volGUID ]; ! ok {
699+ b .hostState .blockCIMVolumeContainers [volGUID ] = make (map [string ]struct {})
700+ }
701+ b .hostState .blockCIMVolumeContainers [volGUID ][containerID ] = struct {}{}
702+
703+ log .G (ctx ).Tracef ("Cached %d verified CIM layer hashes for volume %s (container %s)" , len (hashesToVerify ), volGUID , containerID )
704+
679705 if len (layerCIMs ) > 1 {
680706 _ , err = cimfs .MountMergedVerifiedBlockCIMs (layerCIMs [0 ], layerCIMs [1 :], wcowBlockCimMounts .MountFlags , wcowBlockCimMounts .VolumeGUID , layerDigests [0 ])
681707 if err != nil {
@@ -710,6 +736,28 @@ func (b *Bridge) modifySettings(req *request) (err error) {
710736 log .G (ctx ).Tracef ("CWCOWCombinedLayers:: ContainerID: %v, ContainerRootPath: %v, Layers: %v, ScratchPath: %v" ,
711737 containerID , settings .CombinedLayers .ContainerRootPath , settings .CombinedLayers .Layers , settings .CombinedLayers .ScratchPath )
712738
739+ // The layers size is only one, this is just defensive checking
740+ if len (settings .CombinedLayers .Layers ) == 1 {
741+ layerPath := settings .CombinedLayers .Layers [0 ].Path
742+ if guidStr , ok := volumeGUIDFromLayerPath (layerPath ); ok {
743+ hashes , haveHashes := b .hostState .blockCIMVolumeHashes [guidStr ]
744+ if haveHashes {
745+ // Only do this if it wasn't already enforced by the ResourceTypeWCOWBlockCims request
746+ containers := b .hostState .blockCIMVolumeContainers [guidStr ]
747+ if _ , seen := containers [containerID ]; ! seen {
748+ // This is a container with CIMs already mounted (container with similar layers as an existing container). Call EnforceVerifiedCIMsPolicy on this new container
749+ log .G (ctx ).Tracef ("Verified CIM hashes for reused mount volume %s (container %s)" , guidStr , containerID )
750+ if err := b .hostState .securityPolicyEnforcer .EnforceVerifiedCIMsPolicy (ctx , containerID , hashes ); err != nil {
751+ return fmt .Errorf ("CIM mount is denied by policy for this container: %w" , err )
752+ }
753+ containers [containerID ] = struct {}{}
754+ }
755+ } else {
756+ log .G (ctx ).Debugf ("No cached CIM hashes found for volume %s" , guidStr )
757+ }
758+ }
759+ }
760+
713761 //Since unencrypted scratch is not an option, always pass true
714762 if err := b .hostState .securityPolicyEnforcer .EnforceScratchMountPolicy (ctx , settings .CombinedLayers .ContainerRootPath , true ); err != nil {
715763 return fmt .Errorf ("scratch mounting denied by policy: %w" , err )
0 commit comments