github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/runsc/cmd/capability_test.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cmd 16 17 import ( 18 "flag" 19 "fmt" 20 "os" 21 "testing" 22 23 specs "github.com/opencontainers/runtime-spec/specs-go" 24 "github.com/syndtr/gocapability/capability" 25 "github.com/SagerNet/gvisor/pkg/log" 26 "github.com/SagerNet/gvisor/pkg/test/testutil" 27 "github.com/SagerNet/gvisor/runsc/config" 28 "github.com/SagerNet/gvisor/runsc/container" 29 "github.com/SagerNet/gvisor/runsc/specutils" 30 ) 31 32 func init() { 33 log.SetLevel(log.Debug) 34 if err := testutil.ConfigureExePath(); err != nil { 35 panic(err.Error()) 36 } 37 } 38 39 func checkProcessCaps(pid int, wantCaps *specs.LinuxCapabilities) error { 40 curCaps, err := capability.NewPid2(pid) 41 if err != nil { 42 return fmt.Errorf("capability.NewPid2(%d) failed: %v", pid, err) 43 } 44 if err := curCaps.Load(); err != nil { 45 return fmt.Errorf("unable to load capabilities: %v", err) 46 } 47 fmt.Printf("Capabilities (PID: %d): %v\n", pid, curCaps) 48 49 for _, c := range allCapTypes { 50 if err := checkCaps(c, curCaps, wantCaps); err != nil { 51 return err 52 } 53 } 54 return nil 55 } 56 57 func checkCaps(which capability.CapType, curCaps capability.Capabilities, wantCaps *specs.LinuxCapabilities) error { 58 wantNames := getCaps(which, wantCaps) 59 for name, c := range capFromName { 60 want := specutils.ContainsStr(wantNames, name) 61 got := curCaps.Get(which, c) 62 if want != got { 63 if want { 64 return fmt.Errorf("capability %v:%s should be set", which, name) 65 } 66 return fmt.Errorf("capability %v:%s should NOT be set", which, name) 67 } 68 } 69 return nil 70 } 71 72 func TestCapabilities(t *testing.T) { 73 stop := testutil.StartReaper() 74 defer stop() 75 76 spec := testutil.NewSpecWithArgs("/bin/sleep", "10000") 77 caps := []string{ 78 "CAP_CHOWN", 79 "CAP_SYS_PTRACE", // ptrace is added due to the platform choice. 80 } 81 spec.Process.Capabilities = &specs.LinuxCapabilities{ 82 Permitted: caps, 83 Bounding: caps, 84 Effective: caps, 85 Inheritable: caps, 86 } 87 88 conf := testutil.TestConfig(t) 89 90 // Use --network=host to make sandbox use spec's capabilities. 91 conf.Network = config.NetworkHost 92 93 _, bundleDir, cleanup, err := testutil.SetupContainer(spec, conf) 94 if err != nil { 95 t.Fatalf("error setting up container: %v", err) 96 } 97 defer cleanup() 98 99 // Create and start the container. 100 args := container.Args{ 101 ID: testutil.RandomContainerID(), 102 Spec: spec, 103 BundleDir: bundleDir, 104 } 105 c, err := container.New(conf, args) 106 if err != nil { 107 t.Fatalf("error creating container: %v", err) 108 } 109 defer c.Destroy() 110 if err := c.Start(conf); err != nil { 111 t.Fatalf("error starting container: %v", err) 112 } 113 114 // Check that sandbox and gofer have the proper capabilities. 115 if err := checkProcessCaps(c.Sandbox.Pid, spec.Process.Capabilities); err != nil { 116 t.Error(err) 117 } 118 if err := checkProcessCaps(c.GoferPid, goferCaps); err != nil { 119 t.Error(err) 120 } 121 } 122 123 func TestMain(m *testing.M) { 124 flag.Parse() 125 specutils.MaybeRunAsRoot() 126 os.Exit(m.Run()) 127 }