| package oci | |
| import ( | |
| "testing" | |
| "github.com/opencontainers/runtime-spec/specs-go" | |
| "gotest.tools/v3/assert" | |
| ) | |
| func TestAppendDevicePermissionsFromCgroupRules(t *testing.T) { | |
| ptr := func(i int64) *int64 { return &i } | |
| tests := []struct { | |
| doc string | |
| rule string | |
| expected specs.LinuxDeviceCgroup | |
| expectedErr string | |
| }{ | |
| { | |
| doc: "empty rule", | |
| rule: "", | |
| expectedErr: `invalid device cgroup rule format: ''`, | |
| }, | |
| { | |
| doc: "multiple spaces after first column", | |
| rule: "c 1:1 rwm", | |
| expectedErr: `invalid device cgroup rule format: 'c 1:1 rwm'`, | |
| }, | |
| { | |
| doc: "multiple spaces after second column", | |
| rule: "c 1:1 rwm", | |
| expectedErr: `invalid device cgroup rule format: 'c 1:1 rwm'`, | |
| }, | |
| { | |
| doc: "leading spaces", | |
| rule: " c 1:1 rwm", | |
| expectedErr: `invalid device cgroup rule format: ' c 1:1 rwm'`, | |
| }, | |
| { | |
| doc: "trailing spaces", | |
| rule: "c 1:1 rwm ", | |
| expectedErr: `invalid device cgroup rule format: 'c 1:1 rwm '`, | |
| }, | |
| { | |
| doc: "unknown device type", | |
| rule: "z 1:1 rwm", | |
| expectedErr: `invalid device cgroup rule format: 'z 1:1 rwm'`, | |
| }, | |
| { | |
| doc: "invalid device type", | |
| rule: "zz 1:1 rwm", | |
| expectedErr: `invalid device cgroup rule format: 'zz 1:1 rwm'`, | |
| }, | |
| { | |
| doc: "missing colon", | |
| rule: "c 11 rwm", | |
| expectedErr: `invalid device cgroup rule format: 'c 11 rwm'`, | |
| }, | |
| { | |
| doc: "invalid device major-minor", | |
| rule: "c a:a rwm", | |
| expectedErr: `invalid device cgroup rule format: 'c a:a rwm'`, | |
| }, | |
| { | |
| doc: "negative major device", | |
| rule: "c -1:1 rwm", | |
| expectedErr: `invalid device cgroup rule format: 'c -1:1 rwm'`, | |
| }, | |
| { | |
| doc: "negative minor device", | |
| rule: "c 1:-1 rwm", | |
| expectedErr: `invalid device cgroup rule format: 'c 1:-1 rwm'`, | |
| }, | |
| { | |
| doc: "missing permissions", | |
| rule: "c 1:1", | |
| expectedErr: `invalid device cgroup rule format: 'c 1:1'`, | |
| }, | |
| { | |
| doc: "invalid permissions", | |
| rule: "c 1:1 x", | |
| expectedErr: `invalid device cgroup rule format: 'c 1:1 x'`, | |
| }, | |
| { | |
| doc: "too many permissions", | |
| rule: "c 1:1 rwmrwm", | |
| expectedErr: `invalid device cgroup rule format: 'c 1:1 rwmrwm'`, | |
| }, | |
| { | |
| doc: "major out of range", | |
| rule: "c 18446744073709551616:1 rwm", | |
| expectedErr: `invalid major value in device cgroup rule format: 'c 18446744073709551616:1 rwm'`, | |
| }, | |
| { | |
| doc: "minor out of range", | |
| rule: "c 1:18446744073709551616 rwm", | |
| expectedErr: `invalid minor value in device cgroup rule format: 'c 1:18446744073709551616 rwm'`, | |
| }, | |
| { | |
| doc: "all (a) devices", | |
| rule: "a 1:1 rwm", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "a", Major: ptr(1), Minor: ptr(1), Access: "rwm"}, | |
| }, | |
| { | |
| doc: "char (c) devices", | |
| rule: "c 1:1 rwm", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: ptr(1), Minor: ptr(1), Access: "rwm"}, | |
| }, | |
| { | |
| doc: "block (b) devices", | |
| rule: "b 1:1 rwm", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "b", Major: ptr(1), Minor: ptr(1), Access: "rwm"}, | |
| }, | |
| { | |
| doc: "char device with rwm permissions", | |
| rule: "c 7:128 rwm", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: ptr(7), Minor: ptr(128), Access: "rwm"}, | |
| }, | |
| { | |
| doc: "wildcard major", | |
| rule: "c *:1 rwm", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: ptr(-1), Minor: ptr(1), Access: "rwm"}, | |
| }, | |
| { | |
| doc: "wildcard minor", | |
| rule: "c 1:* rwm", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: ptr(1), Minor: ptr(-1), Access: "rwm"}, | |
| }, | |
| { | |
| doc: "wildcard major and minor", | |
| rule: "c *:* rwm", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: ptr(-1), Minor: ptr(-1), Access: "rwm"}, | |
| }, | |
| { | |
| doc: "read (r) permission", | |
| rule: "c 1:1 r", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: ptr(1), Minor: ptr(1), Access: "r"}, | |
| }, | |
| { | |
| doc: "write (w) permission", | |
| rule: "c 1:1 w", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: ptr(1), Minor: ptr(1), Access: "w"}, | |
| }, | |
| { | |
| doc: "mknod (m) permission", | |
| rule: "c 1:1 m", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: ptr(1), Minor: ptr(1), Access: "m"}, | |
| }, | |
| { | |
| doc: "mknod (m) and read (r) permission", | |
| rule: "c 1:1 mr", | |
| expected: specs.LinuxDeviceCgroup{Allow: true, Type: "c", Major: ptr(1), Minor: ptr(1), Access: "mr"}, | |
| }, | |
| } | |
| for _, tc := range tests { | |
| tc := tc | |
| t.Run(tc.doc, func(t *testing.T) { | |
| out, err := AppendDevicePermissionsFromCgroupRules([]specs.LinuxDeviceCgroup{}, []string{tc.rule}) | |
| if tc.expectedErr != "" { | |
| assert.Error(t, err, tc.expectedErr) | |
| return | |
| } | |
| assert.NilError(t, err) | |
| assert.DeepEqual(t, out, []specs.LinuxDeviceCgroup{tc.expected}) | |
| }) | |
| } | |
| } |