github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/runsc/cmd/exec_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  	"os"
    19  	"testing"
    20  
    21  	"github.com/google/go-cmp/cmp"
    22  	"github.com/google/go-cmp/cmp/cmpopts"
    23  	specs "github.com/opencontainers/runtime-spec/specs-go"
    24  	"github.com/SagerNet/gvisor/pkg/abi/linux"
    25  	"github.com/SagerNet/gvisor/pkg/sentry/control"
    26  	"github.com/SagerNet/gvisor/pkg/sentry/kernel/auth"
    27  	"github.com/SagerNet/gvisor/pkg/urpc"
    28  )
    29  
    30  func TestUser(t *testing.T) {
    31  	testCases := []struct {
    32  		input   string
    33  		want    user
    34  		wantErr bool
    35  	}{
    36  		{input: "0", want: user{kuid: 0, kgid: 0}},
    37  		{input: "7", want: user{kuid: 7, kgid: 0}},
    38  		{input: "49:343", want: user{kuid: 49, kgid: 343}},
    39  		{input: "0:2401", want: user{kuid: 0, kgid: 2401}},
    40  		{input: "", wantErr: true},
    41  		{input: "foo", wantErr: true},
    42  		{input: ":123", wantErr: true},
    43  		{input: "1:2:3", wantErr: true},
    44  	}
    45  
    46  	for _, tc := range testCases {
    47  		var u user
    48  		if err := u.Set(tc.input); err != nil && tc.wantErr {
    49  			// We got an error and wanted one.
    50  			continue
    51  		} else if err == nil && tc.wantErr {
    52  			t.Errorf("user.Set(%s): got no error, but wanted one", tc.input)
    53  		} else if err != nil && !tc.wantErr {
    54  			t.Errorf("user.Set(%s): got error %v, but wanted none", tc.input, err)
    55  		} else if u != tc.want {
    56  			t.Errorf("user.Set(%s): got %+v, but wanted %+v", tc.input, u, tc.want)
    57  		}
    58  	}
    59  }
    60  
    61  func TestCLIArgs(t *testing.T) {
    62  	testCases := []struct {
    63  		ex       Exec
    64  		argv     []string
    65  		expected control.ExecArgs
    66  	}{
    67  		{
    68  			ex: Exec{
    69  				cwd:         "/foo/bar",
    70  				user:        user{kuid: 0, kgid: 0},
    71  				extraKGIDs:  []string{"1", "2", "3"},
    72  				caps:        []string{"CAP_DAC_OVERRIDE"},
    73  				processPath: "",
    74  			},
    75  			argv: []string{"ls", "/"},
    76  			expected: control.ExecArgs{
    77  				Argv:             []string{"ls", "/"},
    78  				WorkingDirectory: "/foo/bar",
    79  				FilePayload:      urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}},
    80  				KUID:             0,
    81  				KGID:             0,
    82  				ExtraKGIDs:       []auth.KGID{1, 2, 3},
    83  				Capabilities: &auth.TaskCapabilities{
    84  					BoundingCaps:    auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
    85  					EffectiveCaps:   auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
    86  					InheritableCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
    87  					PermittedCaps:   auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
    88  				},
    89  			},
    90  		},
    91  	}
    92  
    93  	for _, tc := range testCases {
    94  		e, err := tc.ex.argsFromCLI(tc.argv, true)
    95  		if err != nil {
    96  			t.Errorf("argsFromCLI(%+v): got error: %+v", tc.ex, err)
    97  		} else if !cmp.Equal(*e, tc.expected, cmpopts.IgnoreUnexported(os.File{})) {
    98  			t.Errorf("argsFromCLI(%+v): got %+v, but expected %+v", tc.ex, *e, tc.expected)
    99  		}
   100  	}
   101  }
   102  
   103  func TestJSONArgs(t *testing.T) {
   104  	testCases := []struct {
   105  		// ex is provided to make sure it is overridden by p.
   106  		ex       Exec
   107  		p        specs.Process
   108  		expected control.ExecArgs
   109  	}{
   110  		{
   111  			ex: Exec{
   112  				cwd:         "/baz/quux",
   113  				user:        user{kuid: 1, kgid: 1},
   114  				extraKGIDs:  []string{"4", "5", "6"},
   115  				caps:        []string{"CAP_SETGID"},
   116  				processPath: "/bin/foo",
   117  			},
   118  			p: specs.Process{
   119  				User: specs.User{UID: 0, GID: 0, AdditionalGids: []uint32{1, 2, 3}},
   120  				Args: []string{"ls", "/"},
   121  				Cwd:  "/foo/bar",
   122  				Capabilities: &specs.LinuxCapabilities{
   123  					Bounding:    []string{"CAP_DAC_OVERRIDE"},
   124  					Effective:   []string{"CAP_DAC_OVERRIDE"},
   125  					Inheritable: []string{"CAP_DAC_OVERRIDE"},
   126  					Permitted:   []string{"CAP_DAC_OVERRIDE"},
   127  				},
   128  			},
   129  			expected: control.ExecArgs{
   130  				Argv:             []string{"ls", "/"},
   131  				WorkingDirectory: "/foo/bar",
   132  				FilePayload:      urpc.FilePayload{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}},
   133  				KUID:             0,
   134  				KGID:             0,
   135  				ExtraKGIDs:       []auth.KGID{1, 2, 3},
   136  				Capabilities: &auth.TaskCapabilities{
   137  					BoundingCaps:    auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
   138  					EffectiveCaps:   auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
   139  					InheritableCaps: auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
   140  					PermittedCaps:   auth.CapabilitySetOf(linux.CAP_DAC_OVERRIDE),
   141  				},
   142  			},
   143  		},
   144  	}
   145  
   146  	for _, tc := range testCases {
   147  		e, err := argsFromProcess(&tc.p, true)
   148  		if err != nil {
   149  			t.Errorf("argsFromProcess(%+v): got error: %+v", tc.p, err)
   150  		} else if !cmp.Equal(*e, tc.expected, cmpopts.IgnoreUnexported(os.File{})) {
   151  			t.Errorf("argsFromProcess(%+v): got %+v, but expected %+v", tc.p, *e, tc.expected)
   152  		}
   153  	}
   154  }