mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
int/linux: add/use Getwd
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
@@ -16,3 +16,13 @@ func retryOnEINTR(fn func() error) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// retryOnEINTR2 is like retryOnEINTR, but it returns 2 values.
|
||||
func retryOnEINTR2[T any](fn func() (T, error)) (T, error) {
|
||||
for {
|
||||
val, err := fn()
|
||||
if !errors.Is(err, unix.EINTR) {
|
||||
return val, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,12 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Getwd wraps [unix.Getwd].
|
||||
func Getwd() (wd string, err error) {
|
||||
wd, err = retryOnEINTR2(unix.Getwd)
|
||||
return wd, os.NewSyscallError("getwd", err)
|
||||
}
|
||||
|
||||
// Sendmsg wraps [unix.Sendmsg].
|
||||
func Sendmsg(fd int, p, oob []byte, to unix.Sockaddr, flags int) error {
|
||||
err := retryOnEINTR(func() error {
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/opencontainers/cgroups"
|
||||
"github.com/opencontainers/runc/internal/linux"
|
||||
"github.com/opencontainers/runc/libcontainer/capabilities"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/system"
|
||||
@@ -280,10 +281,10 @@ func verifyCwd() error {
|
||||
// details, and CVE-2024-21626 for the security issue that motivated this
|
||||
// check.
|
||||
//
|
||||
// We have to use unix.Getwd() here because os.Getwd() has a workaround for
|
||||
// We do not use os.Getwd() here because it has a workaround for
|
||||
// $PWD which involves doing stat(.), which can fail if the current
|
||||
// directory is inaccessible to the container process.
|
||||
if wd, err := unix.Getwd(); errors.Is(err, unix.ENOENT) {
|
||||
if wd, err := linux.Getwd(); errors.Is(err, unix.ENOENT) {
|
||||
return errors.New("current working directory is outside of container mount namespace root -- possible container breakout detected")
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("failed to verify if current working directory is safe: %w", err)
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
dbus "github.com/godbus/dbus/v5"
|
||||
"github.com/opencontainers/cgroups"
|
||||
devices "github.com/opencontainers/cgroups/devices/config"
|
||||
"github.com/opencontainers/runc/internal/linux"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/internal/userns"
|
||||
"github.com/opencontainers/runc/libcontainer/seccomp"
|
||||
@@ -344,24 +345,13 @@ type CreateOpts struct {
|
||||
RootlessCgroups bool
|
||||
}
|
||||
|
||||
// getwd is a wrapper similar to os.Getwd, except it always gets
|
||||
// the value from the kernel, which guarantees the returned value
|
||||
// to be absolute and clean.
|
||||
func getwd() (wd string, err error) {
|
||||
for {
|
||||
wd, err = unix.Getwd()
|
||||
if err != unix.EINTR {
|
||||
break
|
||||
}
|
||||
}
|
||||
return wd, os.NewSyscallError("getwd", err)
|
||||
}
|
||||
|
||||
// CreateLibcontainerConfig creates a new libcontainer configuration from a
|
||||
// given specification and a cgroup name
|
||||
func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) {
|
||||
// runc's cwd will always be the bundle path
|
||||
cwd, err := getwd()
|
||||
// Runc's cwd will always be the bundle path.
|
||||
// Use the value from the kernel, which guarantees the returned value
|
||||
// to be absolute and clean.
|
||||
cwd, err := linux.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user