|
@@ -0,0 +1,168 @@
|
|
|
|
+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})
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+}
|