mirror of
https://github.com/opencontainers/runc.git
synced 2026-11-06 05:17:05 +00:00
libct/configs/validate: reject seccomp errnoRet for unsupported actions
The runtime spec says about both defaultErrnoRet and errnoRet: > When the action doesn't support an errno, the runtime MUST print and > error and fail. Yet runc silently ignores errnoRet set for any action other than SCMP_ACT_ERRNO and SCMP_ACT_TRACE. Add a check to the config validator, so the error is reported early (before the container init is started) and clearly (including the syscall name in case of errnoRet). Since the validator checks all syscall rules, this also covers ones which are later skipped as redundant (i.e. having the same action as the default). Add unit and integration tests, and a CHANGELOG entry. Reported in issue 5550. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
1 parent
f4ec3e21b3
commit
8a3685e621
4 files changed
+124
No files matched your search
@@ -32,6 +32,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Running a container which does not have its own mount namespace no longer
|
||||
changes the propagation of host's `/` and of the parent mount of the
|
||||
container rootfs (they were made private or slave). (#5537)
|
||||
- runc now errors out when seccomp `defaultErrnoRet` or `errnoRet` is set for
|
||||
an action which does not support it (i.e. anything other than
|
||||
`SCMP_ACT_ERRNO` and `SCMP_ACT_TRACE`), as required by the runtime spec.
|
||||
Previously, such values were silently ignored. (#5550, #5564)
|
||||
|
||||
## [1.6.0-rc.1] - 2026-10-06
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ func Validate(config *configs.Config) error {
|
||||
rootfs,
|
||||
rootlessEUIDCheck,
|
||||
scheduler,
|
||||
seccompCheck,
|
||||
selinuxCheck,
|
||||
sysctl,
|
||||
uts,
|
||||
@@ -543,3 +544,24 @@ func memoryPolicy(config *configs.Config) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func seccompCheck(config *configs.Config) error {
|
||||
sc := config.Seccomp
|
||||
if sc == nil {
|
||||
return nil
|
||||
}
|
||||
// The runtime spec requires an error if errnoRet
|
||||
// is set for an action that does not support it.
|
||||
supportsErrno := func(a configs.Action) bool {
|
||||
return a == configs.Errno || a == configs.Trace
|
||||
}
|
||||
if sc.DefaultErrnoRet != nil && !supportsErrno(sc.DefaultAction) {
|
||||
return errors.New("seccomp: defaultErrnoRet is only supported for SCMP_ACT_ERRNO and SCMP_ACT_TRACE actions")
|
||||
}
|
||||
for _, call := range sc.Syscalls {
|
||||
if call != nil && call.ErrnoRet != nil && !supportsErrno(call.Action) {
|
||||
return fmt.Errorf("seccomp: syscall %q: errnoRet is only supported for SCMP_ACT_ERRNO and SCMP_ACT_TRACE actions", call.Name)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1168,3 +1168,80 @@ func TestDevValidName(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateSeccompErrnoRet(t *testing.T) {
|
||||
errno := uint(1)
|
||||
testCases := []struct {
|
||||
name string
|
||||
seccomp *configs.Seccomp
|
||||
isErr bool
|
||||
}{
|
||||
{
|
||||
name: "defaultErrnoRet with SCMP_ACT_ERRNO",
|
||||
seccomp: &configs.Seccomp{
|
||||
DefaultAction: configs.Errno,
|
||||
DefaultErrnoRet: &errno,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "defaultErrnoRet with SCMP_ACT_TRACE",
|
||||
seccomp: &configs.Seccomp{
|
||||
DefaultAction: configs.Trace,
|
||||
DefaultErrnoRet: &errno,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "defaultErrnoRet with SCMP_ACT_ALLOW",
|
||||
seccomp: &configs.Seccomp{
|
||||
DefaultAction: configs.Allow,
|
||||
DefaultErrnoRet: &errno,
|
||||
},
|
||||
isErr: true,
|
||||
},
|
||||
{
|
||||
name: "errnoRet with SCMP_ACT_ERRNO",
|
||||
seccomp: &configs.Seccomp{
|
||||
DefaultAction: configs.Allow,
|
||||
Syscalls: []*configs.Syscall{
|
||||
{Name: "mkdir", Action: configs.Errno, ErrnoRet: &errno},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "errnoRet with SCMP_ACT_KILL_PROCESS",
|
||||
seccomp: &configs.Seccomp{
|
||||
DefaultAction: configs.Allow,
|
||||
Syscalls: []*configs.Syscall{
|
||||
{Name: "mkdir", Action: configs.KillProcess, ErrnoRet: &errno},
|
||||
},
|
||||
},
|
||||
isErr: true,
|
||||
},
|
||||
{
|
||||
name: "errnoRet with redundant SCMP_ACT_ALLOW",
|
||||
seccomp: &configs.Seccomp{
|
||||
DefaultAction: configs.Allow,
|
||||
Syscalls: []*configs.Syscall{
|
||||
{Name: "mkdir", Action: configs.Allow, ErrnoRet: &errno},
|
||||
},
|
||||
},
|
||||
isErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
config := &configs.Config{
|
||||
Rootfs: "/var",
|
||||
Seccomp: tc.seccomp,
|
||||
}
|
||||
err := Validate(config)
|
||||
if tc.isErr && err == nil {
|
||||
t.Error("expected error, got nil")
|
||||
}
|
||||
if !tc.isErr && err != nil {
|
||||
t.Errorf("expected nil, got error %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,27 @@ function teardown() {
|
||||
assert_output --partial "Network is down"
|
||||
}
|
||||
|
||||
@test "runc run [seccomp] (errnoRet with unsupported action)" {
|
||||
update_config '.process.args = ["/bin/true"]'
|
||||
|
||||
# defaultErrnoRet with a default action not supporting it.
|
||||
update_config '.linux.seccomp = {
|
||||
"defaultAction":"SCMP_ACT_ALLOW",
|
||||
"defaultErrnoRet": 1
|
||||
}'
|
||||
run ! runc run test_busybox
|
||||
assert_output --partial "defaultErrnoRet is only supported for"
|
||||
|
||||
# errnoRet with a syscall action not supporting it (the rule is
|
||||
# redundant as it is the same as the default action).
|
||||
update_config '.linux.seccomp = {
|
||||
"defaultAction":"SCMP_ACT_ALLOW",
|
||||
"syscalls":[{"names":["mkdir","mkdirat"], "action":"SCMP_ACT_ALLOW", "errnoRet": 1}]
|
||||
}'
|
||||
run ! runc run test_busybox
|
||||
assert_output --regexp 'syscall .*mkdir.*: errnoRet is only supported for'
|
||||
}
|
||||
|
||||
# Prints the numeric value of provided seccomp flags combination.
|
||||
# The parameter is flags string, as supplied in OCI spec, for example
|
||||
# '"SECCOMP_FILTER_FLAG_TSYNC","SECCOMP_FILTER_FLAG_LOG"'.
|
||||
|
||||
Reference in new issue
Block a user