github.com/blixtra/rkt@v0.8.1-0.20160204105720-ab0d1add1a43/tests/rkt_caps_test.go (about)

     1  // Copyright 2015 The rkt 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 main
    16  
    17  import (
    18  	"fmt"
    19  	"os"
    20  	"testing"
    21  
    22  	"github.com/coreos/rkt/tests/testutils"
    23  	"github.com/syndtr/gocapability/capability"
    24  )
    25  
    26  var capsTests = []struct {
    27  	testName            string
    28  	capIsolator         string
    29  	capa                capability.Cap
    30  	capInStage1Expected bool
    31  	capInStage2Expected bool
    32  	nonrootCapExpected  bool
    33  }{
    34  	{
    35  		testName:            "Check we don't have CAP_NET_ADMIN without isolator",
    36  		capIsolator:         "",
    37  		capa:                capability.CAP_NET_ADMIN,
    38  		capInStage1Expected: false,
    39  		capInStage2Expected: false,
    40  		nonrootCapExpected:  false,
    41  	},
    42  	{
    43  		testName:            "Check we have CAP_MKNOD without isolator",
    44  		capIsolator:         "",
    45  		capa:                capability.CAP_MKNOD,
    46  		capInStage1Expected: true,
    47  		capInStage2Expected: true,
    48  		nonrootCapExpected:  true,
    49  	},
    50  	{
    51  		testName:            "Check we have CAP_NET_ADMIN with an isolator",
    52  		capIsolator:         "CAP_NET_ADMIN,CAP_NET_BIND_SERVICE",
    53  		capa:                capability.CAP_NET_ADMIN,
    54  		capInStage1Expected: true,
    55  		capInStage2Expected: true,
    56  		nonrootCapExpected:  true,
    57  	},
    58  	{
    59  		testName:            "Check we have CAP_NET_BIND_SERVICE with an isolator",
    60  		capIsolator:         "CAP_NET_ADMIN,CAP_NET_BIND_SERVICE",
    61  		capa:                capability.CAP_NET_BIND_SERVICE,
    62  		capInStage1Expected: true,
    63  		capInStage2Expected: true,
    64  		nonrootCapExpected:  true,
    65  	},
    66  	{
    67  		testName:            "Check we don't have CAP_NET_ADMIN with an isolator setting CAP_NET_BIND_SERVICE",
    68  		capIsolator:         "CAP_NET_BIND_SERVICE",
    69  		capa:                capability.CAP_NET_ADMIN,
    70  		capInStage1Expected: false,
    71  		capInStage2Expected: false,
    72  		nonrootCapExpected:  false,
    73  	},
    74  }
    75  
    76  func TestCaps(t *testing.T) {
    77  	ctx := testutils.NewRktRunCtx()
    78  	defer ctx.Cleanup()
    79  
    80  	for i, tt := range capsTests {
    81  		stage1Args := []string{"--exec=/inspect --print-caps-pid=1 --print-user"}
    82  		stage2Args := []string{"--exec=/inspect --print-caps-pid=0 --print-user"}
    83  		if tt.capIsolator != "" {
    84  			stage1Args = append(stage1Args, "--capability="+tt.capIsolator)
    85  			stage2Args = append(stage2Args, "--capability="+tt.capIsolator)
    86  		}
    87  		stage1FileName := patchTestACI("rkt-inspect-print-caps-stage1.aci", stage1Args...)
    88  		defer os.Remove(stage1FileName)
    89  		stage2FileName := patchTestACI("rkt-inspect-print-caps-stage2.aci", stage2Args...)
    90  		defer os.Remove(stage2FileName)
    91  		stageFileNames := []string{stage1FileName, stage2FileName}
    92  
    93  		for _, stage := range []int{1, 2} {
    94  			t.Logf("Running test #%v: %v [stage %v]", i, tt.testName, stage)
    95  
    96  			cmd := fmt.Sprintf("%s --debug --insecure-options=image run --mds-register=false --set-env=CAPABILITY=%d %s", ctx.Cmd(), int(tt.capa), stageFileNames[stage-1])
    97  			child := spawnOrFail(t, cmd)
    98  
    99  			expectedLine := tt.capa.String()
   100  			if (stage == 1 && tt.capInStage1Expected) || (stage == 2 && tt.capInStage2Expected) {
   101  				expectedLine += "=enabled"
   102  			} else {
   103  				expectedLine += "=disabled"
   104  			}
   105  			if err := expectWithOutput(child, expectedLine); err != nil {
   106  				t.Fatalf("Expected %q but not found: %v", expectedLine, err)
   107  			}
   108  
   109  			if err := expectWithOutput(child, "User: uid=0 euid=0 gid=0 egid=0"); err != nil {
   110  				t.Fatalf("Expected user 0 but not found: %v", err)
   111  			}
   112  			waitOrFail(t, child, true)
   113  		}
   114  		ctx.Reset()
   115  	}
   116  }
   117  
   118  func TestCapsNonRoot(t *testing.T) {
   119  	ctx := testutils.NewRktRunCtx()
   120  	defer ctx.Cleanup()
   121  
   122  	for i, tt := range capsTests {
   123  		args := []string{"--exec=/inspect --print-caps-pid=0 --print-user", "--user=9000", "--group=9000"}
   124  		if tt.capIsolator != "" {
   125  			args = append(args, "--capability="+tt.capIsolator)
   126  		}
   127  		fileName := patchTestACI("rkt-inspect-print-caps-nonroot.aci", args...)
   128  		defer os.Remove(fileName)
   129  
   130  		t.Logf("Running test #%v: %v [non-root]", i, tt.testName)
   131  
   132  		cmd := fmt.Sprintf("%s --debug --insecure-options=image run --mds-register=false --set-env=CAPABILITY=%d %s", ctx.Cmd(), int(tt.capa), fileName)
   133  		child := spawnOrFail(t, cmd)
   134  
   135  		expectedLine := tt.capa.String()
   136  		if tt.nonrootCapExpected {
   137  			expectedLine += "=enabled"
   138  		} else {
   139  			expectedLine += "=disabled"
   140  		}
   141  		if err := expectWithOutput(child, expectedLine); err != nil {
   142  			t.Fatalf("Expected %q but not found: %v", expectedLine, err)
   143  		}
   144  
   145  		if err := expectWithOutput(child, "User: uid=9000 euid=9000 gid=9000 egid=9000"); err != nil {
   146  			t.Fatalf("Expected user 9000 but not found: %v", err)
   147  		}
   148  
   149  		waitOrFail(t, child, true)
   150  		ctx.Reset()
   151  	}
   152  }