github.com/AbhinandanKurakure/podman/v3@v3.4.10/test/e2e/run_privileged_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"os"
     5  	"strconv"
     6  	"strings"
     7  
     8  	. "github.com/containers/podman/v3/test/utils"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  	. "github.com/onsi/gomega/gexec"
    12  	"github.com/syndtr/gocapability/capability"
    13  )
    14  
    15  // helper function for confirming that container capabilities are equal
    16  // to those of the host, but only to the extent of caps we (podman)
    17  // know about at compile time. That is: the kernel may have more caps
    18  // available than we are aware of, leading to host=FFF... and ctr=3FF...
    19  // because the latter is all we request. Accept that.
    20  func containerCapMatchesHost(ctrCap string, hostCap string) {
    21  	if isRootless() {
    22  		return
    23  	}
    24  	ctrCap_n, err := strconv.ParseUint(ctrCap, 16, 64)
    25  	Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", ctrCap)
    26  
    27  	hostCap_n, err := strconv.ParseUint(hostCap, 16, 64)
    28  	Expect(err).NotTo(HaveOccurred(), "Error parsing %q as hex", hostCap)
    29  
    30  	// host caps can never be zero (except rootless).
    31  	// and host caps must always be a superset (inclusive) of container
    32  	Expect(hostCap_n).To(BeNumerically(">", 0), "host cap %q should be nonzero", hostCap)
    33  	Expect(hostCap_n).To(BeNumerically(">=", ctrCap_n), "host cap %q should never be less than container cap %q", hostCap, ctrCap)
    34  	hostCap_masked := hostCap_n & (1<<len(capability.List()) - 1)
    35  	Expect(ctrCap_n).To(Equal(hostCap_masked), "container cap %q is not a subset of host cap %q", ctrCap, hostCap)
    36  }
    37  
    38  var _ = Describe("Podman privileged container tests", func() {
    39  	var (
    40  		tempdir    string
    41  		err        error
    42  		podmanTest *PodmanTestIntegration
    43  	)
    44  
    45  	BeforeEach(func() {
    46  		tempdir, err = CreateTempDirInTempDir()
    47  		if err != nil {
    48  			os.Exit(1)
    49  		}
    50  		podmanTest = PodmanTestCreate(tempdir)
    51  		podmanTest.Setup()
    52  		podmanTest.SeedImages()
    53  	})
    54  
    55  	AfterEach(func() {
    56  		podmanTest.Cleanup()
    57  		f := CurrentGinkgoTestDescription()
    58  		processTestResult(f)
    59  
    60  	})
    61  
    62  	It("podman privileged make sure sys is mounted rw", func() {
    63  		session := podmanTest.Podman([]string{"run", "--privileged", BB, "mount"})
    64  		session.WaitWithDefaultTimeout()
    65  		Expect(session).Should(Exit(0))
    66  		ok, lines := session.GrepString("sysfs")
    67  		Expect(ok).To(BeTrue())
    68  		Expect(lines[0]).To(ContainSubstring("sysfs (rw,"))
    69  	})
    70  
    71  	It("podman privileged CapEff", func() {
    72  		hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
    73  		Expect(hostCap).Should(Exit(0))
    74  
    75  		session := podmanTest.Podman([]string{"run", "--privileged", BB, "awk", "/^CapEff/ { print $2 }", "/proc/self/status"})
    76  		session.WaitWithDefaultTimeout()
    77  		Expect(session).Should(Exit(0))
    78  
    79  		containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
    80  	})
    81  
    82  	It("podman cap-add CapEff", func() {
    83  		// Get caps of current process
    84  		hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
    85  		Expect(hostCap).Should(Exit(0))
    86  
    87  		session := podmanTest.Podman([]string{"run", "--cap-add", "all", BB, "awk", "/^CapEff/ { print $2 }", "/proc/self/status"})
    88  		session.WaitWithDefaultTimeout()
    89  		Expect(session).Should(Exit(0))
    90  
    91  		containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
    92  	})
    93  
    94  	It("podman cap-add CapEff with --user", func() {
    95  		// Get caps of current process
    96  		hostCap := SystemExec("awk", []string{"/^CapEff/ { print $2 }", "/proc/self/status"})
    97  		Expect(hostCap).Should(Exit(0))
    98  
    99  		session := podmanTest.Podman([]string{"run", "--user=bin", "--cap-add", "all", BB, "awk", "/^CapEff/ { print $2 }", "/proc/self/status"})
   100  		session.WaitWithDefaultTimeout()
   101  		Expect(session).Should(Exit(0))
   102  
   103  		containerCapMatchesHost(session.OutputToString(), hostCap.OutputToString())
   104  	})
   105  
   106  	It("podman cap-drop CapEff", func() {
   107  		session := podmanTest.Podman([]string{"run", "--cap-drop", "all", BB, "grep", "CapEff", "/proc/self/status"})
   108  		session.WaitWithDefaultTimeout()
   109  		Expect(session).Should(Exit(0))
   110  		capEff := strings.Split(session.OutputToString(), " ")
   111  		Expect("0000000000000000").To(Equal(capEff[1]))
   112  	})
   113  
   114  	It("podman privileged should disable seccomp by default", func() {
   115  		hostSeccomp := SystemExec("grep", []string{"-Ei", "^Seccomp:\\s+0$", "/proc/self/status"})
   116  		Expect(hostSeccomp).Should(Exit(0))
   117  
   118  		session := podmanTest.Podman([]string{"run", "--privileged", ALPINE, "grep", "-Ei", "^Seccomp:\\s+0$", "/proc/self/status"})
   119  		session.WaitWithDefaultTimeout()
   120  		Expect(session).Should(Exit(0))
   121  	})
   122  
   123  	It("podman non-privileged should have very few devices", func() {
   124  		session := podmanTest.Podman([]string{"run", "-t", BB, "ls", "-l", "/dev"})
   125  		session.WaitWithDefaultTimeout()
   126  		Expect(session).Should(Exit(0))
   127  		Expect(len(session.OutputToStringArray())).To(Equal(17))
   128  	})
   129  
   130  	It("podman privileged should inherit host devices", func() {
   131  		SkipIfRootless("FIXME: This seems to be broken for rootless mode, /dev/ is close to the same")
   132  		session := podmanTest.Podman([]string{"run", "--privileged", ALPINE, "ls", "-l", "/dev"})
   133  		session.WaitWithDefaultTimeout()
   134  		Expect(session).Should(Exit(0))
   135  		Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 20))
   136  	})
   137  
   138  	It("run no-new-privileges test", func() {
   139  		// Check if our kernel is new enough
   140  		k, err := IsKernelNewerThan("4.14")
   141  		Expect(err).To(BeNil())
   142  		if !k {
   143  			Skip("Kernel is not new enough to test this feature")
   144  		}
   145  
   146  		cap := SystemExec("grep", []string{"NoNewPrivs", "/proc/self/status"})
   147  		if cap.ExitCode() != 0 {
   148  			Skip("Can't determine NoNewPrivs")
   149  		}
   150  
   151  		session := podmanTest.Podman([]string{"run", BB, "grep", "NoNewPrivs", "/proc/self/status"})
   152  		session.WaitWithDefaultTimeout()
   153  		Expect(session).Should(Exit(0))
   154  
   155  		privs := strings.Split(session.OutputToString(), ":")
   156  		session = podmanTest.Podman([]string{"run", "--security-opt", "no-new-privileges", BB, "grep", "NoNewPrivs", "/proc/self/status"})
   157  		session.WaitWithDefaultTimeout()
   158  		Expect(session).Should(Exit(0))
   159  
   160  		noprivs := strings.Split(session.OutputToString(), ":")
   161  		Expect(privs[1]).To(Not(Equal(noprivs[1])))
   162  	})
   163  
   164  })