Use v2 capabilities in layer archives
When building images in a user-namespaced container, v3 capabilities are
stored including the root UID of the creator of the user-namespace.
This UID does not make sense outside the build environment however. If
the image is run in a non-user-namespaced runtime, or if a user-namespaced
runtime uses a different UID, the capabilities requested by the effective
bit will not be honoured by `execve(2)` due to this mismatch.
Instead, we convert v3 capabilities to v2, dropping the root UID on the
fly.
Signed-off-by: Eric Mountain <eric.mountain@datadoghq.com>
(cherry picked from commit 95eb490780
)
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
parent
614a70a11b
commit
2a0c446866
|
@ -118,15 +118,6 @@ func TestBuildUserNamespaceValidateCapabilitiesAreV2(t *testing.T) {
|
|||
_, 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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -402,10 +402,24 @@ func fillGo18FileTypeBits(mode int64, fi os.FileInfo) int64 {
|
|||
// 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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue