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,
"version": true,
"exec": true,
// `info` must be executed in an user namespace.
// If this change, please also update libpod.refreshRootless()
"login": true,
"logout": true,
"kill": true,

View File

@ -4,6 +4,7 @@ import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"sync"
"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
// and use it to lock important operations
aliveLock.Lock()
defer aliveLock.Unlock()
locked := true
defer func() {
if locked {
aliveLock.Unlock()
}
}()
_, err = os.Stat(runtimeAliveFile)
if err != nil {
// If the file doesn't exist, we need to refresh the state
@ -555,9 +561,17 @@ func makeRuntime(runtime *Runtime) (err error) {
// empty state only creates a single file
// As such, it's not really a performance concern
if os.IsNotExist(err) {
if os.Getuid() != 0 {
aliveLock.Unlock()
locked = false
if err2 := runtime.refreshRootless(); err2 != nil {
return err2
}
} else {
if err2 := runtime.refresh(runtimeAliveFile); err2 != nil {
return err2
}
}
} else {
return errors.Wrapf(err, "error reading runtime status file %s", runtimeAliveFile)
}
@ -631,6 +645,14 @@ func (r *Runtime) Shutdown(force bool) error {
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
// Refreshes the state, recreating temporary files
// Does not check validity as the runtime is not valid until after this has run