diff options
-rw-r--r-- | .cirrus.yml | 10 | ||||
-rwxr-xr-x | contrib/cirrus/setup_environment.sh | 2 | ||||
-rw-r--r-- | test/e2e/run_privileged_test.go | 42 |
3 files changed, 40 insertions, 14 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 1bf35e142..06ed7c5e0 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -34,12 +34,12 @@ env: #### #### Cache-image names to test with (double-quotes around names are critical) ### - FEDORA_NAME: "fedora-32" - PRIOR_FEDORA_NAME: "fedora-31" - UBUNTU_NAME: "ubuntu-20" - PRIOR_UBUNTU_NAME: "ubuntu-19" + FEDORA_NAME: "fedora" + PRIOR_FEDORA_NAME: "prior-fedora" + UBUNTU_NAME: "ubuntu" + PRIOR_UBUNTU_NAME: "prior-ubuntu" - _BUILT_IMAGE_SUFFIX: "podman-6530021898584064" + _BUILT_IMAGE_SUFFIX: "c5809900649447424" FEDORA_CACHE_IMAGE_NAME: "${FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}" PRIOR_FEDORA_CACHE_IMAGE_NAME: "${PRIOR_FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}" UBUNTU_CACHE_IMAGE_NAME: "${UBUNTU_NAME}-${_BUILT_IMAGE_SUFFIX}" diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index e22f92a5b..855866477 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -68,7 +68,7 @@ case "$CG_FS_TYPE" in tmpfs) warn "Forcing testing with runc instead of crun" # On ubuntu, the default runc is usually not new enough. - if ${OS_RELEASE_ID} == "ubuntu"; then + if [[ "${OS_RELEASE_ID}" == "ubuntu" ]]; then X=$(echo "export OCI_RUNTIME=/usr/lib/cri-o-runc/sbin/runc" | \ tee -a /etc/environment) && eval "$X" && echo "$X" else diff --git a/test/e2e/run_privileged_test.go b/test/e2e/run_privileged_test.go index ca8da981f..064ba7d2c 100644 --- a/test/e2e/run_privileged_test.go +++ b/test/e2e/run_privileged_test.go @@ -2,13 +2,36 @@ package integration import ( "os" + "strconv" "strings" . "github.com/containers/podman/v2/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/syndtr/gocapability/capability" ) +// helper function for confirming that container capabilities are equal +// to those of the host, but only to the extent of caps we (podman) +// 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) { + ctr_cap_n, err := strconv.ParseUint(ctr_cap, 16, 64) + Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", ctr_cap) + + host_cap_n, err := strconv.ParseUint(host_cap, 16, 64) + Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", host_cap) + + // host caps can never be zero (except rootless, which we don't test). + // 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) +} + var _ = Describe("Podman privileged container tests", func() { var ( tempdir string @@ -44,24 +67,27 @@ var _ = Describe("Podman privileged container tests", func() { It("podman privileged CapEff", func() { SkipIfRootless() - cap := SystemExec("grep", []string{"CapEff", "/proc/self/status"}) - Expect(cap.ExitCode()).To(Equal(0)) + host_cap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"}) + Expect(host_cap.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"run", "--privileged", "busybox", "grep", "CapEff", "/proc/self/status"}) + session := podmanTest.Podman([]string{"run", "--privileged", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(session.OutputToString()).To(Equal(cap.OutputToString())) + + containerCapMatchesHost(session.OutputToString(), host_cap.OutputToString()) }) It("podman cap-add CapEff", func() { SkipIfRootless() - cap := SystemExec("grep", []string{"CapEff", "/proc/self/status"}) - Expect(cap.ExitCode()).To(Equal(0)) + // Get caps of current process + host_cap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"}) + Expect(host_cap.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"run", "--cap-add", "all", "busybox", "grep", "CapEff", "/proc/self/status"}) + session := podmanTest.Podman([]string{"run", "--cap-add", "all", "busybox", "awk", "/^CapEff/ { print $2 }", "/proc/self/status"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - Expect(session.OutputToString()).To(Equal(cap.OutputToString())) + + containerCapMatchesHost(session.OutputToString(), host_cap.OutputToString()) }) It("podman cap-drop CapEff", func() { |