mirror of
https://github.com/containers/podman.git
synced 2025-08-06 11:32:07 +08:00
Merge pull request #8823 from giuseppe/exec-honor-privileged
exec: honor --privileged
This commit is contained in:
@ -387,7 +387,7 @@ func (r *ConmonOCIRuntime) startExec(c *Container, sessionID string, options *Ex
|
||||
finalEnv = append(finalEnv, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
|
||||
processFile, err := prepareProcessExec(c, options.Cmd, finalEnv, options.Terminal, options.Cwd, options.User, sessionID)
|
||||
processFile, err := prepareProcessExec(c, options, finalEnv, sessionID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -1185,26 +1185,33 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
|
||||
|
||||
// prepareProcessExec returns the path of the process.json used in runc exec -p
|
||||
// caller is responsible to close the returned *os.File if needed.
|
||||
func prepareProcessExec(c *Container, cmd, env []string, tty bool, cwd, user, sessionID string) (*os.File, error) {
|
||||
func prepareProcessExec(c *Container, options *ExecOptions, env []string, sessionID string) (*os.File, error) {
|
||||
f, err := ioutil.TempFile(c.execBundlePath(sessionID), "exec-process-")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pspec := c.config.Spec.Process
|
||||
pspec.SelinuxLabel = c.config.ProcessLabel
|
||||
pspec.Args = cmd
|
||||
pspec.Args = options.Cmd
|
||||
for _, cap := range options.CapAdd {
|
||||
pspec.Capabilities.Bounding = append(pspec.Capabilities.Bounding, cap)
|
||||
pspec.Capabilities.Effective = append(pspec.Capabilities.Effective, cap)
|
||||
pspec.Capabilities.Inheritable = append(pspec.Capabilities.Inheritable, cap)
|
||||
pspec.Capabilities.Permitted = append(pspec.Capabilities.Permitted, cap)
|
||||
pspec.Capabilities.Ambient = append(pspec.Capabilities.Ambient, cap)
|
||||
}
|
||||
// We need to default this to false else it will inherit terminal as true
|
||||
// from the container.
|
||||
pspec.Terminal = false
|
||||
if tty {
|
||||
if options.Terminal {
|
||||
pspec.Terminal = true
|
||||
}
|
||||
if len(env) > 0 {
|
||||
pspec.Env = append(pspec.Env, env...)
|
||||
}
|
||||
|
||||
if cwd != "" {
|
||||
pspec.Cwd = cwd
|
||||
if options.Cwd != "" {
|
||||
pspec.Cwd = options.Cwd
|
||||
|
||||
}
|
||||
|
||||
@ -1212,6 +1219,7 @@ func prepareProcessExec(c *Container, cmd, env []string, tty bool, cwd, user, se
|
||||
var sgids []uint32
|
||||
|
||||
// if the user is empty, we should inherit the user that the container is currently running with
|
||||
user := options.User
|
||||
if user == "" {
|
||||
user = c.config.User
|
||||
addGroups = c.config.Groups
|
||||
|
@ -119,6 +119,21 @@ var _ = Describe("Podman exec", func() {
|
||||
Expect(session.ExitCode()).To(Equal(100))
|
||||
})
|
||||
|
||||
It("podman exec --privileged", func() {
|
||||
hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
Expect(hostCap.ExitCode()).To(Equal(0))
|
||||
|
||||
setup := podmanTest.RunTopContainer("test-privileged")
|
||||
setup.WaitWithDefaultTimeout()
|
||||
Expect(setup.ExitCode()).To(Equal(0))
|
||||
|
||||
session := podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
|
||||
})
|
||||
|
||||
It("podman exec terminal doesn't hang", func() {
|
||||
setup := podmanTest.Podman([]string{"run", "-dti", "--name", "test1", fedoraMinimal, "sleep", "+Inf"})
|
||||
setup.WaitWithDefaultTimeout()
|
||||
|
@ -16,22 +16,22 @@ import (
|
||||
// know about at compile time. That is: the kernel may have more caps
|
||||
// available than we are aware of, leading to host=FFF... and ctr=3FF...
|
||||
// because the latter is all we request. Accept that.
|
||||
func containerCapMatchesHost(ctr_cap string, host_cap string) {
|
||||
func containerCapMatchesHost(ctrCap string, hostCap string) {
|
||||
if isRootless() {
|
||||
return
|
||||
}
|
||||
ctr_cap_n, err := strconv.ParseUint(ctr_cap, 16, 64)
|
||||
Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", ctr_cap)
|
||||
ctrCap_n, err := strconv.ParseUint(ctrCap, 16, 64)
|
||||
Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", ctrCap)
|
||||
|
||||
host_cap_n, err := strconv.ParseUint(host_cap, 16, 64)
|
||||
Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", host_cap)
|
||||
hostCap_n, err := strconv.ParseUint(hostCap, 16, 64)
|
||||
Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", hostCap)
|
||||
|
||||
// host caps can never be zero (except rootless).
|
||||
// and host caps must always be a superset (inclusive) of container
|
||||
Expect(host_cap_n).To(BeNumerically(">", 0), "host cap %q should be nonzero", host_cap)
|
||||
Expect(host_cap_n).To(BeNumerically(">=", ctr_cap_n), "host cap %q should never be less than container cap %q", host_cap, ctr_cap)
|
||||
host_cap_masked := host_cap_n & (1<<len(capability.List()) - 1)
|
||||
Expect(ctr_cap_n).To(Equal(host_cap_masked), "container cap %q is not a subset of host cap %q", ctr_cap, host_cap)
|
||||
Expect(hostCap_n).To(BeNumerically(">", 0), "host cap %q should be nonzero", hostCap)
|
||||
Expect(hostCap_n).To(BeNumerically(">=", ctrCap_n), "host cap %q should never be less than container cap %q", hostCap, ctrCap)
|
||||
hostCap_masked := hostCap_n & (1<<len(capability.List()) - 1)
|
||||
Expect(ctrCap_n).To(Equal(hostCap_masked), "container cap %q is not a subset of host cap %q", ctrCap, hostCap)
|
||||
}
|
||||
|
||||
var _ = Describe("Podman privileged container tests", func() {
|
||||
@ -68,38 +68,38 @@ var _ = Describe("Podman privileged container tests", func() {
|
||||
})
|
||||
|
||||
It("podman privileged CapEff", func() {
|
||||
host_cap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
Expect(host_cap.ExitCode()).To(Equal(0))
|
||||
hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
Expect(hostCap.ExitCode()).To(Equal(0))
|
||||
|
||||
session := podmanTest.Podman([]string{"run", "--privileged", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
containerCapMatchesHost(session.OutputToString(), host_cap.OutputToString())
|
||||
containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
|
||||
})
|
||||
|
||||
It("podman cap-add CapEff", func() {
|
||||
// Get caps of current process
|
||||
host_cap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
Expect(host_cap.ExitCode()).To(Equal(0))
|
||||
hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
Expect(hostCap.ExitCode()).To(Equal(0))
|
||||
|
||||
session := podmanTest.Podman([]string{"run", "--cap-add", "all", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
containerCapMatchesHost(session.OutputToString(), host_cap.OutputToString())
|
||||
containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
|
||||
})
|
||||
|
||||
It("podman cap-add CapEff with --user", func() {
|
||||
// Get caps of current process
|
||||
host_cap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
Expect(host_cap.ExitCode()).To(Equal(0))
|
||||
hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
Expect(hostCap.ExitCode()).To(Equal(0))
|
||||
|
||||
session := podmanTest.Podman([]string{"run", "--user=bin", "--cap-add", "all", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
containerCapMatchesHost(session.OutputToString(), host_cap.OutputToString())
|
||||
containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
|
||||
})
|
||||
|
||||
It("podman cap-drop CapEff", func() {
|
||||
|
Reference in New Issue
Block a user