mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #19579 from cyphar/hotfix-vendor-libcontainer
Hotfix vendor libcontainer
This commit is contained in:
commit
6d1455e74b
4 changed files with 111 additions and 1 deletions
|
@ -57,7 +57,7 @@ clone git github.com/miekg/pkcs11 80f102b5cac759de406949c47f0928b99bd64cdf
|
||||||
clone git github.com/jfrazelle/go v1.5.1-1
|
clone git github.com/jfrazelle/go v1.5.1-1
|
||||||
clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
|
clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
|
||||||
|
|
||||||
clone git github.com/opencontainers/runc 47e3f834d73e76bc2a6a585b48d2a93325b34979 # libcontainer
|
clone git github.com/opencontainers/runc f36b00aa12b3cb4e9c42506059fce4145cfbd626 # libcontainer
|
||||||
clone git github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1
|
clone git github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c226cfc6a1
|
||||||
# libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
|
# libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
|
||||||
clone git github.com/coreos/go-systemd v4
|
clone git github.com/coreos/go-systemd v4
|
||||||
|
|
|
@ -3466,6 +3466,84 @@ func (s *DockerSuite) TestRunContainerWithCgroupParentAbsPath(c *check.C) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestRunInvalidCgroupParent checks that a specially-crafted cgroup parent doesn't cause Docker to crash or start modifying /.
|
||||||
|
func (s *DockerSuite) TestRunInvalidCgroupParent(c *check.C) {
|
||||||
|
// Not applicable on Windows as uses Unix specific functionality
|
||||||
|
testRequires(c, DaemonIsLinux)
|
||||||
|
|
||||||
|
cgroupParent := "../../../../../../../../SHOULD_NOT_EXIST"
|
||||||
|
cleanCgroupParent := "SHOULD_NOT_EXIST"
|
||||||
|
name := "cgroup-invalid-test"
|
||||||
|
|
||||||
|
out, _, err := dockerCmdWithError("run", "--cgroup-parent", cgroupParent, "--name", name, "busybox", "cat", "/proc/self/cgroup")
|
||||||
|
if err != nil {
|
||||||
|
// XXX: This may include a daemon crash.
|
||||||
|
c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We expect "/SHOULD_NOT_EXIST" to not exist. If not, we have a security issue.
|
||||||
|
if _, err := os.Stat("/SHOULD_NOT_EXIST"); err == nil || !os.IsNotExist(err) {
|
||||||
|
c.Fatalf("SECURITY: --cgroup-parent with ../../ relative paths cause files to be created in the host (this is bad) !!")
|
||||||
|
}
|
||||||
|
|
||||||
|
cgroupPaths := parseCgroupPaths(string(out))
|
||||||
|
if len(cgroupPaths) == 0 {
|
||||||
|
c.Fatalf("unexpected output - %q", string(out))
|
||||||
|
}
|
||||||
|
id, err := getIDByName(name)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
expectedCgroup := path.Join(cleanCgroupParent, id)
|
||||||
|
found := false
|
||||||
|
for _, path := range cgroupPaths {
|
||||||
|
if strings.HasSuffix(path, expectedCgroup) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
c.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have suffix %q. Cgroup Paths: %v", expectedCgroup, cgroupPaths)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestRunInvalidCgroupParent checks that a specially-crafted cgroup parent doesn't cause Docker to crash or start modifying /.
|
||||||
|
func (s *DockerSuite) TestRunAbsoluteInvalidCgroupParent(c *check.C) {
|
||||||
|
// Not applicable on Windows as uses Unix specific functionality
|
||||||
|
testRequires(c, DaemonIsLinux)
|
||||||
|
|
||||||
|
cgroupParent := "/../../../../../../../../SHOULD_NOT_EXIST"
|
||||||
|
cleanCgroupParent := "/SHOULD_NOT_EXIST"
|
||||||
|
name := "cgroup-absolute-invalid-test"
|
||||||
|
|
||||||
|
out, _, err := dockerCmdWithError("run", "--cgroup-parent", cgroupParent, "--name", name, "busybox", "cat", "/proc/self/cgroup")
|
||||||
|
if err != nil {
|
||||||
|
// XXX: This may include a daemon crash.
|
||||||
|
c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We expect "/SHOULD_NOT_EXIST" to not exist. If not, we have a security issue.
|
||||||
|
if _, err := os.Stat("/SHOULD_NOT_EXIST"); err == nil || !os.IsNotExist(err) {
|
||||||
|
c.Fatalf("SECURITY: --cgroup-parent with /../../ garbage paths cause files to be created in the host (this is bad) !!")
|
||||||
|
}
|
||||||
|
|
||||||
|
cgroupPaths := parseCgroupPaths(string(out))
|
||||||
|
if len(cgroupPaths) == 0 {
|
||||||
|
c.Fatalf("unexpected output - %q", string(out))
|
||||||
|
}
|
||||||
|
id, err := getIDByName(name)
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
expectedCgroup := path.Join(cleanCgroupParent, id)
|
||||||
|
found := false
|
||||||
|
for _, path := range cgroupPaths {
|
||||||
|
if strings.HasSuffix(path, expectedCgroup) {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
c.Fatalf("unexpected cgroup paths. Expected at least one cgroup path to have suffix %q. Cgroup Paths: %v", expectedCgroup, cgroupPaths)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *DockerSuite) TestRunContainerWithCgroupMountRO(c *check.C) {
|
func (s *DockerSuite) TestRunContainerWithCgroupMountRO(c *check.C) {
|
||||||
// Not applicable on Windows as uses Unix specific functionality
|
// Not applicable on Windows as uses Unix specific functionality
|
||||||
// --read-only + userns has remount issues
|
// --read-only + userns has remount issues
|
||||||
|
|
|
@ -230,12 +230,39 @@ func (m *Manager) GetPids() ([]int, error) {
|
||||||
return cgroups.GetPids(dir)
|
return cgroups.GetPids(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pathClean makes a path safe for use with filepath.Join. This is done by not
|
||||||
|
// only cleaning the path, but also (if the path is relative) adding a leading
|
||||||
|
// '/' and cleaning it (then removing the leading '/'). This ensures that a
|
||||||
|
// path resulting from prepending another path will always resolve to lexically
|
||||||
|
// be a subdirectory of the prefixed path. This is all done lexically, so paths
|
||||||
|
// that include symlinks won't be safe as a result of using pathClean.
|
||||||
|
func pathClean(path string) string {
|
||||||
|
// Ensure that all paths are cleaned (especially problematic ones like
|
||||||
|
// "/../../../../../" which can cause lots of issues).
|
||||||
|
path = filepath.Clean(path)
|
||||||
|
|
||||||
|
// If the path isn't absolute, we need to do more processing to fix paths
|
||||||
|
// such as "../../../../<etc>/some/path". We also shouldn't convert absolute
|
||||||
|
// paths to relative ones.
|
||||||
|
if !filepath.IsAbs(path) {
|
||||||
|
path = filepath.Clean(string(os.PathSeparator) + path)
|
||||||
|
// This can't fail, as (by definition) all paths are relative to root.
|
||||||
|
path, _ = filepath.Rel(string(os.PathSeparator), path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean the path again for good measure.
|
||||||
|
return filepath.Clean(path)
|
||||||
|
}
|
||||||
|
|
||||||
func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
|
func getCgroupData(c *configs.Cgroup, pid int) (*cgroupData, error) {
|
||||||
root, err := getCgroupRoot()
|
root, err := getCgroupRoot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean the parent slice path.
|
||||||
|
c.Parent = pathClean(c.Parent)
|
||||||
|
|
||||||
return &cgroupData{
|
return &cgroupData{
|
||||||
root: root,
|
root: root,
|
||||||
parent: c.Parent,
|
parent: c.Parent,
|
||||||
|
|
|
@ -4,6 +4,7 @@ package fs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -95,6 +96,10 @@ func (s *CpusetGroup) ensureParent(current, root string) error {
|
||||||
if filepath.Clean(parent) == root {
|
if filepath.Clean(parent) == root {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// Avoid infinite recursion.
|
||||||
|
if parent == current {
|
||||||
|
return fmt.Errorf("cpuset: cgroup parent path outside cgroup root")
|
||||||
|
}
|
||||||
if err := s.ensureParent(parent, root); err != nil {
|
if err := s.ensureParent(parent, root); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue