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  }