mirror of
https://github.com/opencontainers/runc.git
synced 2026-11-06 05:17:05 +00:00
Merge pull request #5564 from kolyshkin/seccomp-errnoret
libct/configs/validate: reject seccomp errnoRet for unsupported actions
This commit is contained in:
4 files changed
+124
No files matched your search
@@ -39,6 +39,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