diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 493b07c3f7..61f7f0ab41 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -870,7 +870,7 @@ func makeExecConfig(options entities.ExecOptions, rt *libpod.Runtime) (*libpod.E func checkExecPreserveFDs(options entities.ExecOptions) error { if options.PreserveFDs > 0 { - entries, err := os.ReadDir("/proc/self/fd") + entries, err := os.ReadDir(processFileDescriptorsPath) if err != nil { return err } @@ -879,7 +879,7 @@ func checkExecPreserveFDs(options entities.ExecOptions) error { for _, e := range entries { i, err := strconv.Atoi(e.Name()) if err != nil { - return fmt.Errorf("cannot parse %s in /proc/self/fd: %w", e.Name(), err) + return fmt.Errorf("cannot parse %s in %s: %w", e.Name(), processFileDescriptorsPath, err) } m[i] = true } diff --git a/pkg/domain/infra/abi/containers_freebsd.go b/pkg/domain/infra/abi/containers_freebsd.go new file mode 100644 index 0000000000..a095a87cb7 --- /dev/null +++ b/pkg/domain/infra/abi/containers_freebsd.go @@ -0,0 +1,3 @@ +package abi + +const processFileDescriptorsPath = "/dev/fd" diff --git a/pkg/domain/infra/abi/containers_linux.go b/pkg/domain/infra/abi/containers_linux.go new file mode 100644 index 0000000000..10b3d33a49 --- /dev/null +++ b/pkg/domain/infra/abi/containers_linux.go @@ -0,0 +1,3 @@ +package abi + +const processFileDescriptorsPath = "/proc/self/fd" diff --git a/pkg/rootless/rootless_freebsd.c b/pkg/rootless/rootless_freebsd.c new file mode 100644 index 0000000000..f8f0ba4b8e --- /dev/null +++ b/pkg/rootless/rootless_freebsd.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include + +static int open_files_max_fd; +static fd_set *open_files_set; + +int +is_fd_inherited(int fd) +{ + if (open_files_set == NULL || fd > open_files_max_fd || fd < 0) + return 0; + + return FD_ISSET(fd % FD_SETSIZE, &(open_files_set[fd / FD_SETSIZE])) ? 1 : 0; +} + +static void __attribute__((constructor)) init() +{ + /* Store how many FDs were open before the Go runtime kicked in. */ + DIR* d = opendir ("/dev/fd"); + if (d) + { + struct dirent *ent; + size_t size = 0; + + for (ent = readdir (d); ent; ent = readdir (d)) + { + int fd; + + if (ent->d_name[0] == '.') + continue; + + fd = atoi (ent->d_name); + if (fd == dirfd (d)) { + continue; + } + + if (fd >= size * FD_SETSIZE) + { + int i; + size_t new_size; + + new_size = (fd / FD_SETSIZE) + 1; + open_files_set = realloc (open_files_set, new_size * sizeof (fd_set)); + if (open_files_set == NULL) + _exit (EXIT_FAILURE); + + for (i = size; i < new_size; i++) + FD_ZERO (&(open_files_set[i])); + + size = new_size; + } + + if (fd > open_files_max_fd) { + open_files_max_fd = fd; + } + + FD_SET (fd % FD_SETSIZE, &(open_files_set[fd / FD_SETSIZE])); + } + } +} diff --git a/pkg/rootless/rootless_freebsd.go b/pkg/rootless/rootless_freebsd.go new file mode 100644 index 0000000000..b1434bbb62 --- /dev/null +++ b/pkg/rootless/rootless_freebsd.go @@ -0,0 +1,69 @@ +//go:build freebsd && cgo +// +build freebsd,cgo + +package rootless + +import ( + "errors" + + "github.com/containers/storage/pkg/idtools" +) + +// extern int is_fd_inherited(int fd); +import "C" + +// IsRootless returns whether the user is rootless +func IsRootless() bool { + return false +} + +// BecomeRootInUserNS re-exec podman in a new userNS. It returns whether podman was re-executed +// into a new user namespace and the return code from the re-executed podman process. +// If podman was re-executed the caller needs to propagate the error code returned by the child +// process. It is a convenience function for BecomeRootInUserNSWithOpts with a default configuration. +func BecomeRootInUserNS(pausePid string) (bool, int, error) { + return false, -1, errors.New("this function is not supported on this os") +} + +// GetRootlessUID returns the UID of the user in the parent userNS +func GetRootlessUID() int { + return -1 +} + +// GetRootlessGID returns the GID of the user in the parent userNS +func GetRootlessGID() int { + return -1 +} + +// TryJoinFromFilePaths attempts to join the namespaces of the pid files in paths. +// This is useful when there are already running containers and we +// don't have a pause process yet. We can use the paths to the conmon +// processes to attempt joining their namespaces. +// If needNewNamespace is set, the file is read from a temporary user +// namespace, this is useful for containers that are running with a +// different uidmap and the unprivileged user has no way to read the +// file owned by the root in the container. +func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []string) (bool, int, error) { + return false, -1, errors.New("this function is not supported on this os") +} + +// ConfigurationMatches checks whether the additional uids/gids configured for the user +// match the current user namespace. +func ConfigurationMatches() (bool, error) { + return true, nil +} + +// GetConfiguredMappings returns the additional IDs configured for the current user. +func GetConfiguredMappings(quiet bool) ([]idtools.IDMap, []idtools.IDMap, error) { + return nil, nil, errors.New("this function is not supported on this os") +} + +// ReadMappingsProc returns the uid_map and gid_map +func ReadMappingsProc(path string) ([]idtools.IDMap, error) { + return nil, nil +} + +// IsFdInherited checks whether the fd is opened and valid to use +func IsFdInherited(fd int) bool { + return int(C.is_fd_inherited(C.int(fd))) > 0 +} diff --git a/pkg/rootless/rootless_unsupported.go b/pkg/rootless/rootless_unsupported.go index b08075c193..c2e86fa1d8 100644 --- a/pkg/rootless/rootless_unsupported.go +++ b/pkg/rootless/rootless_unsupported.go @@ -1,5 +1,5 @@ -//go:build !linux || !cgo -// +build !linux !cgo +//go:build !(linux || freebsd) || !cgo +// +build !linux,!freebsd !cgo package rootless