seccomp.Syscall: embed runtime-spec Syscall type

This makes the type better reflect the difference with the "runtime" profile;
our local type is used to generate a runtime-spec seccomp profile and extends
the runtime-spec type with additional fields; adding a "Name" field for backward
compatibility with older JSON representations, additional "Comment" metadata,
and conditional rules ("Includes", "Excludes") used during generation to adjust
the profile based on the container (capabilities) and host's (architecture, kernel)
configuration.

This change introduces one change in the type; the "runtime-spec" type uses a
`[]LinuxSeccompArg` for the `Args` field, whereas the local type used pointers;
`[]*LinuxSeccompArg`.

In addition, the runtime-spec Syscall type brings a new `ErrnoRet` field, allowing
the profile to specify the errno code returned for the syscall, which allows
changing the default EPERM for specific syscalls.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2021-02-09 14:30:14 +01:00
parent b9ad7b96bd
commit d92739713c
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
6 changed files with 604 additions and 558 deletions

View file

@ -394,7 +394,6 @@
"writev"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {},
"excludes": {}
@ -406,7 +405,6 @@
"ptrace"
],
"action": "SCMP_ACT_ALLOW",
"args": null,
"comment": "",
"includes": {
"minKernel": "4.8"
@ -498,7 +496,6 @@
"sync_file_range2"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"arches": [
@ -517,7 +514,6 @@
"set_tls"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"arches": [
@ -532,7 +528,6 @@
"arch_prctl"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"arches": [
@ -547,7 +542,6 @@
"modify_ldt"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"arches": [
@ -565,7 +559,6 @@
"s390_runtime_instr"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"arches": [
@ -580,7 +573,6 @@
"open_by_handle_at"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -614,7 +606,6 @@
"unshare"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -677,7 +668,6 @@
"reboot"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -691,7 +681,6 @@
"chroot"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -707,7 +696,6 @@
"finit_module"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -721,7 +709,6 @@
"acct"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -740,7 +727,6 @@
"ptrace"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -755,7 +741,6 @@
"ioperm"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -771,7 +756,6 @@
"clock_settime"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -785,7 +769,6 @@
"vhangup"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -801,7 +784,6 @@
"set_mempolicy"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [
@ -815,7 +797,6 @@
"syslog"
],
"action": "SCMP_ACT_ALLOW",
"args": [],
"comment": "",
"includes": {
"caps": [

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,12 @@
"name": "close",
"action": "SCMP_ACT_ALLOW",
"args": []
},
{
"name": "syslog",
"action": "SCMP_ACT_ERRNO",
"errnoRet": 12345,
"args": []
}
]
}

View file

@ -40,15 +40,18 @@ type Filter struct {
MinKernel *KernelVersion `json:"minKernel,omitempty"`
}
// Syscall is used to match a group of syscalls in Seccomp
// Syscall is used to match a group of syscalls in Seccomp. It extends the
// runtime-spec Syscall type, adding a "Name" field for backward compatibility
// with older JSON representations, additional "Comment" metadata, and conditional
// rules ("Includes", "Excludes") used to generate a runtime-spec Seccomp profile
// based on the container (capabilities) and host's (arch, kernel) configuration.
type Syscall struct {
Name string `json:"name,omitempty"`
Names []string `json:"names,omitempty"`
Action specs.LinuxSeccompAction `json:"action"`
Args []*specs.LinuxSeccompArg `json:"args"`
Comment string `json:"comment"`
Includes Filter `json:"includes"`
Excludes Filter `json:"excludes"`
specs.LinuxSyscall
// Deprecated: kept for backward compatibility with old JSON profiles, use Names instead
Name string `json:"name,omitempty"`
Comment string `json:"comment"`
Includes Filter `json:"includes"`
Excludes Filter `json:"excludes"`
}
// KernelVersion holds information about the kernel.

View file

@ -150,29 +150,15 @@ Loop:
}
}
if call.Name != "" && len(call.Names) != 0 {
return nil, errors.New("'name' and 'names' were specified in the seccomp profile, use either 'name' or 'names'")
if call.Name != "" {
if len(call.Names) != 0 {
return nil, errors.New("'name' and 'names' were specified in the seccomp profile, use either 'name' or 'names'")
}
call.Names = append(call.Names, call.Name)
}
if call.Name != "" {
newConfig.Syscalls = append(newConfig.Syscalls, createSpecsSyscall([]string{call.Name}, call.Action, call.Args))
} else {
newConfig.Syscalls = append(newConfig.Syscalls, createSpecsSyscall(call.Names, call.Action, call.Args))
}
newConfig.Syscalls = append(newConfig.Syscalls, call.LinuxSyscall)
}
return newConfig, nil
}
func createSpecsSyscall(names []string, action specs.LinuxSeccompAction, args []*specs.LinuxSeccompArg) specs.LinuxSyscall {
newCall := specs.LinuxSyscall{
Names: names,
Action: action,
}
// Loop through all the arguments of the syscall and convert them
for _, arg := range args {
newCall.Args = append(newCall.Args, *arg)
}
return newCall
}

View file

@ -18,9 +18,45 @@ func TestLoadProfile(t *testing.T) {
t.Fatal(err)
}
rs := createSpec()
if _, err := LoadProfile(string(f), &rs); err != nil {
p, err := LoadProfile(string(f), &rs)
if err != nil {
t.Fatal(err)
}
var expectedErrno uint = 12345
expected := specs.LinuxSeccomp{
DefaultAction: "SCMP_ACT_ERRNO",
Syscalls: []specs.LinuxSyscall{
{
Names: []string{"clone"},
Action: "SCMP_ACT_ALLOW",
Args: []specs.LinuxSeccompArg{{
Index: 0,
Value: 2114060288,
ValueTwo: 0,
Op: "SCMP_CMP_MASKED_EQ",
}},
},
{
Names: []string{"open"},
Action: "SCMP_ACT_ALLOW",
Args: []specs.LinuxSeccompArg{},
},
{
Names: []string{"close"},
Action: "SCMP_ACT_ALLOW",
Args: []specs.LinuxSeccompArg{},
},
{
Names: []string{"syslog"},
Action: "SCMP_ACT_ERRNO",
ErrnoRet: &expectedErrno,
Args: []specs.LinuxSeccompArg{},
},
},
}
assert.DeepEqual(t, expected, *p)
}
// TestLoadLegacyProfile tests loading a seccomp profile in the old format