Skip to content

Commit 91c0a7a

Browse files
author
Mrunal Patel
authored
Merge pull request #3580 from kolyshkin/fix-seccomp-ssb
seccomp: do not ignore SPEC_ALLOW flag
2 parents 2e8b7a1 + 26dc55e commit 91c0a7a

File tree

3 files changed

+54
-24
lines changed

3 files changed

+54
-24
lines changed

libcontainer/seccomp/patchbpf/enosys_linux.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ const uintptr_t C_SET_MODE_FILTER = SECCOMP_SET_MODE_FILTER;
4343
#endif
4444
const uintptr_t C_FILTER_FLAG_LOG = SECCOMP_FILTER_FLAG_LOG;
4545
46+
#ifndef SECCOMP_FILTER_FLAG_SPEC_ALLOW
47+
# define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)
48+
#endif
49+
const uintptr_t C_FILTER_FLAG_SPEC_ALLOW = SECCOMP_FILTER_FLAG_SPEC_ALLOW;
50+
4651
#ifndef SECCOMP_FILTER_FLAG_NEW_LISTENER
4752
# define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3)
4853
#endif
@@ -641,8 +646,13 @@ func filterFlags(config *configs.Seccomp, filter *libseccomp.ScmpFilter) (flags
641646
flags |= uint(C.C_FILTER_FLAG_LOG)
642647
}
643648
}
644-
645-
// TODO: Support seccomp flags not yet added to libseccomp-golang...
649+
if apiLevel >= 4 {
650+
if ssb, err := filter.GetSSB(); err != nil {
651+
return 0, false, fmt.Errorf("unable to fetch SECCOMP_FILTER_FLAG_SPEC_ALLOW bit: %w", err)
652+
} else if ssb {
653+
flags |= uint(C.C_FILTER_FLAG_SPEC_ALLOW)
654+
}
655+
}
646656

647657
for _, call := range config.Syscalls {
648658
if call.Action == configs.Notify {
@@ -655,6 +665,9 @@ func filterFlags(config *configs.Seccomp, filter *libseccomp.ScmpFilter) (flags
655665
}
656666

657667
func sysSeccompSetFilter(flags uint, filter []unix.SockFilter) (fd int, err error) {
668+
// This debug output is validated in tests/integration/seccomp.bats
669+
// by the SECCOMP_FILTER_FLAG_* test.
670+
logrus.Debugf("seccomp filter flags: %d", flags)
658671
fprog := unix.SockFprog{
659672
Len: uint16(len(filter)),
660673
Filter: &filter[0],

libcontainer/seccomp/seccomp_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ func InitSeccomp(config *configs.Seccomp) (int, error) {
105105
if err := filter.SetSSB(true); err != nil {
106106
return -1, fmt.Errorf("error adding SSB flag to seccomp filter: %w", err)
107107
}
108+
// NOTE when adding more flags, make sure to also modify filterFlags in patchbpf.
108109
default:
109110
return -1, fmt.Errorf("seccomp flags %q not yet supported by runc", flag)
110111
}

tests/integration/seccomp.bats

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -70,31 +70,47 @@ function teardown() {
7070
# Linux 4.14: SECCOMP_FILTER_FLAG_LOG
7171
# Linux 4.17: SECCOMP_FILTER_FLAG_SPEC_ALLOW
7272
requires_kernel 4.17
73-
SECCOMP_FILTER_FLAGS=(
74-
'' # no flag
75-
'"SECCOMP_FILTER_FLAG_LOG"'
76-
'"SECCOMP_FILTER_FLAG_SPEC_ALLOW"'
77-
'"SECCOMP_FILTER_FLAG_TSYNC"'
78-
'"SECCOMP_FILTER_FLAG_LOG","SECCOMP_FILTER_FLAG_SPEC_ALLOW"'
79-
'"SECCOMP_FILTER_FLAG_LOG","SECCOMP_FILTER_FLAG_TSYNC"'
80-
'"SECCOMP_FILTER_FLAG_SPEC_ALLOW","SECCOMP_FILTER_FLAG_TSYNC"'
81-
'"SECCOMP_FILTER_FLAG_LOG","SECCOMP_FILTER_FLAG_SPEC_ALLOW","SECCOMP_FILTER_FLAG_TSYNC"'
73+
74+
update_config ' .process.args = ["/bin/sh", "-c", "mkdir /dev/shm/foo"]
75+
| .process.noNewPrivileges = false
76+
| .linux.seccomp = {
77+
"defaultAction":"SCMP_ACT_ALLOW",
78+
"architectures":["SCMP_ARCH_X86","SCMP_ARCH_X32","SCMP_ARCH_X86_64","SCMP_ARCH_AARCH64","SCMP_ARCH_ARM"],
79+
"syscalls":[{"names":["mkdir"], "action":"SCMP_ACT_ERRNO"}]
80+
}'
81+
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
8292
)
83-
for flags in "${SECCOMP_FILTER_FLAGS[@]}"; do
84-
update_config ' .process.args = ["/bin/sh", "-c", "mkdir /dev/shm/foo"]
85-
| .process.noNewPrivileges = false
86-
| .linux.seccomp = {
87-
"defaultAction":"SCMP_ACT_ALLOW",
88-
"architectures":["SCMP_ARCH_X86","SCMP_ARCH_X32","SCMP_ARCH_X86_64","SCMP_ARCH_AARCH64","SCMP_ARCH_ARM"],
89-
"flags":['"${flags}"'],
90-
"syscalls":[{"names":["mkdir"], "action":"SCMP_ACT_ERRNO"}]
91-
}'
92-
93-
# This test checks that the flags are accepted without errors but does
94-
# not check they are effectively applied
95-
runc run test_busybox
93+
for key in "${!FLAGS[@]}"; do
94+
case "$key" in
95+
'REMOVE')
96+
update_config ' del(.linux.seccomp.flags)'
97+
;;
98+
'EMPTY')
99+
update_config ' .linux.seccomp.flags = []'
100+
;;
101+
*)
102+
update_config ' .linux.seccomp.flags = [ '"${key}"' ]'
103+
;;
104+
esac
105+
106+
runc --debug run test_busybox
96107
[ "$status" -ne 0 ]
97108
[[ "$output" == *"mkdir:"*"/dev/shm/foo"*"Operation not permitted"* ]]
109+
110+
# Check the numeric flags value, as printed in the debug log, is as expected.
111+
exp="\"seccomp filter flags: ${FLAGS[$key]}\""
112+
echo "flags $key, expecting $exp"
113+
[[ "$output" == *"$exp"* ]]
98114
done
99115
}
100116

0 commit comments

Comments
 (0)