Skip to content

Conversation

@rzlink
Copy link
Collaborator

@rzlink rzlink commented Nov 14, 2025

Fixes copying from Windows container mount roots by using SeBackupPrivilege to handle protected system files ('System Volume Information' and 'WcSandboxState') that cause 'Access is denied' errors when reading file metadata.

Implementation:

  • Uses process-wide EnableProcessPrivileges (not thread-local RunWithPrivileges)
  • Simple wrapper around copy.Copy with privilege elevation and restoration

Test changes:

  • Enabled testCopyRelativeParents for Windows with nanoserver:ltsc2022
  • Added Windows-specific test implementations for 7 target stages
  • Enabled testCopyParentsMissingDirectory on Windows

The access denied errors occur during os.Lstat() when reading file metadata. SeBackupPrivilege allows reading this metadata even with restrictive ACLs on Windows container volumes.

Fixes #6335

func copyWithElevatedPrivileges(ctx context.Context, srcRoot string, src string, destRoot string, dest string, opt ...copy.Opt) error {
privileges := []string{winio.SeBackupPrivilege}

if err := winio.EnableProcessPrivileges(privileges); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work with parallel build steps?

Note that there is already similar code in contenthash. That one seems to use a reference counter.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tonistiigi Regarding this issue, I think the right approach isn’t to check permissions to allow copying system-protected folders, but rather to skip those folders during the copy process.

I’ve opened a PR in your fsutil repository that updates the Copy function so it respects the exclusion list before making the OS system call that triggers the “access denied” errors. This should help resolve many permission-related problems on the system.

Please take a look and let me know what you think.
PR: tonistiigi/fsutil#243

Introduce util/winprivileges package with reference-counted privilege
management to prevent race conditions when multiple goroutines need
SeBackupPrivilege concurrently in parallel builds.

This fixes Windows COPY operations that fail with 'Access is denied'
errors when reading protected system files ('System Volume Information'
and 'WcSandboxState') in container mount roots.

Implementation:
- Create util/winprivileges with reference-counted Enable/Disable functions
- Use process-wide privileges (not thread-local) for multi-threaded context
- Update cache/contenthash to use centralized manager
- Update solver/llbsolver/file/backend_windows.go copyWithElevatedPrivileges
- Update session/filesync/diffcopy_windows.go sendDiffCopy
- Remove direct winio.EnableProcessPrivileges/DisableProcessPrivileges calls
- Coordinate privilege management across all components

The reference counting ensures that when multiple operations need the
privilege simultaneously (e.g., parallel builds), the privilege remains
enabled until all operations complete, preventing race conditions where
one goroutine disables the privilege while another still needs it.

Fixes #6635

Signed-off-by: Dawei Wei <[email protected]>
@rzlink rzlink force-pushed the windows-copy-sebackup-privilege branch from 3f03454 to 8bd5e4a Compare November 17, 2025 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v0.26] WCOW: Fix COPY --parents tests

3 participants