...

Source file src/github.com/containerd/cgroups/v2/devicefilter_test.go

Documentation: github.com/containerd/cgroups/v2

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package v2
    18  
    19  import (
    20  	"strings"
    21  	"testing"
    22  
    23  	"github.com/opencontainers/runtime-spec/specs-go"
    24  )
    25  
    26  func hash(s, comm string) string {
    27  	var res []string
    28  	for _, l := range strings.Split(s, "\n") {
    29  		trimmed := strings.TrimSpace(l)
    30  		if trimmed == "" || strings.HasPrefix(trimmed, comm) {
    31  			continue
    32  		}
    33  		res = append(res, trimmed)
    34  	}
    35  	return strings.Join(res, "\n")
    36  }
    37  
    38  func testDeviceFilter(t testing.TB, devices []specs.LinuxDeviceCgroup, expectedStr string) {
    39  	insts, _, err := DeviceFilter(devices)
    40  	if err != nil {
    41  		t.Fatalf("%s: %v (devices: %+v)", t.Name(), err, devices)
    42  	}
    43  	s := insts.String()
    44  	t.Logf("%s: devices: %+v\n%s", t.Name(), devices, s)
    45  	if expectedStr != "" {
    46  		hashed := hash(s, "//")
    47  		expectedHashed := hash(expectedStr, "//")
    48  		if expectedHashed != hashed {
    49  			t.Fatalf("expected:\n%q\ngot\n%q", expectedHashed, hashed)
    50  		}
    51  	}
    52  }
    53  
    54  func TestDeviceFilter_Nil(t *testing.T) {
    55  	expected := `
    56  // load parameters into registers
    57          0: LdXMemH dst: r2 src: r1 off: 0 imm: 0
    58          1: LdXMemW dst: r3 src: r1 off: 0 imm: 0
    59          2: RSh32Imm dst: r3 imm: 16
    60          3: LdXMemW dst: r4 src: r1 off: 4 imm: 0
    61          4: LdXMemW dst: r5 src: r1 off: 8 imm: 0
    62  block-0:
    63  // return 0 (reject)
    64          5: Mov32Imm dst: r0 imm: 0
    65          6: Exit
    66  	`
    67  	testDeviceFilter(t, nil, expected)
    68  }
    69  
    70  func TestDeviceFilter_Privileged(t *testing.T) {
    71  	devices := []specs.LinuxDeviceCgroup{
    72  		{
    73  			Type:   "a",
    74  			Major:  pointerInt64(-1),
    75  			Minor:  pointerInt64(-1),
    76  			Access: "rwm",
    77  			Allow:  true,
    78  		},
    79  	}
    80  	expected :=
    81  		`
    82  // load parameters into registers
    83          0: LdXMemH dst: r2 src: r1 off: 0 imm: 0
    84          1: LdXMemW dst: r3 src: r1 off: 0 imm: 0
    85          2: RSh32Imm dst: r3 imm: 16
    86          3: LdXMemW dst: r4 src: r1 off: 4 imm: 0
    87          4: LdXMemW dst: r5 src: r1 off: 8 imm: 0
    88  block-0:
    89  // return 1 (accept)
    90          5: Mov32Imm dst: r0 imm: 1
    91          6: Exit
    92  	`
    93  	testDeviceFilter(t, devices, expected)
    94  }
    95  
    96  func TestDeviceFilter_PrivilegedExceptSingleDevice(t *testing.T) {
    97  	devices := []specs.LinuxDeviceCgroup{
    98  		{
    99  			Type:   "a",
   100  			Major:  pointerInt64(-1),
   101  			Minor:  pointerInt64(-1),
   102  			Access: "rwm",
   103  			Allow:  true,
   104  		},
   105  		{
   106  			Type:   "b",
   107  			Major:  pointerInt64(8),
   108  			Minor:  pointerInt64(0),
   109  			Access: "rwm",
   110  			Allow:  false,
   111  		},
   112  	}
   113  	expected := `
   114  // load parameters into registers
   115           0: LdXMemH dst: r2 src: r1 off: 0 imm: 0
   116           1: LdXMemW dst: r3 src: r1 off: 0 imm: 0
   117           2: RSh32Imm dst: r3 imm: 16
   118           3: LdXMemW dst: r4 src: r1 off: 4 imm: 0
   119           4: LdXMemW dst: r5 src: r1 off: 8 imm: 0
   120  block-0:
   121  // return 0 (reject) if type==b && major == 8 && minor == 0
   122           5: JNEImm dst: r2 off: -1 imm: 1 <block-1>
   123           6: JNEImm dst: r4 off: -1 imm: 8 <block-1>
   124           7: JNEImm dst: r5 off: -1 imm: 0 <block-1>
   125           8: Mov32Imm dst: r0 imm: 0
   126           9: Exit
   127  block-1:
   128  // return 1 (accept)
   129          10: Mov32Imm dst: r0 imm: 1
   130          11: Exit
   131  `
   132  	testDeviceFilter(t, devices, expected)
   133  }
   134  
   135  func TestDeviceFilter_Weird(t *testing.T) {
   136  	devices := []specs.LinuxDeviceCgroup{
   137  		{
   138  			Type:   "b",
   139  			Major:  pointerInt64(8),
   140  			Minor:  pointerInt64(1),
   141  			Access: "rwm",
   142  			Allow:  false,
   143  		},
   144  		{
   145  			Type:   "a",
   146  			Major:  pointerInt64(-1),
   147  			Minor:  pointerInt64(-1),
   148  			Access: "rwm",
   149  			Allow:  true,
   150  		},
   151  		{
   152  			Type:   "b",
   153  			Major:  pointerInt64(8),
   154  			Minor:  pointerInt64(2),
   155  			Access: "rwm",
   156  			Allow:  false,
   157  		},
   158  	}
   159  	// 8/1 is allowed, 8/2 is not allowed.
   160  	// This conforms to runc v1.0.0-rc.9 (cgroup1) behavior.
   161  	expected := `
   162  // load parameters into registers
   163           0: LdXMemH dst: r2 src: r1 off: 0 imm: 0
   164           1: LdXMemW dst: r3 src: r1 off: 0 imm: 0
   165           2: RSh32Imm dst: r3 imm: 16
   166           3: LdXMemW dst: r4 src: r1 off: 4 imm: 0
   167           4: LdXMemW dst: r5 src: r1 off: 8 imm: 0
   168  block-0:
   169  // return 0 (reject) if type==b && major == 8 && minor == 2
   170           5: JNEImm dst: r2 off: -1 imm: 1 <block-1>
   171           6: JNEImm dst: r4 off: -1 imm: 8 <block-1>
   172           7: JNEImm dst: r5 off: -1 imm: 2 <block-1>
   173           8: Mov32Imm dst: r0 imm: 0
   174           9: Exit
   175  block-1:
   176  // return 1 (accept)
   177          10: Mov32Imm dst: r0 imm: 1
   178          11: Exit
   179  `
   180  	testDeviceFilter(t, devices, expected)
   181  }
   182  
   183  func pointerInt64(int int64) *int64 {
   184  	return &int
   185  }
   186  

View as plain text