Merge pull request #42352 from AkihiroSuda/cherrypick-41724

[20.10 backport] Use v2 capabilities in layer archives
diff --git a/integration/build/build_userns_linux_test.go b/integration/build/build_userns_linux_test.go
index f5b3a27..5c0bd54 100644
--- a/integration/build/build_userns_linux_test.go
+++ b/integration/build/build_userns_linux_test.go
@@ -118,15 +118,6 @@
 	_, err = stdcopy.StdCopy(actualStdout, actualStderr, logReader)
 	assert.NilError(t, err)
 	if strings.TrimSpace(actualStdout.String()) != "/bin/sleep cap_net_bind_service=eip" {
-		// Activate when fix is merged: https://github.com/moby/moby/pull/41724
-		//t.Fatalf("run produced invalid output: %q, expected %q", actualStdout.String(), "/bin/sleep cap_net_bind_service=eip")
-		// t.Logf("run produced invalid output (expected until #41724 merges): %q, expected %q",
-		// 	actualStdout.String(),
-		// 	"/bin/sleep cap_net_bind_service=eip")
-	} else {
-		// Shouldn't happen until fix is merged: https://github.com/moby/moby/pull/41724
-		t.Fatalf("run produced valid output (unexpected until #41724 merges): %q, expected %q",
-			actualStdout.String(),
-			"/bin/sleep cap_net_bind_service=eip")
+		t.Fatalf("run produced invalid output: %q, expected %q", actualStdout.String(), "/bin/sleep cap_net_bind_service=eip")
 	}
 }
diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go
index 8d14b78..50b83c6 100644
--- a/pkg/archive/archive.go
+++ b/pkg/archive/archive.go
@@ -402,10 +402,24 @@
 // ReadSecurityXattrToTarHeader reads security.capability xattr from filesystem
 // to a tar header
 func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {
+	const (
+		// Values based on linux/include/uapi/linux/capability.h
+		xattrCapsSz2    = 20
+		versionOffset   = 3
+		vfsCapRevision2 = 2
+		vfsCapRevision3 = 3
+	)
 	capability, _ := system.Lgetxattr(path, "security.capability")
 	if capability != nil {
+		length := len(capability)
+		if capability[versionOffset] == vfsCapRevision3 {
+			// Convert VFS_CAP_REVISION_3 to VFS_CAP_REVISION_2 as root UID makes no
+			// sense outside the user namespace the archive is built in.
+			capability[versionOffset] = vfsCapRevision2
+			length = xattrCapsSz2
+		}
 		hdr.Xattrs = make(map[string]string)
-		hdr.Xattrs["security.capability"] = string(capability)
+		hdr.Xattrs["security.capability"] = string(capability[:length])
 	}
 	return nil
 }