Bump dependency opencontainers/runc@v1.0.0-rc9

This commit is contained in:
Odin Ugedal
2019-10-05 13:45:54 +02:00
parent 00096d8fed
commit 708a917b7d
30 changed files with 1463 additions and 197 deletions

View File

@@ -13,7 +13,7 @@ import (
"strings"
"time"
"github.com/cyphar/filepath-securejoin"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/mrunalp/fileutils"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
@@ -197,7 +197,7 @@ func prepareBindMount(m *configs.Mount, rootfs string) error {
if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil {
return err
}
if err := checkMountDestination(rootfs, dest); err != nil {
if err := checkProcMount(rootfs, dest, m.Source); err != nil {
return err
}
// update the mount with the correct dest after symlinks are resolved.
@@ -209,6 +209,80 @@ func prepareBindMount(m *configs.Mount, rootfs string) error {
return nil
}
func mountCgroupV1(m *configs.Mount, rootfs, mountLabel string, enableCgroupns bool) error {
binds, err := getCgroupMounts(m)
if err != nil {
return err
}
var merged []string
for _, b := range binds {
ss := filepath.Base(b.Destination)
if strings.Contains(ss, ",") {
merged = append(merged, ss)
}
}
tmpfs := &configs.Mount{
Source: "tmpfs",
Device: "tmpfs",
Destination: m.Destination,
Flags: defaultMountFlags,
Data: "mode=755",
PropagationFlags: m.PropagationFlags,
}
if err := mountToRootfs(tmpfs, rootfs, mountLabel, enableCgroupns); err != nil {
return err
}
for _, b := range binds {
if enableCgroupns {
subsystemPath := filepath.Join(rootfs, b.Destination)
if err := os.MkdirAll(subsystemPath, 0755); err != nil {
return err
}
flags := defaultMountFlags
if m.Flags&unix.MS_RDONLY != 0 {
flags = flags | unix.MS_RDONLY
}
cgroupmount := &configs.Mount{
Source: "cgroup",
Device: "cgroup",
Destination: subsystemPath,
Flags: flags,
Data: filepath.Base(subsystemPath),
}
if err := mountNewCgroup(cgroupmount); err != nil {
return err
}
} else {
if err := mountToRootfs(b, rootfs, mountLabel, enableCgroupns); err != nil {
return err
}
}
}
for _, mc := range merged {
for _, ss := range strings.Split(mc, ",") {
// symlink(2) is very dumb, it will just shove the path into
// the link and doesn't do any checks or relative path
// conversion. Also, don't error out if the cgroup already exists.
if err := os.Symlink(mc, filepath.Join(rootfs, m.Destination, ss)); err != nil && !os.IsExist(err) {
return err
}
}
}
return nil
}
func mountCgroupV2(m *configs.Mount, rootfs, mountLabel string, enableCgroupns bool) error {
cgroupPath, err := securejoin.SecureJoin(rootfs, m.Destination)
if err != nil {
return err
}
if err := os.MkdirAll(cgroupPath, 0755); err != nil {
return err
}
return unix.Mount(m.Source, cgroupPath, "cgroup2", uintptr(m.Flags), m.Data)
}
func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns bool) error {
var (
dest = m.Destination
@@ -309,62 +383,14 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b
}
}
case "cgroup":
binds, err := getCgroupMounts(m)
if err != nil {
return err
}
var merged []string
for _, b := range binds {
ss := filepath.Base(b.Destination)
if strings.Contains(ss, ",") {
merged = append(merged, ss)
if cgroups.IsCgroup2UnifiedMode() {
if err := mountCgroupV2(m, rootfs, mountLabel, enableCgroupns); err != nil {
return err
}
}
tmpfs := &configs.Mount{
Source: "tmpfs",
Device: "tmpfs",
Destination: m.Destination,
Flags: defaultMountFlags,
Data: "mode=755",
PropagationFlags: m.PropagationFlags,
}
if err := mountToRootfs(tmpfs, rootfs, mountLabel, enableCgroupns); err != nil {
return err
}
for _, b := range binds {
if enableCgroupns {
subsystemPath := filepath.Join(rootfs, b.Destination)
if err := os.MkdirAll(subsystemPath, 0755); err != nil {
return err
}
flags := defaultMountFlags
if m.Flags&unix.MS_RDONLY != 0 {
flags = flags | unix.MS_RDONLY
}
cgroupmount := &configs.Mount{
Source: "cgroup",
Device: "cgroup",
Destination: subsystemPath,
Flags: flags,
Data: filepath.Base(subsystemPath),
}
if err := mountNewCgroup(cgroupmount); err != nil {
return err
}
} else {
if err := mountToRootfs(b, rootfs, mountLabel, enableCgroupns); err != nil {
return err
}
}
}
for _, mc := range merged {
for _, ss := range strings.Split(mc, ",") {
// symlink(2) is very dumb, it will just shove the path into
// the link and doesn't do any checks or relative path
// conversion. Also, don't error out if the cgroup already exists.
if err := os.Symlink(mc, filepath.Join(rootfs, m.Destination, ss)); err != nil && !os.IsExist(err) {
return err
}
} else {
if err := mountCgroupV1(m, rootfs, mountLabel, enableCgroupns); err != nil {
return err
}
}
if m.Flags&unix.MS_RDONLY != 0 {
@@ -388,7 +414,7 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b
if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil {
return err
}
if err := checkMountDestination(rootfs, dest); err != nil {
if err := checkProcMount(rootfs, dest, m.Source); err != nil {
return err
}
// update the mount with the correct dest after symlinks are resolved.
@@ -435,12 +461,12 @@ func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
return binds, nil
}
// checkMountDestination checks to ensure that the mount destination is not over the top of /proc.
// checkProcMount checks to ensure that the mount destination is not over the top of /proc.
// dest is required to be an abs path and have any symlinks resolved before calling this function.
func checkMountDestination(rootfs, dest string) error {
invalidDestinations := []string{
"/proc",
}
//
// if source is nil, don't stat the filesystem. This is used for restore of a checkpoint.
func checkProcMount(rootfs, dest, source string) error {
const procPath = "/proc"
// White list, it should be sub directories of invalid destinations
validDestinations := []string{
// These entries can be bind mounted by files emulated by fuse,
@@ -463,16 +489,40 @@ func checkMountDestination(rootfs, dest string) error {
return nil
}
}
for _, invalid := range invalidDestinations {
path, err := filepath.Rel(filepath.Join(rootfs, invalid), dest)
path, err := filepath.Rel(filepath.Join(rootfs, procPath), dest)
if err != nil {
return err
}
// pass if the mount path is located outside of /proc
if strings.HasPrefix(path, "..") {
return nil
}
if path == "." {
// an empty source is pasted on restore
if source == "" {
return nil
}
// only allow a mount on-top of proc if it's source is "proc"
isproc, err := isProc(source)
if err != nil {
return err
}
if path != "." && !strings.HasPrefix(path, "..") {
return fmt.Errorf("%q cannot be mounted because it is located inside %q", dest, invalid)
// pass if the mount is happening on top of /proc and the source of
// the mount is a proc filesystem
if isproc {
return nil
}
return fmt.Errorf("%q cannot be mounted because it is not of type proc", dest)
}
return nil
return fmt.Errorf("%q cannot be mounted because it is inside /proc", dest)
}
func isProc(path string) (bool, error) {
var s unix.Statfs_t
if err := unix.Statfs(path, &s); err != nil {
return false, err
}
return s.Type == unix.PROC_SUPER_MAGIC, nil
}
func setupDevSymlinks(rootfs string) error {