Vendor in latest github.com/containers/storage,image, buildah

Grab latest fixes from subpackages

Including fixes for usernamespace chowning retaining file attributes
Better logging of error messages.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2018-10-07 08:27:00 -04:00
parent 141a1327fb
commit 3a76772bb1
18 changed files with 289 additions and 96 deletions

View File

@ -10,8 +10,8 @@ github.com/containerd/cgroups 58556f5ad8448d99a6f7bea69ea4bdb7747cfeb0
github.com/containerd/continuity master github.com/containerd/continuity master
github.com/containernetworking/cni v0.7.0-alpha1 github.com/containernetworking/cni v0.7.0-alpha1
github.com/containernetworking/plugins 1562a1e60ed101aacc5e08ed9dbeba8e9f3d4ec1 github.com/containernetworking/plugins 1562a1e60ed101aacc5e08ed9dbeba8e9f3d4ec1
github.com/containers/image 8f11f3ad8912d8bc43a7d25992b8f313ffefd430 github.com/containers/image 7a1eac5d1df2dbd73d8b71853ebce32d989fcae3
github.com/containers/storage 68332c059156eae970a03245cfcd4d717fb66ecd github.com/containers/storage 41294c85d97bef688e18f710402895dbecde3308
github.com/containers/psgo 5dde6da0bc8831b35243a847625bcf18183bd1ee github.com/containers/psgo 5dde6da0bc8831b35243a847625bcf18183bd1ee
github.com/coreos/go-systemd v14 github.com/coreos/go-systemd v14
github.com/cri-o/ocicni master github.com/cri-o/ocicni master
@ -90,7 +90,7 @@ k8s.io/kube-openapi 275e2ce91dec4c05a4094a7b1daee5560b555ac9 https://github.com/
k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e https://github.com/kubernetes/utils k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e https://github.com/kubernetes/utils
github.com/mrunalp/fileutils master github.com/mrunalp/fileutils master
github.com/varlink/go master github.com/varlink/go master
github.com/containers/buildah cf87f0947ef719872816cc5d6a5ba4db1c261365 github.com/containers/buildah af8cb28f84d81ee1bca04c893142cd790b908c75
github.com/Nvveen/Gotty master github.com/Nvveen/Gotty master
github.com/fsouza/go-dockerclient master github.com/fsouza/go-dockerclient master
github.com/openshift/imagebuilder master github.com/openshift/imagebuilder master

View File

@ -17,6 +17,8 @@ The Buildah package provides a command line tool that can be used to
## Buildah Information for Developers ## Buildah Information for Developers
For blogs, release announcements and more, please checkout the [buildah.io](https://buildah.io) website!
**[Buildah Demos](demos)** **[Buildah Demos](demos)**
**[Changelog](CHANGELOG.md)** **[Changelog](CHANGELOG.md)**

View File

@ -24,7 +24,7 @@ const (
Package = "buildah" Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec // Version for the Package. Bump version in contrib/rpm/buildah.spec
// too. // too.
Version = "1.4-dev" Version = "1.5-dev"
// The value we use to identify what type of information, currently a // The value we use to identify what type of information, currently a
// serialized Builder structure, we are using as per-container state. // serialized Builder structure, we are using as per-container state.
// This should only be changed when we make incompatible changes to // This should only be changed when we make incompatible changes to

View File

@ -100,18 +100,6 @@ func RunUsingChroot(spec *specs.Spec, bundlePath string, stdin io.Reader, stdout
} }
logrus.Debugf("config = %v", string(specbytes)) logrus.Debugf("config = %v", string(specbytes))
// Run the grandparent subprocess in a user namespace that reuses the mappings that we have.
uidmap, gidmap, err := util.GetHostIDMappings("")
if err != nil {
return err
}
for i := range uidmap {
uidmap[i].HostID = uidmap[i].ContainerID
}
for i := range gidmap {
gidmap[i].HostID = gidmap[i].ContainerID
}
// Default to using stdin/stdout/stderr if we weren't passed objects to use. // Default to using stdin/stdout/stderr if we weren't passed objects to use.
if stdin == nil { if stdin == nil {
stdin = os.Stdin stdin = os.Stdin
@ -162,10 +150,6 @@ func RunUsingChroot(spec *specs.Spec, bundlePath string, stdin io.Reader, stdout
cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, stdout, stderr cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, stdout, stderr
cmd.Dir = "/" cmd.Dir = "/"
cmd.Env = append([]string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}, os.Environ()...) cmd.Env = append([]string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}, os.Environ()...)
cmd.UnshareFlags = syscall.CLONE_NEWUSER
cmd.UidMappings = uidmap
cmd.GidMappings = gidmap
cmd.GidMappingsEnableSetgroups = true
logrus.Debugf("Running %#v in %#v", cmd.Cmd, cmd) logrus.Debugf("Running %#v in %#v", cmd.Cmd, cmd)
confwg.Add(1) confwg.Add(1)
@ -568,10 +552,19 @@ func runUsingChroot(spec *specs.Spec, bundlePath string, ctty *os.File, stdin io
cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, stdout, stderr cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, stdout, stderr
cmd.Dir = "/" cmd.Dir = "/"
cmd.Env = append([]string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}, os.Environ()...) cmd.Env = append([]string{fmt.Sprintf("LOGLEVEL=%d", logrus.GetLevel())}, os.Environ()...)
cmd.UnshareFlags = syscall.CLONE_NEWUSER | syscall.CLONE_NEWUTS | syscall.CLONE_NEWNS cmd.UnshareFlags = syscall.CLONE_NEWUTS | syscall.CLONE_NEWNS
requestedUserNS := false
for _, ns := range spec.Linux.Namespaces {
if ns.Type == specs.LinuxNamespaceType(specs.UserNamespace) {
requestedUserNS = true
}
}
if len(spec.Linux.UIDMappings) > 0 || len(spec.Linux.GIDMappings) > 0 || requestedUserNS {
cmd.UnshareFlags = cmd.UnshareFlags | syscall.CLONE_NEWUSER
cmd.UidMappings = uidmap cmd.UidMappings = uidmap
cmd.GidMappings = gidmap cmd.GidMappings = gidmap
cmd.GidMappingsEnableSetgroups = true cmd.GidMappingsEnableSetgroups = true
}
if ctty != nil { if ctty != nil {
cmd.Setsid = true cmd.Setsid = true
cmd.Ctty = ctty cmd.Ctty = ctty
@ -697,15 +690,7 @@ func runUsingChrootExecMain() {
fmt.Fprintf(os.Stderr, "error setting SELinux label for process: %v\n", err) fmt.Fprintf(os.Stderr, "error setting SELinux label for process: %v\n", err)
os.Exit(1) os.Exit(1)
} }
logrus.Debugf("setting capabilities")
if err := setCapabilities(options.Spec); err != nil {
fmt.Fprintf(os.Stderr, "error setting capabilities for process %v\n", err)
os.Exit(1)
}
if err = setSeccomp(options.Spec); err != nil {
fmt.Fprintf(os.Stderr, "error setting seccomp filter for process: %v\n", err)
os.Exit(1)
}
logrus.Debugf("setting resource limits") logrus.Debugf("setting resource limits")
if err = setRlimits(options.Spec, false, false); err != nil { if err = setRlimits(options.Spec, false, false); err != nil {
fmt.Fprintf(os.Stderr, "error setting process resource limits for process: %v\n", err) fmt.Fprintf(os.Stderr, "error setting process resource limits for process: %v\n", err)
@ -747,11 +732,28 @@ func runUsingChrootExecMain() {
os.Exit(1) os.Exit(1)
} }
} }
logrus.Debugf("setting gid") logrus.Debugf("setting gid")
if err = syscall.Setresgid(int(user.GID), int(user.GID), int(user.GID)); err != nil { if err = syscall.Setresgid(int(user.GID), int(user.GID), int(user.GID)); err != nil {
fmt.Fprintf(os.Stderr, "error setting GID: %v", err) fmt.Fprintf(os.Stderr, "error setting GID: %v", err)
os.Exit(1) os.Exit(1)
} }
if err = setSeccomp(options.Spec); err != nil {
fmt.Fprintf(os.Stderr, "error setting seccomp filter for process: %v\n", err)
os.Exit(1)
}
logrus.Debugf("setting capabilities")
var keepCaps []string
if user.UID != 0 {
keepCaps = []string{"CAP_SETUID"}
}
if err := setCapabilities(options.Spec, keepCaps...); err != nil {
fmt.Fprintf(os.Stderr, "error setting capabilities for process: %v\n", err)
os.Exit(1)
}
logrus.Debugf("setting uid") logrus.Debugf("setting uid")
if err = syscall.Setresuid(int(user.UID), int(user.UID), int(user.UID)); err != nil { if err = syscall.Setresuid(int(user.UID), int(user.UID), int(user.UID)); err != nil {
fmt.Fprintf(os.Stderr, "error setting UID: %v", err) fmt.Fprintf(os.Stderr, "error setting UID: %v", err)
@ -855,7 +857,11 @@ func setApparmorProfile(spec *specs.Spec) error {
} }
// setCapabilities sets capabilities for ourselves, to be more or less inherited by any processes that we'll start. // setCapabilities sets capabilities for ourselves, to be more or less inherited by any processes that we'll start.
func setCapabilities(spec *specs.Spec) error { func setCapabilities(spec *specs.Spec, keepCaps ...string) error {
currentCaps, err := capability.NewPid(0)
if err != nil {
return errors.Wrapf(err, "error reading capabilities of current process")
}
caps, err := capability.NewPid(0) caps, err := capability.NewPid(0)
if err != nil { if err != nil {
return errors.Wrapf(err, "error reading capabilities of current process") return errors.Wrapf(err, "error reading capabilities of current process")
@ -868,8 +874,8 @@ func setCapabilities(spec *specs.Spec) error {
capability.AMBIENT: spec.Process.Capabilities.Ambient, capability.AMBIENT: spec.Process.Capabilities.Ambient,
} }
knownCaps := capability.List() knownCaps := capability.List()
caps.Clear(capability.CAPS | capability.BOUNDS | capability.AMBS)
for capType, capList := range capMap { for capType, capList := range capMap {
caps.Clear(capType)
for _, capToSet := range capList { for _, capToSet := range capList {
cap := capability.CAP_LAST_CAP cap := capability.CAP_LAST_CAP
for _, c := range knownCaps { for _, c := range knownCaps {
@ -883,11 +889,24 @@ func setCapabilities(spec *specs.Spec) error {
} }
caps.Set(capType, cap) caps.Set(capType, cap)
} }
for _, capToSet := range keepCaps {
cap := capability.CAP_LAST_CAP
for _, c := range knownCaps {
if strings.EqualFold("CAP_"+c.String(), capToSet) {
cap = c
break
} }
for capType := range capMap {
if err = caps.Apply(capType); err != nil {
return errors.Wrapf(err, "error setting %s capabilities to %#v", capType.String(), capMap[capType])
} }
if cap == capability.CAP_LAST_CAP {
return errors.Errorf("error mapping capability %q to a number", capToSet)
}
if currentCaps.Get(capType, cap) {
caps.Set(capType, cap)
}
}
}
if err = caps.Apply(capability.CAPS | capability.BOUNDS | capability.AMBS); err != nil {
return errors.Wrapf(err, "error setting capabilities")
} }
return nil return nil
} }

View File

@ -92,6 +92,15 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
var imgID string var imgID string
systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath)
blocked, err := isReferenceBlocked(dest, systemContext)
if err != nil {
return "", errors.Wrapf(err, "error checking if committing to registry for %q is blocked", transports.ImageName(dest))
}
if blocked {
return "", errors.Errorf("commit access to registry for %q is blocked by configuration", transports.ImageName(dest))
}
policy, err := signature.DefaultPolicy(systemContext) policy, err := signature.DefaultPolicy(systemContext)
if err != nil { if err != nil {
return imgID, errors.Wrapf(err, "error obtaining default signature policy") return imgID, errors.Wrapf(err, "error obtaining default signature policy")
@ -120,7 +129,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
return imgID, errors.Wrapf(err, "error computing layer digests and building metadata") return imgID, errors.Wrapf(err, "error computing layer digests and building metadata")
} }
// "Copy" our image to where it needs to be. // "Copy" our image to where it needs to be.
err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, nil, systemContext, "")) err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, src, nil, dest, systemContext, ""))
if err != nil { if err != nil {
return imgID, errors.Wrapf(err, "error copying layers and metadata") return imgID, errors.Wrapf(err, "error copying layers and metadata")
} }
@ -162,6 +171,15 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
// Push copies the contents of the image to a new location. // Push copies the contents of the image to a new location.
func Push(ctx context.Context, image string, dest types.ImageReference, options PushOptions) error { func Push(ctx context.Context, image string, dest types.ImageReference, options PushOptions) error {
systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath)
blocked, err := isReferenceBlocked(dest, systemContext)
if err != nil {
return errors.Wrapf(err, "error checking if pushing to registry for %q is blocked", transports.ImageName(dest))
}
if blocked {
return errors.Errorf("push access to registry for %q is blocked by configuration", transports.ImageName(dest))
}
policy, err := signature.DefaultPolicy(systemContext) policy, err := signature.DefaultPolicy(systemContext)
if err != nil { if err != nil {
return errors.Wrapf(err, "error obtaining default signature policy") return errors.Wrapf(err, "error obtaining default signature policy")
@ -176,7 +194,7 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options
return err return err
} }
// Copy everything. // Copy everything.
err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, nil, systemContext, options.ManifestType)) err = cp.Image(ctx, policyContext, dest, src, getCopyOptions(options.ReportWriter, src, nil, dest, systemContext, options.ManifestType))
if err != nil { if err != nil {
return errors.Wrapf(err, "error copying layers and metadata") return errors.Wrapf(err, "error copying layers and metadata")
} }

