@@ -66,11 +66,32 @@ function teardown() {
66
66
[[ " $output " == * " Network is down" * ]]
67
67
}
68
68
69
- @test " runc run [seccomp] (SECCOMP_FILTER_FLAG_*)" {
70
- # Linux 4.14: SECCOMP_FILTER_FLAG_LOG
71
- # Linux 4.17: SECCOMP_FILTER_FLAG_SPEC_ALLOW
72
- requires_kernel 4.17
69
+ # Prints the numeric value of provided seccomp flags combination.
70
+ # The parameter is flags string, as supplied in OCI spec, for example
71
+ # '"SECCOMP_FILTER_FLAG_TSYNC","SECCOMP_FILTER_FLAG_LOG"'.
72
+ function flags_value() {
73
+ # Numeric values of seccomp flags.
74
+ declare -A values=(
75
+ [' "SECCOMP_FILTER_FLAG_TSYNC"' ]=0 # Supported but ignored by runc, thus 0.
76
+ [' "SECCOMP_FILTER_FLAG_LOG"' ]=2
77
+ [' "SECCOMP_FILTER_FLAG_SPEC_ALLOW"' ]=4
78
+ # XXX: add new values above this line.
79
+ )
80
+ # Split the flags.
81
+ IFS=' ,' read -ra flags <<< " $1"
82
+
83
+ local flag v sum=0
84
+ for flag in " ${flags[@]} " ; do
85
+ # This will produce "values[$flag]: unbound variable"
86
+ # error for a new flag yet unknown to the test.
87
+ v=${values[$flag]}
88
+ (( sum += v)) || true
89
+ done
90
+
91
+ echo $sum
92
+ }
73
93
94
+ @test " runc run [seccomp] (SECCOMP_FILTER_FLAG_*)" {
74
95
update_config ' .process.args = ["/bin/sh", "-c", "mkdir /dev/shm/foo"]
75
96
| .process.noNewPrivileges = false
76
97
| .linux.seccomp = {
@@ -79,18 +100,35 @@ function teardown() {
79
100
"syscalls":[{"names":["mkdir", "mkdirat"], "action":"SCMP_ACT_ERRNO"}]
80
101
}'
81
102
82
- declare -A FLAGS=(
83
- [' REMOVE' ]=0 # No setting, use built-in default.
84
- [' EMPTY' ]=0 # Empty set of flags.
85
- [' "SECCOMP_FILTER_FLAG_LOG"' ]=2
86
- [' "SECCOMP_FILTER_FLAG_SPEC_ALLOW"' ]=4
87
- [' "SECCOMP_FILTER_FLAG_TSYNC"' ]=0 # tsync flag is ignored.
88
- [' "SECCOMP_FILTER_FLAG_LOG","SECCOMP_FILTER_FLAG_SPEC_ALLOW"' ]=6
89
- [' "SECCOMP_FILTER_FLAG_LOG","SECCOMP_FILTER_FLAG_TSYNC"' ]=2
90
- [' "SECCOMP_FILTER_FLAG_SPEC_ALLOW","SECCOMP_FILTER_FLAG_TSYNC"' ]=4
91
- [' "SECCOMP_FILTER_FLAG_LOG","SECCOMP_FILTER_FLAG_SPEC_ALLOW","SECCOMP_FILTER_FLAG_TSYNC"' ]=6
103
+ # Get the list of flags supported by runc/seccomp/kernel,
104
+ # or "null" if no flags are supported or runc is too old.
105
+ mapfile -t flags < <( __runc features | jq -c ' .linux.seccomp.supportedFlags' |
106
+ tr -d ' []\n' | tr ' ,' ' \n' )
107
+
108
+ # This is a set of all possible flag combinations to test.
109
+ declare -A TEST_CASES=(
110
+ [' EMPTY' ]=0 # Special value: empty set of flags.
111
+ [' REMOVE' ]=0 # Special value: no flags set.
92
112
)
93
- for key in " ${! FLAGS[@]} " ; do
113
+
114
+ # If supported, runc should set SPEC_ALLOW if no flags are set.
115
+ if [[ " ${flags[*]} " == * ' "SECCOMP_FILTER_FLAG_SPEC_ALLOW" ' * ]]; then
116
+ TEST_CASES[' REMOVE' ]=$( flags_value ' "SECCOMP_FILTER_FLAG_SPEC_ALLOW"' )
117
+ fi
118
+
119
+ # Add all possible combinations of seccomp flags
120
+ # and their expected numeric values to TEST_CASES.
121
+ if [ " ${flags[0]} " != " null" ]; then
122
+ # Use shell {a,}{b,}{c,} to generate the powerset.
123
+ for fc in $( eval echo " $( printf " {'%s,',}" " ${flags[@]} " ) " ) ; do
124
+ # Remove the last comma.
125
+ fc=" ${fc/% ,/ } "
126
+ TEST_CASES[$fc ]=$( flags_value " $fc " )
127
+ done
128
+ fi
129
+
130
+ # Finally, run the tests.
131
+ for key in " ${! TEST_CASES[@]} " ; do
94
132
case " $key " in
95
133
' REMOVE' )
96
134
update_config ' del(.linux.seccomp.flags)'
@@ -108,7 +146,7 @@ function teardown() {
108
146
[[ " $output " == * " mkdir:" * " /dev/shm/foo" * " Operation not permitted" * ]]
109
147
110
148
# Check the numeric flags value, as printed in the debug log, is as expected.
111
- exp=" \" seccomp filter flags: ${FLAGS [$key]} \" "
149
+ exp=" \" seccomp filter flags: ${TEST_CASES [$key]} \" "
112
150
echo " flags $key , expecting $exp "
113
151
[[ " $output " == * " $exp " * ]]
114
152
done
0 commit comments