From d373ebc4de9a514af7d42c2edc980ec1d0868598 Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Sun, 2 Apr 2023 08:35:34 -0700 Subject: [PATCH] Properly mount base layers As opposed to a writable layer derived from a base layer, the volume path of a base layer, once activated and prepared will not be a WCIFS volume, but the actual path on disk to the snapshot. We cannot directly mount this folder, as that would mean a client may gain access and potentially damage important metadata files that would render the layer unusabble. For base layers we need to mount the Files folder which must exist in any valid base windows-layer. Signed-off-by: Gabriel Adrian Samfira --- mount/mount_windows.go | 8 ++++++++ snapshots/windows/windows.go | 12 +----------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/mount/mount_windows.go b/mount/mount_windows.go index e964c9bfb..3ef7a3872 100644 --- a/mount/mount_windows.go +++ b/mount/mount_windows.go @@ -99,6 +99,14 @@ func (m *Mount) mount(target string) (retErr error) { return fmt.Errorf("failed to get volume path for layer %s: %w", m.Source, err) } + if len(parentLayerPaths) == 0 { + // this is a base layer. It gets mounted without going through WCIFS. We need to mount the Files + // folder, not the actual source, or the client may inadvertently remove metadata files. + volume = filepath.Join(volume, "Files") + if _, err := os.Stat(volume); err != nil { + return fmt.Errorf("no Files folder in layer %s", layerID) + } + } if err := bindfilter.ApplyFileBinding(target, volume, m.ReadOnly()); err != nil { return fmt.Errorf("failed to set volume mount path for layer %s: %w", m.Source, err) } diff --git a/snapshots/windows/windows.go b/snapshots/windows/windows.go index 0f35000a7..eca46dfe8 100644 --- a/snapshots/windows/windows.go +++ b/snapshots/windows/windows.go @@ -319,16 +319,6 @@ func (s *snapshotter) mounts(sn storage.Snapshot, key string) []mount.Mount { mountType := "windows-layer" - if len(sn.ParentIDs) == 0 { - // A mount of a parentless snapshot is a bind-mount. - mountType = "bind" - // If not being extracted into, then the bind-target is the - // "Files" subdirectory. - if !strings.Contains(key, snapshots.UnpackKeyPrefix) { - source = filepath.Join(source, "Files") - } - } - // error is not checked here, as a string array will never fail to Marshal parentLayersJSON, _ := json.Marshal(parentLayerPaths) parentLayersOption := mount.ParentLayerPathsFlag + string(parentLayersJSON) @@ -336,7 +326,7 @@ func (s *snapshotter) mounts(sn storage.Snapshot, key string) []mount.Mount { options := []string{ roFlag, } - if mountType != "bind" { + if len(sn.ParentIDs) != 0 { options = append(options, parentLayersOption) } mounts := []mount.Mount{