View File

@ -3,7 +3,10 @@ package buildah
import ( import (
"io" "io"
"github.com/sirupsen/logrus"
cp "github.com/containers/image/copy" cp "github.com/containers/image/copy"
"github.com/containers/image/transports"
"github.com/containers/image/types" "github.com/containers/image/types"
) )
@ -14,11 +17,35 @@ const (
DOCKER = "docker" DOCKER = "docker"
) )
func getCopyOptions(reportWriter io.Writer, sourceSystemContext *types.SystemContext, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options { func getCopyOptions(reportWriter io.Writer, sourceReference types.ImageReference, sourceSystemContext *types.SystemContext, destinationReference types.ImageReference, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options {
sourceCtx := &types.SystemContext{}
if sourceSystemContext != nil {
*sourceCtx = *sourceSystemContext
}
sourceInsecure, err := isReferenceInsecure(sourceReference, sourceCtx)
if err != nil {
logrus.Debugf("error determining if registry for %q is insecure: %v", transports.ImageName(sourceReference), err)
} else if sourceInsecure {
sourceCtx.DockerInsecureSkipTLSVerify = true
sourceCtx.OCIInsecureSkipTLSVerify = true
}
destinationCtx := &types.SystemContext{}
if destinationSystemContext != nil {
*destinationCtx = *destinationSystemContext
}
destinationInsecure, err := isReferenceInsecure(destinationReference, destinationCtx)
if err != nil {
logrus.Debugf("error determining if registry for %q is insecure: %v", transports.ImageName(destinationReference), err)
} else if destinationInsecure {
destinationCtx.DockerInsecureSkipTLSVerify = true
destinationCtx.OCIInsecureSkipTLSVerify = true
}
return &cp.Options{ return &cp.Options{
ReportWriter: reportWriter, ReportWriter: reportWriter,
SourceCtx: sourceSystemContext, SourceCtx: sourceCtx,
DestinationCtx: destinationSystemContext, DestinationCtx: destinationCtx,
ForceManifestMIMEType: manifestType, ForceManifestMIMEType: manifestType,
} }
} }

View File

@ -325,6 +325,9 @@ func (b *Executor) Preserve(path string) error {
archivedPath := filepath.Join(b.mountPoint, cachedPath) archivedPath := filepath.Join(b.mountPoint, cachedPath)
logrus.Debugf("no longer need cache of %q in %q", archivedPath, b.volumeCache[cachedPath]) logrus.Debugf("no longer need cache of %q in %q", archivedPath, b.volumeCache[cachedPath])
if err := os.Remove(b.volumeCache[cachedPath]); err != nil { if err := os.Remove(b.volumeCache[cachedPath]); err != nil {
if os.IsNotExist(err) {
continue
}
return errors.Wrapf(err, "error removing %q", b.volumeCache[cachedPath]) return errors.Wrapf(err, "error removing %q", b.volumeCache[cachedPath])
} }
delete(b.volumeCache, cachedPath) delete(b.volumeCache, cachedPath)
@ -343,6 +346,9 @@ func (b *Executor) volumeCacheInvalidate(path string) error {
} }
for _, cachedPath := range invalidated { for _, cachedPath := range invalidated {
if err := os.Remove(b.volumeCache[cachedPath]); err != nil { if err := os.Remove(b.volumeCache[cachedPath]); err != nil {
if os.IsNotExist(err) {
continue
}
return errors.Wrapf(err, "error removing volume cache %q", b.volumeCache[cachedPath]) return errors.Wrapf(err, "error removing volume cache %q", b.volumeCache[cachedPath])
} }
archivedPath := filepath.Join(b.mountPoint, cachedPath) archivedPath := filepath.Join(b.mountPoint, cachedPath)
@ -1125,6 +1131,7 @@ func (b *Executor) Commit(ctx context.Context, ib *imagebuilder.Builder, created
AdditionalTags: b.additionalTags, AdditionalTags: b.additionalTags,
ReportWriter: writer, ReportWriter: writer,
PreferredManifestType: b.outputFormat, PreferredManifestType: b.outputFormat,
SystemContext: b.systemContext,
IIDFile: b.iidfile, IIDFile: b.iidfile,
Squash: b.squash, Squash: b.squash,
Parent: b.builder.FromImageID, Parent: b.builder.FromImageID,

View File

@ -3,7 +3,6 @@ package buildah
import ( import (
"context" "context"
"fmt" "fmt"
"os"
"strings" "strings"
"github.com/containers/buildah/util" "github.com/containers/buildah/util"
@ -14,7 +13,6 @@ import (
"github.com/containers/image/types" "github.com/containers/image/types"
"github.com/containers/storage" "github.com/containers/storage"
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"
"github.com/opencontainers/selinux/go-selinux"
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
"github.com/openshift/imagebuilder" "github.com/openshift/imagebuilder"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -36,36 +34,6 @@ const (
minimumTruncatedIDLength = 3 minimumTruncatedIDLength = 3
) )
func reserveSELinuxLabels(store storage.Store, id string) error {
if selinux.GetEnabled() {
containers, err := store.Containers()
if err != nil {
return err
}
for _, c := range containers {
if id == c.ID {
continue
} else {
b, err := OpenBuilder(store, c.ID)
if err != nil {
if os.IsNotExist(err) {
// Ignore not exist errors since containers probably created by other tool
// TODO, we need to read other containers json data to reserve their SELinux labels
continue
}
return err
}
// Prevent different containers from using same MCS label
if err := label.ReserveLabel(b.ProcessLabel); err != nil {
return err
}
}
}
}
return nil
}
func pullAndFindImage(ctx context.Context, store storage.Store, imageName string, options BuilderOptions, sc *types.SystemContext) (*storage.Image, types.ImageReference, error) { func pullAndFindImage(ctx context.Context, store storage.Store, imageName string, options BuilderOptions, sc *types.SystemContext) (*storage.Image, types.ImageReference, error) {
pullOptions := PullOptions{ pullOptions := PullOptions{
ReportWriter: options.ReportWriter, ReportWriter: options.ReportWriter,
@ -303,7 +271,7 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions
} }
}() }()
if err = reserveSELinuxLabels(store, container.ID); err != nil { if err = ReserveSELinuxLabels(store, container.ID); err != nil {
return nil, err return nil, err
} }
processLabel, mountLabel, err := label.InitLabels(options.CommonBuildOpts.LabelOpts) processLabel, mountLabel, err := label.InitLabels(options.CommonBuildOpts.LabelOpts)

View File

@ -128,11 +128,6 @@ var (
Name: "iidfile", Name: "iidfile",
Usage: "`file` to write the image ID to", Usage: "`file` to write the image ID to",
}, },
cli.StringFlag{
Name: "isolation",
Usage: "`type` of process isolation to use. Use BUILDAH_ISOLATION environment variable to override.",
Value: DefaultIsolation(),
},
cli.StringSliceFlag{ cli.StringSliceFlag{
Name: "label", Name: "label",
Usage: "Set metadata for an image (default [])", Usage: "Set metadata for an image (default [])",
@ -229,6 +224,11 @@ var (
Name: "cpuset-mems", Name: "cpuset-mems",
Usage: "memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.", Usage: "memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.",
}, },
cli.StringFlag{
Name: "isolation",
Usage: "`type` of process isolation to use. Use BUILDAH_ISOLATION environment variable to override.",
Value: DefaultIsolation(),
},
cli.StringFlag{ cli.StringFlag{
Name: "memory, m", Name: "memory, m",
Usage: "memory limit (format: <number>[<unit>], where unit = b, k, m or g)", Usage: "memory limit (format: <number>[<unit>], where unit = b, k, m or g)",

View File

@ -283,6 +283,8 @@ func SystemContextFromOptions(c *cli.Context) (*types.SystemContext, error) {
} }
if c.IsSet("tls-verify") { if c.IsSet("tls-verify") {
ctx.DockerInsecureSkipTLSVerify = !c.BoolT("tls-verify") ctx.DockerInsecureSkipTLSVerify = !c.BoolT("tls-verify")
ctx.OCIInsecureSkipTLSVerify = !c.BoolT("tls-verify")
ctx.DockerDaemonInsecureSkipTLSVerify = !c.BoolT("tls-verify")
} }
if c.IsSet("creds") { if c.IsSet("creds") {
var err error var err error

View File

@ -160,6 +160,14 @@ func pullImage(ctx context.Context, store storage.Store, imageName string, optio
srcRef = srcRef2 srcRef = srcRef2
} }
blocked, err := isReferenceBlocked(srcRef, sc)
if err != nil {
return nil, errors.Wrapf(err, "error checking if pulling from registry for %q is blocked", transports.ImageName(srcRef))
}
if blocked {
return nil, errors.Errorf("pull access to registry for %q is blocked by configuration", transports.ImageName(srcRef))
}
destName, err := localImageNameForReference(ctx, store, srcRef, spec) destName, err := localImageNameForReference(ctx, store, srcRef, spec)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error computing local image name for %q", transports.ImageName(srcRef)) return nil, errors.Wrapf(err, "error computing local image name for %q", transports.ImageName(srcRef))
@ -190,7 +198,7 @@ func pullImage(ctx context.Context, store storage.Store, imageName string, optio
}() }()
logrus.Debugf("copying %q to %q", spec, destName) logrus.Debugf("copying %q to %q", spec, destName)
pullError := cp.Image(ctx, policyContext, destRef, srcRef, getCopyOptions(options.ReportWriter, sc, nil, "")) pullError := cp.Image(ctx, policyContext, destRef, srcRef, getCopyOptions(options.ReportWriter, srcRef, sc, destRef, nil, ""))
if pullError == nil { if pullError == nil {
return destRef, nil return destRef, nil
} }

View File

@ -11,6 +11,8 @@
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
const char *_max_user_namespaces = "/proc/sys/user/max_user_namespaces";
static int _buildah_unshare_parse_envint(const char *envname) { static int _buildah_unshare_parse_envint(const char *envname) {
char *p, *q; char *p, *q;
long l; long l;
@ -31,7 +33,10 @@ static int _buildah_unshare_parse_envint(const char *envname) {
void _buildah_unshare(void) void _buildah_unshare(void)
{ {
FILE *fp;
int flags, pidfd, continuefd, n, pgrp, sid, ctty; int flags, pidfd, continuefd, n, pgrp, sid, ctty;
long max_userns;
size_t n_read;
char buf[2048]; char buf[2048];
flags = _buildah_unshare_parse_envint("_Buildah-unshare"); flags = _buildah_unshare_parse_envint("_Buildah-unshare");
@ -41,6 +46,22 @@ void _buildah_unshare(void)
if ((flags & CLONE_NEWUSER) != 0) { if ((flags & CLONE_NEWUSER) != 0) {
if (unshare(CLONE_NEWUSER) == -1) { if (unshare(CLONE_NEWUSER) == -1) {
fprintf(stderr, "Error during unshare(CLONE_NEWUSER): %m\n"); fprintf(stderr, "Error during unshare(CLONE_NEWUSER): %m\n");
fp = fopen(_max_user_namespaces, "r");
if (fp != NULL) {
memset(buf, 0, sizeof(buf));
n_read = fread(buf, 1, sizeof(buf) - 1, fp);
if (n_read > 0) {
max_userns = atoi(buf);
if (max_userns == 0) {
fprintf(stderr, "User namespaces are not enabled in %s.\n", _max_user_namespaces);
}
} else {
fprintf(stderr, "Error reading %s: no contents, should contain a number greater than 0.\n", _max_user_namespaces);
}
fclose(fp);
} else {
fprintf(stderr, "Error reading %s: %m\n", _max_user_namespaces);
}
_exit(1); _exit(1);
} }
} }

View File

@ -191,8 +191,8 @@ func (c *Cmd) Start() error {
} }
defer gidmap.Close() defer gidmap.Close()
if _, err := fmt.Fprintf(gidmap, "%s", g.String()); err != nil { if _, err := fmt.Fprintf(gidmap, "%s", g.String()); err != nil {
fmt.Fprintf(continueWrite, "error writing /proc/%s/gid_map: %v", pidString, err) fmt.Fprintf(continueWrite, "error writing %q to /proc/%s/gid_map: %v", g.String(), pidString, err)
return errors.Wrapf(err, "error writing /proc/%s/gid_map", pidString) return errors.Wrapf(err, "error writing %q to /proc/%s/gid_map", g.String(), pidString)
} }
} }
} }
@ -222,8 +222,8 @@ func (c *Cmd) Start() error {
} }
defer uidmap.Close() defer uidmap.Close()
if _, err := fmt.Fprintf(uidmap, "%s", u.String()); err != nil { if _, err := fmt.Fprintf(uidmap, "%s", u.String()); err != nil {
fmt.Fprintf(continueWrite, "error writing /proc/%s/uid_map: %v", pidString, err) fmt.Fprintf(continueWrite, "error writing %q to /proc/%s/uid_map: %v", u.String(), pidString, err)
return errors.Wrapf(err, "error writing /proc/%s/uid_map", pidString) return errors.Wrapf(err, "error writing %q to /proc/%s/uid_map", u.String(), pidString)
} }
} }
} }

View File

@ -7,14 +7,19 @@ import (
"sync" "sync"
"github.com/containers/image/docker/reference" "github.com/containers/image/docker/reference"
"github.com/containers/image/pkg/sysregistries"
"github.com/containers/image/pkg/sysregistriesv2" "github.com/containers/image/pkg/sysregistriesv2"
"github.com/containers/image/types" "github.com/containers/image/types"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive" "github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/reexec" "github.com/containers/storage/pkg/reexec"
rspec "github.com/opencontainers/runtime-spec/specs-go" rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus"
) )
// InitReexec is a wrapper for reexec.Init(). It should be called at // InitReexec is a wrapper for reexec.Init(). It should be called at
@ -181,6 +186,70 @@ func getRegistries(sc *types.SystemContext) ([]string, error) {
return searchRegistries, nil return searchRegistries, nil
} }
// isRegistryInsecure checks if the named registry is marked as not secure
func isRegistryInsecure(registry string, sc *types.SystemContext) (bool, error) {
registries, err := sysregistriesv2.GetRegistries(sc)
if err != nil {
return false, errors.Wrapf(err, "unable to parse the registries configuration (%s)", sysregistries.RegistriesConfPath(sc))
}
if reginfo := sysregistriesv2.FindRegistry(registry, registries); reginfo != nil {
if reginfo.Insecure {
logrus.Debugf("registry %q is marked insecure in registries configuration %q", registry, sysregistries.RegistriesConfPath(sc))
} else {
logrus.Debugf("registry %q is not marked insecure in registries configuration %q", registry, sysregistries.RegistriesConfPath(sc))
}
return reginfo.Insecure, nil
}
logrus.Debugf("registry %q is not listed in registries configuration %q, assuming it's secure", registry, sysregistries.RegistriesConfPath(sc))
return false, nil
}
// isRegistryBlocked checks if the named registry is marked as blocked
func isRegistryBlocked(registry string, sc *types.SystemContext) (bool, error) {
registries, err := sysregistriesv2.GetRegistries(sc)
if err != nil {
return false, errors.Wrapf(err, "unable to parse the registries configuration (%s)", sysregistries.RegistriesConfPath(sc))
}
if reginfo := sysregistriesv2.FindRegistry(registry, registries); reginfo != nil {
if reginfo.Blocked {
logrus.Debugf("registry %q is marked as blocked in registries configuration %q", registry, sysregistries.RegistriesConfPath(sc))
} else {
logrus.Debugf("registry %q is not marked as blocked in registries configuration %q", registry, sysregistries.RegistriesConfPath(sc))
}
return reginfo.Blocked, nil
}
logrus.Debugf("registry %q is not listed in registries configuration %q, assuming it's not blocked", registry, sysregistries.RegistriesConfPath(sc))
return false, nil
}
// isReferenceSomething checks if the registry part of a reference is insecure or blocked
func isReferenceSomething(ref types.ImageReference, sc *types.SystemContext, what func(string, *types.SystemContext) (bool, error)) (bool, error) {
if ref != nil && ref.DockerReference() != nil {
if named, ok := ref.DockerReference().(reference.Named); ok {
if domain := reference.Domain(named); domain != "" {
return what(domain, sc)
}
}
}
return false, nil
}
// isReferenceInsecure checks if the registry part of a reference is insecure
func isReferenceInsecure(ref types.ImageReference, sc *types.SystemContext) (bool, error) {
return isReferenceSomething(ref, sc, isRegistryInsecure)
}
// isReferenceBlocked checks if the registry part of a reference is blocked
func isReferenceBlocked(ref types.ImageReference, sc *types.SystemContext) (bool, error) {
if ref != nil && ref.Transport() != nil {
switch ref.Transport().Name() {
case "docker":
return isReferenceSomething(ref, sc, isRegistryBlocked)
}
}
return false, nil
}
// hasRegistry returns a bool/err response if the image has a registry in its // hasRegistry returns a bool/err response if the image has a registry in its
// name // name
func hasRegistry(imageName string) (bool, error) { func hasRegistry(imageName string) (bool, error) {
@ -194,3 +263,35 @@ func hasRegistry(imageName string) (bool, error) {
} }
return false, nil return false, nil
} }
// ReserveSELinuxLabels reads containers storage and reserves SELinux containers
// fall all existing buildah containers
func ReserveSELinuxLabels(store storage.Store, id string) error {
if selinux.GetEnabled() {
containers, err := store.Containers()
if err != nil {
return err
}
for _, c := range containers {
if id == c.ID {
continue
} else {
b, err := OpenBuilder(store, c.ID)
if err != nil {
if os.IsNotExist(err) {
// Ignore not exist errors since containers probably created by other tool
// TODO, we need to read other containers json data to reserve their SELinux labels
continue
}
return err
}
// Prevent different containers from using same MCS label
if err := label.ReserveLabel(b.ProcessLabel); err != nil {
return err
}
}
}
}
return nil
}

