rootless: be in an userns to initialize the runtime

be sure to be in an userns for a rootless process before initializing
the runtime.  In case we are not running as uid==0, take advantage of
"podman info" that creates the runtime.

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

Closes: #1372
Approved by: mheon
This commit is contained in:
Giuseppe Scrivano
2018-08-30 18:26:41 +02:00
committed by Atomic Bot
parent daa28349c8
commit 14c0f9d63c
2 changed files with 27 additions and 3 deletions

View File

@ -29,6 +29,8 @@ var cmdsNotRequiringRootless = map[string]bool{
"help": true, "help": true,
"version": true, "version": true,
"exec": true, "exec": true,
// `info` must be executed in an user namespace.
// If this change, please also update libpod.refreshRootless()
"login": true, "login": true,
"logout": true, "logout": true,
"kill": true, "kill": true,

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"sync" "sync"
"syscall" "syscall"
@ -547,7 +548,12 @@ func makeRuntime(runtime *Runtime) (err error) {
// TODO: we can't close the FD in this lock, so we should keep it around // TODO: we can't close the FD in this lock, so we should keep it around
// and use it to lock important operations // and use it to lock important operations
aliveLock.Lock() aliveLock.Lock()
defer aliveLock.Unlock() locked := true
defer func() {
if locked {
aliveLock.Unlock()
}
}()
_, err = os.Stat(runtimeAliveFile) _, err = os.Stat(runtimeAliveFile)
if err != nil { if err != nil {
// If the file doesn't exist, we need to refresh the state // If the file doesn't exist, we need to refresh the state
@ -555,8 +561,16 @@ 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 err2 := runtime.refresh(runtimeAliveFile); err2 != nil { if os.Getuid() != 0 {
return err2 aliveLock.Unlock()
locked = false
if err2 := runtime.refreshRootless(); err2 != nil {
return err2
}
} else {
if err2 := runtime.refresh(runtimeAliveFile); err2 != nil {
return err2
}
} }
} else { } else {
return errors.Wrapf(err, "error reading runtime status file %s", runtimeAliveFile) return errors.Wrapf(err, "error reading runtime status file %s", runtimeAliveFile)
@ -631,6 +645,14 @@ func (r *Runtime) Shutdown(force bool) error {
return lastError return lastError
} }
// Reconfigures the runtime after a reboot for a rootless process
func (r *Runtime) refreshRootless() error {
// Take advantage of a command that requires a new userns
// so that we are running as the root user and able to use refresh()
cmd := exec.Command(os.Args[0], "info")
return cmd.Run()
}
// Reconfigures the runtime after a reboot // Reconfigures the runtime after a reboot
// Refreshes the state, recreating temporary files // Refreshes the state, recreating temporary files
// Does not check validity as the runtime is not valid until after this has run // Does not check validity as the runtime is not valid until after this has run