Skip to content

Commit

Permalink
rootless: fix pod rm when uid in the container != 0
Browse files Browse the repository at this point in the history
join the user namespace where the pod is running, so that we can both
manage the storage and correctly send the kill signal to a process
which is not running as root in the namespace.

Closes: containers#2577

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Mar 8, 2019
1 parent 1b2f867 commit 414eeb1
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cmd/podman/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ var cmdsNotRequiringRootless = map[*cobra.Command]bool{
_mountCommand: true,
_killCommand: true,
_pauseCommand: true,
_podKillCommand: true,
_podRmCommand: true,
_restartCommand: true,
_runCommand: true,
_unpauseCommand: true,
Expand Down
31 changes: 31 additions & 0 deletions cmd/podman/pod_rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package main

import (
"fmt"
"os"

"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/pkg/adapter"
"github.com/containers/libpod/pkg/rootless"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -46,11 +48,40 @@ func init() {

// podRmCmd deletes pods
func podRmCmd(c *cliconfig.PodRmValues) error {
if os.Geteuid() != 0 {
rootless.SetSkipStorageSetup(true)
}
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)

if rootless.IsRootless() {
var pod *adapter.Pod
if c.All || len(c.InputArgs) > 1 {
return errors.New("rootless mode doesn't support more than 1 pod")
}
if c.Latest {
pod, err = runtime.GetLatestPod()
if err != nil {
return errors.Wrapf(err, "unable to get latest pod")
}
} else {
pod, err = runtime.LookupPod(c.InputArgs[0])
if err != nil {
return err
}
}
became, ret, err := runtime.JoinOrCreateRootlessPod(pod)
if err != nil {
return err
}
if became {
os.Exit(ret)
}
}

podRmIds, podRmErrors := runtime.RemovePods(getContext(), c)
for _, p := range podRmIds {
fmt.Println(p)
Expand Down
37 changes: 37 additions & 0 deletions pkg/adapter/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,3 +337,40 @@ func IsImageNotFound(err error) bool {
func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (libpod.HealthCheckStatus, error) {
return r.Runtime.HealthCheck(c.InputArgs[0])
}

// JoinOrCreateRootlessPod joins the specified pod if it is running or it creates a new user namespace
// if the pod is stopped
func (r *LocalRuntime) JoinOrCreateRootlessPod(pod *Pod) (bool, int, error) {
if os.Geteuid() == 0 {
return false, 0, nil
}

inspect, err := pod.Inspect()
if err != nil {
return false, 0, err
}
for _, ctr := range inspect.Containers {
prevCtr, err := r.LookupContainer(ctr.ID)
if err != nil {
return false, -1, err
}
s, err := prevCtr.State()
if err != nil {
return false, -1, err
}
if s != libpod.ContainerStateRunning && s != libpod.ContainerStatePaused {
continue
}
data, err := ioutil.ReadFile(prevCtr.Config().ConmonPidFile)
if err != nil {
return false, -1, errors.Wrapf(err, "cannot read conmon PID file %q", prevCtr.Config().ConmonPidFile)
}
conmonPid, err := strconv.Atoi(string(data))
if err != nil {
return false, -1, errors.Wrapf(err, "cannot parse PID %q", data)
}
return rootless.JoinDirectUserAndMountNS(uint(conmonPid))
}

return rootless.BecomeRootInUserNS()
}
7 changes: 7 additions & 0 deletions pkg/adapter/runtime_remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -751,3 +751,10 @@ func IsImageNotFound(err error) bool {
func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (libpod.HealthCheckStatus, error) {
return -1, libpod.ErrNotImplemented
}

// JoinOrCreateRootlessPod joins the specified pod if it is running or it creates a new user namespace
// if the pod is stopped
func (r *LocalRuntime) JoinOrCreateRootlessPod(pod *Pod) (bool, int, error) {
// Nothing to do in the remote case
return true, 0, nil
}

0 comments on commit 414eeb1

Please sign in to comment.