mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
Pre-open container root directory
A lot of filesystem-related stuff happens inside the container root directory, and we have used its name before. It makes sense to pre-open it and use a *os.File handle instead. Function names in internal/pathrs are kept as is for simplicity (and it is an internal package), but they now accept root as *os.File. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
@@ -31,12 +31,12 @@ import (
|
||||
// Callers need to be very careful operating on the trailing path, as trivial
|
||||
// mistakes like following symlinks can cause security bugs. Most people
|
||||
// should probably just use [MkdirAllInRoot] or [CreateInRoot].
|
||||
func MkdirAllParentInRoot(root, unsafePath string, mode os.FileMode) (*os.File, string, error) {
|
||||
func MkdirAllParentInRoot(root *os.File, unsafePath string, mode os.FileMode) (*os.File, string, error) {
|
||||
// MkdirAllInRoot also does hallucinateUnsafePath, but we need to do it
|
||||
// here first because when we split unsafePath into (dir, file) components
|
||||
// we want to be doing so with the hallucinated path (so that trailing
|
||||
// dangling symlinks are treated correctly).
|
||||
unsafePath, err := hallucinateUnsafePath(root, unsafePath)
|
||||
unsafePath, err := hallucinateUnsafePath(root.Name(), unsafePath)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("failed to construct hallucinated target path: %w", err)
|
||||
}
|
||||
|
||||
@@ -24,12 +24,11 @@ import (
|
||||
|
||||
"github.com/cyphar/filepath-securejoin/pathrs-lite"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// MkdirAllInRoot attempts to make
|
||||
//
|
||||
// path, _ := securejoin.SecureJoin(root, unsafePath)
|
||||
// path, _ := securejoin.SecureJoin(root.Name(), unsafePath)
|
||||
// os.MkdirAll(path, mode)
|
||||
// os.Open(path)
|
||||
//
|
||||
@@ -48,8 +47,8 @@ import (
|
||||
// handling if unsafePath has already been scoped within the rootfs (this is
|
||||
// needed for a lot of runc callers and fixing this would require reworking a
|
||||
// lot of path logic).
|
||||
func MkdirAllInRoot(root, unsafePath string, mode os.FileMode) (*os.File, error) {
|
||||
unsafePath, err := hallucinateUnsafePath(root, unsafePath)
|
||||
func MkdirAllInRoot(root *os.File, unsafePath string, mode os.FileMode) (*os.File, error) {
|
||||
unsafePath, err := hallucinateUnsafePath(root.Name(), unsafePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to construct hallucinated target path: %w", err)
|
||||
}
|
||||
@@ -67,13 +66,7 @@ func MkdirAllInRoot(root, unsafePath string, mode os.FileMode) (*os.File, error)
|
||||
mode &= 0o1777
|
||||
}
|
||||
|
||||
rootDir, err := os.OpenFile(root, unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open root handle: %w", err)
|
||||
}
|
||||
defer rootDir.Close()
|
||||
|
||||
return retryEAGAIN(func() (*os.File, error) {
|
||||
return pathrs.MkdirAllHandle(rootDir, unsafePath, mode)
|
||||
return pathrs.MkdirAllHandle(root, unsafePath, mode)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -28,11 +28,11 @@ import (
|
||||
)
|
||||
|
||||
// OpenInRoot opens the given path inside the root with the provided flags. It
|
||||
// is effectively shorthand for [securejoin.OpenInRoot] followed by
|
||||
// is effectively shorthand for [securejoin.OpenatInRoot] followed by
|
||||
// [securejoin.Reopen].
|
||||
func OpenInRoot(root, subpath string, flags int) (*os.File, error) {
|
||||
func OpenInRoot(root *os.File, subpath string, flags int) (*os.File, error) {
|
||||
handle, err := retryEAGAIN(func() (*os.File, error) {
|
||||
return pathrs.OpenInRoot(root, subpath)
|
||||
return pathrs.OpenatInRoot(root, subpath)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -47,7 +47,7 @@ func OpenInRoot(root, subpath string, flags int) (*os.File, error) {
|
||||
// open(O_CREAT|O_NOFOLLOW) semantics. If you want the creation to use O_EXCL,
|
||||
// include it in the passed flags. The fileMode argument uses unix.* mode bits,
|
||||
// *not* os.FileMode.
|
||||
func CreateInRoot(root, subpath string, flags int, fileMode uint32) (*os.File, error) {
|
||||
func CreateInRoot(root *os.File, subpath string, flags int, fileMode uint32) (*os.File, error) {
|
||||
dirFd, filename, err := MkdirAllParentInRoot(root, subpath, 0o755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -63,5 +63,5 @@ func CreateInRoot(root, subpath string, flags int, fileMode uint32) (*os.File, e
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return os.NewFile(uintptr(fd), root+"/"+subpath), nil
|
||||
return os.NewFile(uintptr(fd), root.Name()+"/"+subpath), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user