View File

@ -3,9 +3,9 @@ github.com/blang/semver master
github.com/BurntSushi/toml master github.com/BurntSushi/toml master
github.com/containerd/continuity master github.com/containerd/continuity master
github.com/containernetworking/cni v0.7.0-alpha1 github.com/containernetworking/cni v0.7.0-alpha1
github.com/containers/image 8f11f3ad8912d8bc43a7d25992b8f313ffefd430 github.com/containers/image 5cc7850824afe2b4fb016f8906666b358c50dc31
github.com/containers/libpod 2afadeec6696fefac468a49c8ba24b0bc275aa75 github.com/containers/libpod 2afadeec6696fefac468a49c8ba24b0bc275aa75
github.com/containers/storage 68332c059156eae970a03245cfcd4d717fb66ecd github.com/containers/storage 41294c85d97bef688e18f710402895dbecde3308
github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716 github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00 github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1 github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1

View File

@ -516,7 +516,7 @@ func (c *dockerClient) detectProperties(ctx context.Context) error {
url := fmt.Sprintf(resolvedPingV2URL, scheme, c.registry) url := fmt.Sprintf(resolvedPingV2URL, scheme, c.registry)
resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, noAuth) resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, noAuth)
if err != nil { if err != nil {
logrus.Debugf("Ping %s err %#v", url, err) logrus.Debugf("Ping %s err %s (%#v)", url, err.Error(), err)
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
@ -542,7 +542,7 @@ func (c *dockerClient) detectProperties(ctx context.Context) error {
pingV1 := func(scheme string) bool { pingV1 := func(scheme string) bool {
url := fmt.Sprintf(resolvedPingV1URL, scheme, c.registry) url := fmt.Sprintf(resolvedPingV1URL, scheme, c.registry)
resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, noAuth) resp, err := c.makeRequestToResolvedURL(ctx, "GET", url, nil, nil, -1, noAuth)
logrus.Debugf("Ping %s err %#v", url, err) logrus.Debugf("Ping %s err %s (%#v)", url, err.Error(), err)
if err != nil { if err != nil {
return false return false
} }

View File

@ -34,6 +34,19 @@ func SetupCertificates(dir string, tlsc *tls.Config) error {
for _, f := range fs { for _, f := range fs {
fullPath := filepath.Join(dir, f.Name()) fullPath := filepath.Join(dir, f.Name())
if strings.HasSuffix(f.Name(), ".crt") { if strings.HasSuffix(f.Name(), ".crt") {
logrus.Debugf(" crt: %s", fullPath)
data, err := ioutil.ReadFile(fullPath)
if err != nil {
if os.IsNotExist(err) {
// Dangling symbolic link?
// Race with someone who deleted the
// file after we read the directory's
// list of contents?
logrus.Warnf("error reading certificate %q: %v", fullPath, err)
continue
}
return err
}
if tlsc.RootCAs == nil { if tlsc.RootCAs == nil {
systemPool, err := tlsconfig.SystemCertPool() systemPool, err := tlsconfig.SystemCertPool()
if err != nil { if err != nil {
@ -41,11 +54,6 @@ func SetupCertificates(dir string, tlsc *tls.Config) error {
} }
tlsc.RootCAs = systemPool tlsc.RootCAs = systemPool
} }
logrus.Debugf(" crt: %s", fullPath)
data, err := ioutil.ReadFile(fullPath)
if err != nil {
return err
}
tlsc.RootCAs.AppendCertsFromPEM(data) tlsc.RootCAs.AppendCertsFromPEM(data)
} }
if strings.HasSuffix(f.Name(), ".cert") { if strings.HasSuffix(f.Name(), ".cert") {

View File

@ -8,6 +8,7 @@ import (
"syscall" "syscall"
"github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system"
) )
func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools.IDMappings) error { func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools.IDMappings) error {
@ -49,6 +50,11 @@ func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools.
if err != nil { if err != nil {
return fmt.Errorf("%s: lstat(%q): %v", os.Args[0], path, err) return fmt.Errorf("%s: lstat(%q): %v", os.Args[0], path, err)
} }
cap, err := system.Lgetxattr(path, "security.capability")
if err != nil && err != system.ErrNotSupportedPlatform {
return fmt.Errorf("%s: Lgetxattr(%q): %v", os.Args[0], path, err)
}
// Make the change. // Make the change.
if err := syscall.Lchown(path, uid, gid); err != nil { if err := syscall.Lchown(path, uid, gid); err != nil {
return fmt.Errorf("%s: chown(%q): %v", os.Args[0], path, err) return fmt.Errorf("%s: chown(%q): %v", os.Args[0], path, err)
@ -59,6 +65,12 @@ func platformLChown(path string, info os.FileInfo, toHost, toContainer *idtools.
return fmt.Errorf("%s: chmod(%q): %v", os.Args[0], path, err) return fmt.Errorf("%s: chmod(%q): %v", os.Args[0], path, err)
} }
} }
if cap != nil {
if err := system.Lsetxattr(path, "security.capability", cap, 0); err != nil {
return fmt.Errorf("%s: Lsetxattr(%q): %v", os.Args[0], path, err)
}
}
} }
} }
return nil return nil