Jelajahi Sumber

archive: Fix the storing of setuid bits, etc

In commit 3dfc910d7774d57c533b067fbe59d6b24dd803cd we changed from
syscall.Chmod() to os.Chmod(), but these take a different form of the
Mode argument. The sycall one takes the raw linux form, wheras
os.Chmod takes the os.FileMode form, and they differ for the higher
bits (setuid, setgid, etc). The raw tar header uses a form which
is compatible with the syscalls, but not the go calls.

We fix this by using hdr.FileInfo() which properly converts the mode
to what go expects.

Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
Alexander Larsson 11 tahun lalu
induk
melakukan
5ba2462961
1 mengubah file dengan 8 tambahan dan 3 penghapusan
  1. 8 3
      archive/archive.go

+ 8 - 3
archive/archive.go

@@ -187,19 +187,24 @@ func addTarFile(path, name string, tw *tar.Writer) error {
 }
 }
 
 
 func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader) error {
 func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader) error {
+	// hdr.Mode is in linux format, which we can use for sycalls,
+	// but for os.Foo() calls we need the mode converted to os.FileMode,
+	// so use hdrInfo.Mode() (they differ for e.g. setuid bits)
+	hdrInfo := hdr.FileInfo()
+
 	switch hdr.Typeflag {
 	switch hdr.Typeflag {
 	case tar.TypeDir:
 	case tar.TypeDir:
 		// Create directory unless it exists as a directory already.
 		// Create directory unless it exists as a directory already.
 		// In that case we just want to merge the two
 		// In that case we just want to merge the two
 		if fi, err := os.Lstat(path); !(err == nil && fi.IsDir()) {
 		if fi, err := os.Lstat(path); !(err == nil && fi.IsDir()) {
-			if err := os.Mkdir(path, os.FileMode(hdr.Mode)); err != nil {
+			if err := os.Mkdir(path, hdrInfo.Mode()); err != nil {
 				return err
 				return err
 			}
 			}
 		}
 		}
 
 
 	case tar.TypeReg, tar.TypeRegA:
 	case tar.TypeReg, tar.TypeRegA:
 		// Source is regular file
 		// Source is regular file
-		file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, os.FileMode(hdr.Mode))
+		file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, hdrInfo.Mode())
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
@@ -249,7 +254,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader) e
 	// There is no LChmod, so ignore mode for symlink. Also, this
 	// There is no LChmod, so ignore mode for symlink. Also, this
 	// must happen after chown, as that can modify the file mode
 	// must happen after chown, as that can modify the file mode
 	if hdr.Typeflag != tar.TypeSymlink {
 	if hdr.Typeflag != tar.TypeSymlink {
-		if err := os.Chmod(path, os.FileMode(hdr.Mode&07777)); err != nil {
+		if err := os.Chmod(path, hdrInfo.Mode()); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}