Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions libcontainer/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"strings"

"golang.org/x/sys/unix"

"github.com/opencontainers/runc/internal/pathrs"
)

const (
Expand Down Expand Up @@ -67,23 +65,3 @@ func Annotations(labels []string) (bundle string, userAnnotations map[string]str
}
return bundle, userAnnotations
}

// CleanPath 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 CleanPath.
//
// Deprecated: This function has been moved to internal/pathrs and this wrapper
// will be removed in runc 1.5.
var CleanPath = pathrs.LexicallyCleanPath

// StripRoot returns the passed path, stripping the root path if it was
// (lexicially) inside it. Note that both passed paths will always be treated
// as absolute, and the returned path will also always be absolute. In
// addition, the paths are cleaned before stripping the root.
//
// Deprecated: This function has been moved to internal/pathrs and this wrapper
// will be removed in runc 1.5.
var StripRoot = pathrs.LexicallyStripRoot
40 changes: 0 additions & 40 deletions libcontainer/utils/utils_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ import (
"fmt"
"math"
"os"
"path/filepath"
"runtime"
"strconv"
"sync"
_ "unsafe" // for go:linkname

securejoin "github.com/cyphar/filepath-securejoin"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"

Expand Down Expand Up @@ -146,44 +144,6 @@ func NewSockPair(name string) (parent, child *os.File, err error) {
return os.NewFile(uintptr(fds[1]), name+"-p"), os.NewFile(uintptr(fds[0]), name+"-c"), nil
}

// WithProcfd runs the passed closure with a procfd path (/proc/self/fd/...)
// corresponding to the unsafePath resolved within the root. Before passing the
// fd, this path is verified to have been inside the root -- so operating on it
// through the passed fdpath should be safe. Do not access this path through
// the original path strings, and do not attempt to use the pathname outside of
// the passed closure (the file handle will be freed once the closure returns).
//
// Deprecated: This function is an internal implementation detail of runc and
// is no longer used. It will be removed in runc 1.5.
func WithProcfd(root, unsafePath string, fn func(procfd string) error) error {
// Remove the root then forcefully resolve inside the root.
unsafePath = pathrs.LexicallyStripRoot(root, unsafePath)
fullPath, err := securejoin.SecureJoin(root, unsafePath)
if err != nil {
return fmt.Errorf("resolving path inside rootfs failed: %w", err)
}

procSelfFd, closer := ProcThreadSelf("fd/")
defer closer()

// Open the target path.
fh, err := os.OpenFile(fullPath, unix.O_PATH|unix.O_CLOEXEC, 0)
if err != nil {
return fmt.Errorf("open o_path procfd: %w", err)
}
defer fh.Close()

procfd := filepath.Join(procSelfFd, strconv.Itoa(int(fh.Fd())))
// Double-check the path is the one we expected.
if realpath, err := os.Readlink(procfd); err != nil {
return fmt.Errorf("procfd verification failed: %w", err)
} else if realpath != fullPath {
return fmt.Errorf("possibly malicious path detected -- refusing to operate on %s", realpath)
}

return fn(procfd)
}

// WithProcfdFile is a very minimal wrapper around [ProcThreadSelfFd]. The
// caller is responsible for making sure that the provided file handle is
// actually safe to operate on.
Expand Down