mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 12:18:16 +00:00 
			
		
		
		
	Update Runc to 1.1.14
Changelog: https://github.com/opencontainers/runc/releases/tag/v1.1.14
This commit is contained in:
		
							
								
								
									
										129
									
								
								vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										129
									
								
								vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -4,11 +4,17 @@
 | 
			
		||||
package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	_ "unsafe" // for go:linkname
 | 
			
		||||
 | 
			
		||||
	"github.com/opencontainers/runc/libcontainer/system"
 | 
			
		||||
 | 
			
		||||
	securejoin "github.com/cyphar/filepath-securejoin"
 | 
			
		||||
	"golang.org/x/sys/unix"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -115,3 +121,126 @@ func NewSockPair(name string) (parent *os.File, child *os.File, err error) {
 | 
			
		||||
	}
 | 
			
		||||
	return os.NewFile(uintptr(fds[1]), name+"-p"), os.NewFile(uintptr(fds[0]), name+"-c"), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsLexicallyInRoot is shorthand for strings.HasPrefix(path+"/", root+"/"),
 | 
			
		||||
// but properly handling the case where path or root are "/".
 | 
			
		||||
//
 | 
			
		||||
// NOTE: The return value only make sense if the path doesn't contain "..".
 | 
			
		||||
func IsLexicallyInRoot(root, path string) bool {
 | 
			
		||||
	if root != "/" {
 | 
			
		||||
		root += "/"
 | 
			
		||||
	}
 | 
			
		||||
	if path != "/" {
 | 
			
		||||
		path += "/"
 | 
			
		||||
	}
 | 
			
		||||
	return strings.HasPrefix(path, root)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MkdirAllInRootOpen attempts to make
 | 
			
		||||
//
 | 
			
		||||
//	path, _ := securejoin.SecureJoin(root, unsafePath)
 | 
			
		||||
//	os.MkdirAll(path, mode)
 | 
			
		||||
//	os.Open(path)
 | 
			
		||||
//
 | 
			
		||||
// safer against attacks where components in the path are changed between
 | 
			
		||||
// SecureJoin returning and MkdirAll (or Open) being called. In particular, we
 | 
			
		||||
// try to detect any symlink components in the path while we are doing the
 | 
			
		||||
// MkdirAll.
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Unlike os.MkdirAll, mode is not Go's os.FileMode, it is the unix mode
 | 
			
		||||
// (the suid/sgid/sticky bits are not the same as for os.FileMode).
 | 
			
		||||
//
 | 
			
		||||
// NOTE: If unsafePath is a subpath of root, we assume that you have already
 | 
			
		||||
// called SecureJoin and so we use the provided path verbatim without resolving
 | 
			
		||||
// any symlinks (this is done in a way that avoids symlink-exchange races).
 | 
			
		||||
// This means that the path also must not contain ".." elements, otherwise an
 | 
			
		||||
// error will occur.
 | 
			
		||||
//
 | 
			
		||||
// This is a somewhat less safe alternative to
 | 
			
		||||
// <https://github.com/cyphar/filepath-securejoin/pull/13>, but it should
 | 
			
		||||
// detect attempts to trick us into creating directories outside of the root.
 | 
			
		||||
// We should migrate to securejoin.MkdirAll once it is merged.
 | 
			
		||||
func MkdirAllInRootOpen(root, unsafePath string, mode uint32) (_ *os.File, Err error) {
 | 
			
		||||
	// If the path is already "within" the root, use it verbatim.
 | 
			
		||||
	fullPath := unsafePath
 | 
			
		||||
	if !IsLexicallyInRoot(root, unsafePath) {
 | 
			
		||||
		var err error
 | 
			
		||||
		fullPath, err = securejoin.SecureJoin(root, unsafePath)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	subPath, err := filepath.Rel(root, fullPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check for any silly mode bits.
 | 
			
		||||
	if mode&^0o7777 != 0 {
 | 
			
		||||
		return nil, fmt.Errorf("tried to include non-mode bits in MkdirAll mode: 0o%.3o", mode)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	currentDir, err := os.OpenFile(root, unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("open root handle: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if Err != nil {
 | 
			
		||||
			currentDir.Close()
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	for _, part := range strings.Split(subPath, string(filepath.Separator)) {
 | 
			
		||||
		switch part {
 | 
			
		||||
		case "", ".":
 | 
			
		||||
			// Skip over no-op components.
 | 
			
		||||
			continue
 | 
			
		||||
		case "..":
 | 
			
		||||
			return nil, fmt.Errorf("possible breakout detected: found %q component in SecureJoin subpath %s", part, subPath)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		nextDir, err := system.Openat(currentDir, part, unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0)
 | 
			
		||||
		switch {
 | 
			
		||||
		case err == nil:
 | 
			
		||||
			// Update the currentDir.
 | 
			
		||||
			_ = currentDir.Close()
 | 
			
		||||
			currentDir = nextDir
 | 
			
		||||
 | 
			
		||||
		case errors.Is(err, unix.ENOTDIR):
 | 
			
		||||
			// This might be a symlink or some other random file. Either way,
 | 
			
		||||
			// error out.
 | 
			
		||||
			return nil, fmt.Errorf("cannot mkdir in %s/%s: %w", currentDir.Name(), part, unix.ENOTDIR)
 | 
			
		||||
 | 
			
		||||
		case errors.Is(err, os.ErrNotExist):
 | 
			
		||||
			// Luckily, mkdirat will not follow trailing symlinks, so this is
 | 
			
		||||
			// safe to do as-is.
 | 
			
		||||
			if err := system.Mkdirat(currentDir, part, mode); err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
			// Open the new directory. There is a race here where an attacker
 | 
			
		||||
			// could swap the directory with a different directory, but
 | 
			
		||||
			// MkdirAll's fuzzy semantics mean we don't care about that.
 | 
			
		||||
			nextDir, err := system.Openat(currentDir, part, unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, fmt.Errorf("open newly created directory: %w", err)
 | 
			
		||||
			}
 | 
			
		||||
			// Update the currentDir.
 | 
			
		||||
			_ = currentDir.Close()
 | 
			
		||||
			currentDir = nextDir
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return currentDir, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MkdirAllInRoot is a wrapper around MkdirAllInRootOpen which closes the
 | 
			
		||||
// returned handle, for callers that don't need to use it.
 | 
			
		||||
func MkdirAllInRoot(root, unsafePath string, mode uint32) error {
 | 
			
		||||
	f, err := MkdirAllInRootOpen(root, unsafePath, mode)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		_ = f.Close()
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user