Skip to content

Commit 23f25b8

Browse files
Merge pull request #8823 from giuseppe/exec-honor-privileged
exec: honor --privileged
2 parents 142b4ac + b3bd37b commit 23f25b8

File tree

4 files changed

+47
-24
lines changed

4 files changed

+47
-24
lines changed

libpod/oci_conmon_exec_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ func (r *ConmonOCIRuntime) startExec(c *Container, sessionID string, options *Ex
387387
finalEnv = append(finalEnv, fmt.Sprintf("%s=%s", k, v))
388388
}
389389

390-
processFile, err := prepareProcessExec(c, options.Cmd, finalEnv, options.Terminal, options.Cwd, options.User, sessionID)
390+
processFile, err := prepareProcessExec(c, options, finalEnv, sessionID)
391391
if err != nil {
392392
return nil, nil, err
393393
}

libpod/oci_conmon_linux.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,33 +1185,41 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
11851185

11861186
// prepareProcessExec returns the path of the process.json used in runc exec -p
11871187
// caller is responsible to close the returned *os.File if needed.
1188-
func prepareProcessExec(c *Container, cmd, env []string, tty bool, cwd, user, sessionID string) (*os.File, error) {
1188+
func prepareProcessExec(c *Container, options *ExecOptions, env []string, sessionID string) (*os.File, error) {
11891189
f, err := ioutil.TempFile(c.execBundlePath(sessionID), "exec-process-")
11901190
if err != nil {
11911191
return nil, err
11921192
}
11931193
pspec := c.config.Spec.Process
11941194
pspec.SelinuxLabel = c.config.ProcessLabel
1195-
pspec.Args = cmd
1195+
pspec.Args = options.Cmd
1196+
for _, cap := range options.CapAdd {
1197+
pspec.Capabilities.Bounding = append(pspec.Capabilities.Bounding, cap)
1198+
pspec.Capabilities.Effective = append(pspec.Capabilities.Effective, cap)
1199+
pspec.Capabilities.Inheritable = append(pspec.Capabilities.Inheritable, cap)
1200+
pspec.Capabilities.Permitted = append(pspec.Capabilities.Permitted, cap)
1201+
pspec.Capabilities.Ambient = append(pspec.Capabilities.Ambient, cap)
1202+
}
11961203
// We need to default this to false else it will inherit terminal as true
11971204
// from the container.
11981205
pspec.Terminal = false
1199-
if tty {
1206+
if options.Terminal {
12001207
pspec.Terminal = true
12011208
}
12021209
if len(env) > 0 {
12031210
pspec.Env = append(pspec.Env, env...)
12041211
}
12051212

1206-
if cwd != "" {
1207-
pspec.Cwd = cwd
1213+
if options.Cwd != "" {
1214+
pspec.Cwd = options.Cwd
12081215

12091216
}
12101217

12111218
var addGroups []string
12121219
var sgids []uint32
12131220

12141221
// if the user is empty, we should inherit the user that the container is currently running with
1222+
user := options.User
12151223
if user == "" {
12161224
user = c.config.User
12171225
addGroups = c.config.Groups

test/e2e/exec_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ var _ = Describe("Podman exec", func() {
119119
Expect(session.ExitCode()).To(Equal(100))
120120
})
121121

122+
It("podman exec --privileged", func() {
123+
hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
124+
Expect(hostCap.ExitCode()).To(Equal(0))
125+
126+
setup := podmanTest.RunTopContainer("test-privileged")
127+
setup.WaitWithDefaultTimeout()
128+
Expect(setup.ExitCode()).To(Equal(0))
129+
130+
session := podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
131+
session.WaitWithDefaultTimeout()
132+
Expect(session.ExitCode()).To(Equal(0))
133+
134+
containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
135+
})
136+
122137
It("podman exec terminal doesn't hang", func() {
123138
setup := podmanTest.Podman([]string{"run", "-dti", "--name", "test1", fedoraMinimal, "sleep", "+Inf"})
124139
setup.WaitWithDefaultTimeout()

test/e2e/run_privileged_test.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,22 @@ import (
1616
// know about at compile time. That is: the kernel may have more caps
1717
// available than we are aware of, leading to host=FFF... and ctr=3FF...
1818
// because the latter is all we request. Accept that.
19-
func containerCapMatchesHost(ctr_cap string, host_cap string) {
19+
func containerCapMatchesHost(ctrCap string, hostCap string) {
2020
if isRootless() {
2121
return
2222
}
23-
ctr_cap_n, err := strconv.ParseUint(ctr_cap, 16, 64)
24-
Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", ctr_cap)
23+
ctrCap_n, err := strconv.ParseUint(ctrCap, 16, 64)
24+
Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", ctrCap)
2525

26-
host_cap_n, err := strconv.ParseUint(host_cap, 16, 64)
27-
Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", host_cap)
26+
hostCap_n, err := strconv.ParseUint(hostCap, 16, 64)
27+
Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", hostCap)
2828

2929
// host caps can never be zero (except rootless).
3030
// and host caps must always be a superset (inclusive) of container
31-
Expect(host_cap_n).To(BeNumerically(">", 0), "host cap %q should be nonzero", host_cap)
32-
Expect(host_cap_n).To(BeNumerically(">=", ctr_cap_n), "host cap %q should never be less than container cap %q", host_cap, ctr_cap)
33-
host_cap_masked := host_cap_n & (1<<len(capability.List()) - 1)
34-
Expect(ctr_cap_n).To(Equal(host_cap_masked), "container cap %q is not a subset of host cap %q", ctr_cap, host_cap)
31+
Expect(hostCap_n).To(BeNumerically(">", 0), "host cap %q should be nonzero", hostCap)
32+
Expect(hostCap_n).To(BeNumerically(">=", ctrCap_n), "host cap %q should never be less than container cap %q", hostCap, ctrCap)
33+
hostCap_masked := hostCap_n & (1<<len(capability.List()) - 1)
34+
Expect(ctrCap_n).To(Equal(hostCap_masked), "container cap %q is not a subset of host cap %q", ctrCap, hostCap)
3535
}
3636

3737
var _ = Describe("Podman privileged container tests", func() {
@@ -68,38 +68,38 @@ var _ = Describe("Podman privileged container tests", func() {
6868
})
6969

7070
It("podman privileged CapEff", func() {
71-
host_cap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
72-
Expect(host_cap.ExitCode()).To(Equal(0))
71+
hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
72+
Expect(hostCap.ExitCode()).To(Equal(0))
7373

7474
session := podmanTest.Podman([]string{"run", "--privileged", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"})
7575
session.WaitWithDefaultTimeout()
7676
Expect(session.ExitCode()).To(Equal(0))
7777

78-
containerCapMatchesHost(session.OutputToString(), host_cap.OutputToString())
78+
containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
7979
})
8080

8181
It("podman cap-add CapEff", func() {
8282
// Get caps of current process
83-
host_cap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
84-
Expect(host_cap.ExitCode()).To(Equal(0))
83+
hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
84+
Expect(hostCap.ExitCode()).To(Equal(0))
8585

8686
session := podmanTest.Podman([]string{"run", "--cap-add", "all", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"})
8787
session.WaitWithDefaultTimeout()
8888
Expect(session.ExitCode()).To(Equal(0))
8989

90-
containerCapMatchesHost(session.OutputToString(), host_cap.OutputToString())
90+
containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
9191
})
9292

9393
It("podman cap-add CapEff with --user", func() {
9494
// Get caps of current process
95-
host_cap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
96-
Expect(host_cap.ExitCode()).To(Equal(0))
95+
hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
96+
Expect(hostCap.ExitCode()).To(Equal(0))
9797

9898
session := podmanTest.Podman([]string{"run", "--user=bin", "--cap-add", "all", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"})
9999
session.WaitWithDefaultTimeout()
100100
Expect(session.ExitCode()).To(Equal(0))
101101

102-
containerCapMatchesHost(session.OutputToString(), host_cap.OutputToString())
102+
containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
103103
})
104104

105105
It("podman cap-drop CapEff", func() {

0 commit comments

Comments
 (0)