Merge pull request #50871 from vvoland/50870-28.x
[28.x backport] graphdriver/windows: Potential fix for access denied
diff --git a/daemon/graphdriver/windows/windows.go b/daemon/graphdriver/windows/windows.go
index 151256d..428239c 100644
--- a/daemon/graphdriver/windows/windows.go
+++ b/daemon/graphdriver/windows/windows.go
@@ -799,37 +799,25 @@
}
// writeLayer writes a layer from a tar file.
-func writeLayer(layerData io.Reader, home string, id string, parentLayerPaths ...string) (size int64, retErr error) {
- err := winio.EnableProcessPrivileges([]string{winio.SeSecurityPrivilege, winio.SeBackupPrivilege, winio.SeRestorePrivilege})
- if err != nil {
- return 0, err
- }
- if noreexec {
- defer func() {
- if err := winio.DisableProcessPrivileges([]string{winio.SeSecurityPrivilege, winio.SeBackupPrivilege, winio.SeRestorePrivilege}); err != nil {
- // This should never happen, but just in case when in debugging mode.
- // See https://github.com/docker/docker/pull/28002#discussion_r86259241 for rationale.
- panic("Failed to disabled process privileges while in non re-exec mode")
- }
- }()
- }
-
- w, err := hcsshim.NewLayerWriter(hcsshim.DriverInfo{Flavour: filterDriver, HomeDir: home}, id, parentLayerPaths)
- if err != nil {
- return 0, err
- }
-
- defer func() {
- if err := w.Close(); err != nil {
- // This error should not be discarded as a failure here
- // could result in an invalid layer on disk
- if retErr == nil {
- retErr = err
- }
+func writeLayer(layerData io.Reader, home string, id string, parentLayerPaths ...string) (size int64, _ error) {
+ err := winio.RunWithPrivileges([]string{winio.SeSecurityPrivilege, winio.SeBackupPrivilege, winio.SeRestorePrivilege}, func() error {
+ var err error
+ w, err := hcsshim.NewLayerWriter(hcsshim.DriverInfo{Flavour: filterDriver, HomeDir: home}, id, parentLayerPaths)
+ if err != nil {
+ return err
}
- }()
- return writeLayerFromTar(layerData, w, filepath.Join(home, id))
+ s, err := writeLayerFromTar(layerData, w, filepath.Join(home, id))
+ if err != nil {
+ // Close, but don't override the error from writeLayerFromTar
+ _ = w.Close()
+ return err
+ }
+
+ size = s
+ return w.Close()
+ })
+ return size, err
}
// resolveID computes the layerID information based on the given id.