Skip to content

Commit 8f9d08a

Browse files
committed
tests/int: use runc features in seccomp flags test
This test (initially added by commit 58ea21d and later amended in commit 26dc55e) currently has two major deficiencies: 1. All possible flag combinations, and their respective numeric values, have to be explicitly listed. Currently we support 3 flags, so there is only 7 combinations, but adding more flags will become increasingly difficult. 2. It requires kernel 4.17 (for SECCOMP_FILTER_FLAG_SPEC_ALLOW), and not doing any tests when running on an older kernel. This, too, will make it more difficult to add extra flags in the future. Both issues can be solved by using runc features which now prints all known and supported runc flags. We still have to hardcode individual flags to test, and their numeric values, but most of other work is coded now. In particular: * The test checks that all the supported flags are being tested. In other words, this is a sanity check that if a new flag is added to runc, the test is amended appropriately. * Flags that are known but not supported (say because of an older kernel) are removed from the test. This makes it possible to run the test on older kernels, removing the limitation (2) above. * The test calculates the powerset (all possible combinations) of supported flags, and their numeric values. This makes it easier to add more flags, removing the limitation (1) above. The downside to this is the test code is somewhat complicated. Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 95679c3 commit 8f9d08a

File tree

1 file changed

+62
-16
lines changed

1 file changed

+62
-16
lines changed

tests/integration/seccomp.bats

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ function teardown() {
6767
}
6868

6969
@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
73-
7470
update_config ' .process.args = ["/bin/sh", "-c", "mkdir /dev/shm/foo"]
7571
| .process.noNewPrivileges = false
7672
| .linux.seccomp = {
@@ -79,18 +75,68 @@ function teardown() {
7975
"syscalls":[{"names":["mkdir"], "action":"SCMP_ACT_ERRNO"}]
8076
}'
8177

82-
declare -A FLAGS=(
83-
['REMOVE']=4 # 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
78+
# This is a set of all possible flag combinations to test.
79+
declare -A TEST_CASES=(
80+
['EMPTY']=0 # Special value: empty set of flags.
81+
)
82+
83+
# List of flags to test and their respective numeric values.
84+
declare -A flags=(
85+
["TSYNC"]=0 # Supported but ignored by runc, thus 0.
86+
["LOG"]=2
87+
["SPEC_ALLOW"]=4
88+
# XXX: add new seccomp flags above this line.
9289
)
93-
for key in "${!FLAGS[@]}"; do
90+
91+
# Get the list of flags supported by runc/seccomp/kernel.
92+
mapfile -t sup_flags < <(__runc features |
93+
jq '.linux.seccomp.supported_flags' | grep 'SECCOMP' |
94+
sed -e 's/^ *"SECCOMP_FILTER_FLAG_//' -e 's/",*$//')
95+
96+
# Check that any new seccomp flags added are actually tested.
97+
for f in "${sup_flags[@]}"; do
98+
if ! [ -v 'flags[$f]' ]; then
99+
echo "ERROR: seccomp flag $f not added to the test; fix the text!" 1>&2
100+
exit 1
101+
fi
102+
done
103+
104+
# Filter out flags not supported by the current seccomp/kernel,
105+
# so this test can be run on older systems.
106+
for f in "${!flags[@]}"; do
107+
found=0
108+
for v in "${sup_flags[@]}"; do
109+
if [ "$f" = "$v" ]; then
110+
found=1
111+
break
112+
fi
113+
done
114+
[ "$found" -eq 0 ] && unset 'flags[$f]'
115+
done
116+
117+
# Special value: do not set any flags in spec. In this case, runc
118+
# should set SPEC_ALLOW flag in this case, if it is supported,
119+
# or 0 otherwise.
120+
TEST_CASES['REMOVE']=${flags["SPEC_ALLOW"]-0}
121+
122+
# Add all possible combinations (i.e., a powerset) of seccomp flags
123+
# and their expected numeric values to TEST_CASES.
124+
if [ "${#flags[@]}" -gt 0 ]; then
125+
for fc in $(eval echo "$(printf "{'\"SECCOMP_FILTER_FLAG_'%s'\",',}" "${!flags[@]}")"); do
126+
# Calculate the numeric value of the flags set.
127+
val=0
128+
for k in "${!flags[@]}"; do
129+
if [[ "$fc" == *"$k\","* ]]; then
130+
((val += flags[$k])) || true
131+
fi
132+
done
133+
# Remove the last comma from fc.
134+
TEST_CASES[${fc/%,/}]=$val
135+
done
136+
fi
137+
138+
# Finally, run the tests.
139+
for key in "${!TEST_CASES[@]}"; do
94140
case "$key" in
95141
'REMOVE')
96142
update_config ' del(.linux.seccomp.flags)'
@@ -108,7 +154,7 @@ function teardown() {
108154
[[ "$output" == *"mkdir:"*"/dev/shm/foo"*"Operation not permitted"* ]]
109155

110156
# Check the numeric flags value, as printed in the debug log, is as expected.
111-
exp="\"seccomp filter flags: ${FLAGS[$key]}\""
157+
exp="\"seccomp filter flags: ${TEST_CASES[$key]}\""
112158
echo "flags $key, expecting $exp"
113159
[[ "$output" == *"$exp"* ]]
114160
done

0 commit comments

Comments
 (0)