Skip to content
Merged
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
4 changes: 2 additions & 2 deletions internal/pathrs/mkdirall.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
15 changes: 4 additions & 11 deletions internal/pathrs/mkdirall_pathrslite.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
//
Expand All @@ -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)
}
Expand All @@ -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)
})
}
10 changes: 5 additions & 5 deletions internal/pathrs/root_pathrslite.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
}
10 changes: 8 additions & 2 deletions libcontainer/criu_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,16 @@ func isOnTmpfs(path string, mounts []*configs.Mount) bool {
// This function also creates missing mountpoints as long as they
// are not on top of a tmpfs, as CRIU will restore tmpfs content anyway.
func (c *Container) prepareCriuRestoreMounts(mounts []*configs.Mount) error {
rootFd, err := os.OpenFile(c.config.Rootfs, unix.O_DIRECTORY|unix.O_CLOEXEC|unix.O_PATH, 0)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(added O_PATH to here)

if err != nil {
return fmt.Errorf("open rootfs handle: %w", err)
}
defer rootFd.Close()

umounts := []string{}
defer func() {
for _, u := range umounts {
mntFile, err := pathrs.OpenInRoot(c.config.Rootfs, u, unix.O_PATH)
mntFile, err := pathrs.OpenInRoot(rootFd, u, unix.O_PATH)
if err != nil {
logrus.Warnf("Error during cleanup unmounting %s: open handle: %v", u, err)
continue
Expand Down Expand Up @@ -590,7 +596,7 @@ func (c *Container) prepareCriuRestoreMounts(mounts []*configs.Mount) error {
continue
}
me := mountEntry{Mount: m}
if err := me.createOpenMountpoint(c.config.Rootfs); err != nil {
if err := me.createOpenMountpoint(rootFd); err != nil {
return fmt.Errorf("create criu restore mountpoint for %s mount: %w", me.Destination, err)
}
if me.dstFile != nil {
Expand Down
Loading
Loading