rootless: check uid with Geteuid() instead of Getuid()

change the tests to use chroot to set a numeric UID/GID.

Go syscall.Credential doesn't change the effective UID/GID of the
process.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>

Closes: #1372
Approved by: mheon
This commit is contained in:
Giuseppe Scrivano
2018-08-31 09:31:34 +02:00
committed by Atomic Bot
parent bdee681409
commit 807f6f8d8f
10 changed files with 21 additions and 16 deletions

View File

@ -99,7 +99,7 @@ func createCmd(c *cli.Context) error {
storageOpts.UIDMap = mappings.UIDMap storageOpts.UIDMap = mappings.UIDMap
storageOpts.GIDMap = mappings.GIDMap storageOpts.GIDMap = mappings.GIDMap
if os.Getuid() != 0 { if os.Geteuid() != 0 {
rootless.SetSkipStorageSetup(true) rootless.SetSkipStorageSetup(true)
} }
@ -778,7 +778,7 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
} }
func joinOrCreateRootlessUserNamespace(createConfig *cc.CreateConfig, runtime *libpod.Runtime) (bool, int, error) { func joinOrCreateRootlessUserNamespace(createConfig *cc.CreateConfig, runtime *libpod.Runtime) (bool, int, error) {
if os.Getuid() == 0 { if os.Geteuid() == 0 {
return false, 0, nil return false, 0, nil
} }

View File

@ -26,7 +26,7 @@ var (
) )
func pauseCmd(c *cli.Context) error { func pauseCmd(c *cli.Context) error {
if os.Getuid() != 0 { if os.Geteuid() != 0 {
return errors.New("pause is not supported for rootless containers") return errors.New("pause is not supported for rootless containers")
} }

View File

@ -74,7 +74,7 @@ func runCmd(c *cli.Context) error {
storageOpts.UIDMap = mappings.UIDMap storageOpts.UIDMap = mappings.UIDMap
storageOpts.GIDMap = mappings.GIDMap storageOpts.GIDMap = mappings.GIDMap
if os.Getuid() != 0 { if os.Geteuid() != 0 {
rootless.SetSkipStorageSetup(true) rootless.SetSkipStorageSetup(true)
} }

View File

@ -64,7 +64,7 @@ func statsCmd(c *cli.Context) error {
return err return err
} }
if os.Getuid() != 0 { if os.Geteuid() != 0 {
return errors.New("stats is not supported for rootless containers") return errors.New("stats is not supported for rootless containers")
} }

View File

@ -26,7 +26,7 @@ var (
) )
func unpauseCmd(c *cli.Context) error { func unpauseCmd(c *cli.Context) error {
if os.Getuid() != 0 { if os.Geteuid() != 0 {
return errors.New("unpause is not supported for rootless containers") return errors.New("unpause is not supported for rootless containers")
} }

View File

@ -20,7 +20,7 @@ import (
) )
func (r *OCIRuntime) moveConmonToCgroup(ctr *Container, cgroupParent string, cmd *exec.Cmd) error { func (r *OCIRuntime) moveConmonToCgroup(ctr *Container, cgroupParent string, cmd *exec.Cmd) error {
if os.Getuid() == 0 { if os.Geteuid() == 0 {
if r.cgroupManager == SystemdCgroupsManager { if r.cgroupManager == SystemdCgroupsManager {
unitName := createUnitName("libpod-conmon", ctr.ID()) unitName := createUnitName("libpod-conmon", ctr.ID())

View File

@ -561,7 +561,7 @@ func makeRuntime(runtime *Runtime) (err error) {
// empty state only creates a single file // empty state only creates a single file
// As such, it's not really a performance concern // As such, it's not really a performance concern
if os.IsNotExist(err) { if os.IsNotExist(err) {
if os.Getuid() != 0 { if os.Geteuid() != 0 {
aliveLock.Unlock() aliveLock.Unlock()
locked = false locked = false
if err2 := runtime.refreshRootless(); err2 != nil { if err2 := runtime.refreshRootless(); err2 != nil {

View File

@ -107,6 +107,10 @@ reexec_userns_join (int userns)
_exit (EXIT_FAILURE); _exit (EXIT_FAILURE);
close (userns); close (userns);
if (setresgid (0, 0, 0) < 0 ||
setresuid (0, 0, 0) < 0)
_exit (EXIT_FAILURE);
execvp (argv[0], argv); execvp (argv[0], argv);
_exit (EXIT_FAILURE); _exit (EXIT_FAILURE);

View File

@ -34,7 +34,7 @@ func runInUser() error {
// IsRootless tells us if we are running in rootless mode // IsRootless tells us if we are running in rootless mode
func IsRootless() bool { func IsRootless() bool {
return os.Getuid() != 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" return os.Geteuid() != 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != ""
} }
var ( var (
@ -88,7 +88,7 @@ func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap)
// JoinNS re-exec podman in a new userNS and join the user namespace of the specified // JoinNS re-exec podman in a new userNS and join the user namespace of the specified
// PID. // PID.
func JoinNS(pid uint) (bool, int, error) { func JoinNS(pid uint) (bool, int, error) {
if os.Getuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" { if os.Geteuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" {
return false, -1, nil return false, -1, nil
} }
@ -116,7 +116,7 @@ func JoinNS(pid uint) (bool, int, error) {
// If podman was re-executed the caller needs to propagate the error code returned by the child // If podman was re-executed the caller needs to propagate the error code returned by the child
// process. // process.
func BecomeRootInUserNS() (bool, int, error) { func BecomeRootInUserNS() (bool, int, error) {
if os.Getuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" { if os.Geteuid() == 0 || os.Getenv("_LIBPOD_USERNS_CONFIGURED") != "" {
if os.Getenv("_LIBPOD_USERNS_CONFIGURED") == "init" { if os.Getenv("_LIBPOD_USERNS_CONFIGURED") == "init" {
return false, 0, runInUser() return false, 0, runInUser()
} }
@ -142,7 +142,7 @@ func BecomeRootInUserNS() (bool, int, error) {
var uids, gids []idtools.IDMap var uids, gids []idtools.IDMap
username := os.Getenv("USER") username := os.Getenv("USER")
if username == "" { if username == "" {
user, err := user.LookupId(fmt.Sprintf("%d", os.Geteuid())) user, err := user.LookupId(fmt.Sprintf("%d", os.Getuid()))
if err != nil && os.Getenv("PODMAN_ALLOW_SINGLE_ID_MAPPING_IN_USERNS") == "" { if err != nil && os.Getenv("PODMAN_ALLOW_SINGLE_ID_MAPPING_IN_USERNS") == "" {
return false, 0, errors.Wrapf(err, "could not find user by UID nor USER env was set") return false, 0, errors.Wrapf(err, "could not find user by UID nor USER env was set")
} }

View File

@ -10,7 +10,6 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
"testing" "testing"
"time" "time"
@ -190,11 +189,13 @@ func (p *PodmanTest) PodmanAsUser(args []string, uid, gid uint32, env []string)
} else { } else {
fmt.Printf("Running: (env: %v) %s %s\n", env, p.PodmanBinary, strings.Join(podmanOptions, " ")) fmt.Printf("Running: (env: %v) %s %s\n", env, p.PodmanBinary, strings.Join(podmanOptions, " "))
} }
command := exec.Command(p.PodmanBinary, podmanOptions...) var command *exec.Cmd
if uid != 0 || gid != 0 { if uid != 0 || gid != 0 {
command.SysProcAttr = &syscall.SysProcAttr{} nsEnterOpts := append([]string{"--userspec", fmt.Sprintf("%d:%d", uid, gid), "/", p.PodmanBinary}, podmanOptions...)
command.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid} command = exec.Command("chroot", nsEnterOpts...)
} else {
command = exec.Command(p.PodmanBinary, podmanOptions...)
} }
if env != nil { if env != nil {
command.Env = env command.Env = env