int/linux: add/use Getwd

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin
2025-03-25 14:36:42 -07:00
parent 8cc1eb379b
commit 431b8bb4d8
4 changed files with 24 additions and 17 deletions
+10
View File
@@ -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
View File
@@ -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 {
+3 -2
View File
@@ -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)
+5 -15
View File
@@ -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
}