Specifying --ipc=host --pid=host is broken

For some reason we were overwriting memory when handling both
--pid=host and --ipc=host.  Simplified the code to handle this
correctly, and add test to make sure it does not happen again.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2020-07-28 09:18:21 -04:00
parent 288ebec6e7
commit bb4d269087
4 changed files with 75 additions and 24 deletions

View File

@ -10,7 +10,7 @@ type ContainerCLIOpts struct {
BlkIOWeightDevice []string BlkIOWeightDevice []string
CapAdd []string CapAdd []string
CapDrop []string CapDrop []string
CGroupsNS string CgroupNS string
CGroupsMode string CGroupsMode string
CGroupParent string CGroupParent string
CIDFile string CIDFile string

View File

@ -186,6 +186,46 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.Linu
return memory, nil return memory, nil
} }
func setNamespaces(s *specgen.SpecGenerator, c *ContainerCLIOpts) error {
var err error
if c.PID != "" {
s.PidNS, err = specgen.ParseNamespace(c.PID)
if err != nil {
return err
}
}
if c.IPC != "" {
s.IpcNS, err = specgen.ParseNamespace(c.IPC)
if err != nil {
return err
}
}
if c.UTS != "" {
s.UtsNS, err = specgen.ParseNamespace(c.UTS)
if err != nil {
return err
}
}
if c.CgroupNS != "" {
s.CgroupNS, err = specgen.ParseNamespace(c.CgroupNS)
if err != nil {
return err
}
}
// userns must be treated differently
if c.UserNS != "" {
s.UserNS, err = specgen.ParseUserNamespace(c.UserNS)
if err != nil {
return err
}
}
if c.Net != nil {
s.NetNS = c.Net.Network
}
return nil
}
func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) error { func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) error {
var ( var (
err error err error
@ -252,28 +292,8 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
} }
s.Expose = expose s.Expose = expose
for k, v := range map[string]*specgen.Namespace{ if err := setNamespaces(s, c); err != nil {
c.IPC: &s.IpcNS, return err
c.PID: &s.PidNS,
c.UTS: &s.UtsNS,
c.CGroupsNS: &s.CgroupNS,
} {
if k != "" {
*v, err = specgen.ParseNamespace(k)
if err != nil {
return err
}
}
}
// userns must be treated differently
if c.UserNS != "" {
s.UserNS, err = specgen.ParseUserNamespace(c.UserNS)
if err != nil {
return err
}
}
if c.Net != nil {
s.NetNS = c.Net.Network
} }
if sig := c.StopSignal; len(sig) > 0 { if sig := c.StopSignal; len(sig) > 0 {

View File

@ -195,7 +195,7 @@ func createInit(c *cobra.Command) error {
cliVals.IPC = c.Flag("ipc").Value.String() cliVals.IPC = c.Flag("ipc").Value.String()
cliVals.UTS = c.Flag("uts").Value.String() cliVals.UTS = c.Flag("uts").Value.String()
cliVals.PID = c.Flag("pid").Value.String() cliVals.PID = c.Flag("pid").Value.String()
cliVals.CGroupsNS = c.Flag("cgroupns").Value.String() cliVals.CgroupNS = c.Flag("cgroupns").Value.String()
if c.Flag("entrypoint").Changed { if c.Flag("entrypoint").Changed {
val := c.Flag("entrypoint").Value.String() val := c.Flag("entrypoint").Value.String()
cliVals.Entrypoint = &val cliVals.Entrypoint = &val

View File

@ -2,6 +2,7 @@ package integration
import ( import (
"os" "os"
"os/exec"
"strings" "strings"
. "github.com/containers/podman/v2/test/utils" . "github.com/containers/podman/v2/test/utils"
@ -102,4 +103,34 @@ var _ = Describe("Podman run ns", func() {
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError()) Expect(session).To(ExitWithError())
}) })
It("podman run --ipc=host --pid=host", func() {
cmd := exec.Command("ls", "-l", "/proc/self/ns/pid")
res, err := cmd.Output()
Expect(err).To(BeNil())
fields := strings.Split(string(res), " ")
hostPidNS := strings.TrimSuffix(fields[len(fields)-1], "\n")
cmd = exec.Command("ls", "-l", "/proc/self/ns/ipc")
res, err = cmd.Output()
Expect(err).To(BeNil())
fields = strings.Split(string(res), " ")
hostIpcNS := strings.TrimSuffix(fields[len(fields)-1], "\n")
session := podmanTest.Podman([]string{"run", "--ipc=host", "--pid=host", ALPINE, "ls", "-l", "/proc/self/ns/pid"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
fields = strings.Split(session.OutputToString(), " ")
ctrPidNS := strings.TrimSuffix(fields[len(fields)-1], "\n")
session = podmanTest.Podman([]string{"run", "--ipc=host", "--pid=host", ALPINE, "ls", "-l", "/proc/self/ns/ipc"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
fields = strings.Split(session.OutputToString(), " ")
ctrIpcNS := strings.TrimSuffix(fields[len(fields)-1], "\n")
Expect(hostPidNS).To(Equal(ctrPidNS))
Expect(hostIpcNS).To(Equal(ctrIpcNS))
})
}) })