From adee333df76c02d99c740cf82cdf6074cade49b9 Mon Sep 17 00:00:00 2001
From: Giuseppe Scrivano <gscrivan@redhat.com>
Date: Mon, 24 May 2021 12:33:14 +0200
Subject: [PATCH 1/2] seccomp: add support for defaultErrnoRet

Add support to specify the default errno return value.

The OCI runtime specs already have support for it, and both crun (>=
0.19) and runc (>= 1.0-rc95) have support for it.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
---
 pkg/seccomp/conversion.go    | 1 +
 pkg/seccomp/filter.go        | 2 +-
 pkg/seccomp/seccomp_linux.go | 1 +
 pkg/seccomp/types.go         | 3 ++-
 4 files changed, 5 insertions(+), 2 deletions(-)

--- a/pkg/seccomp/conversion.go
+++ b/pkg/seccomp/conversion.go
@@ -118,6 +118,7 @@
 		return nil, errors.Wrap(err, "convert default action")
 	}
 	res.DefaultAction = newDefaultAction
+	res.DefaultErrnoRet = spec.DefaultErrnoRet
 
 	// Loop through all syscall blocks and convert them to the internal format
 	for _, call := range spec.Syscalls {
--- a/pkg/seccomp/filter.go
+++ b/pkg/seccomp/filter.go
@@ -41,7 +41,7 @@
 		return nil, errors.Wrap(err, "convert spec to seccomp profile")
 	}
 
-	defaultAction, err := toAction(profile.DefaultAction, nil)
+	defaultAction, err := toAction(profile.DefaultAction, profile.DefaultErrnoRet)
 	if err != nil {
 		return nil, errors.Wrapf(err, "convert default action %s", profile.DefaultAction)
 	}
--- a/pkg/seccomp/seccomp_linux.go
+++ b/pkg/seccomp/seccomp_linux.go
@@ -111,6 +111,7 @@
 	}
 
 	newConfig.DefaultAction = specs.LinuxSeccompAction(config.DefaultAction)
+	newConfig.DefaultErrnoRet = config.DefaultErrnoRet
 
 Loop:
 	// Loop through all syscall blocks and convert them to libcontainer format after filtering them
--- a/pkg/seccomp/types.go
+++ b/pkg/seccomp/types.go
@@ -6,7 +6,8 @@
 
 // Seccomp represents the config for a seccomp profile for syscall restriction.
 type Seccomp struct {
-	DefaultAction Action `json:"defaultAction"`
+	DefaultAction   Action `json:"defaultAction"`
+	DefaultErrnoRet *uint  `json:"defaultErrnoRet"`
 	// Architectures is kept to maintain backward compatibility with the old
 	// seccomp profile.
 	Architectures []Arch         `json:"architectures,omitempty"`
--- a/pkg/seccomp/default_linux.go
+++ b/pkg/seccomp/default_linux.go
@@ -46,10 +46,56 @@
 // DefaultProfile defines the allowlist for the default seccomp profile.
 func DefaultProfile() *Seccomp {
 	einval := uint(syscall.EINVAL)
+	enosys := uint(unix.ENOSYS)
+	eperm := uint(unix.EPERM)
 
 	syscalls := []*Syscall{
 		{
 			Names: []string{
+				"bdflush",
+				"clone3",
+				"io_pgetevents",
+				"io_uring_enter",
+				"io_uring_register",
+				"io_uring_setup",
+				"kexec_file_load",
+				"kexec_load",
+				"membarrier",
+				"migrate_pages",
+				"move_pages",
+				"nfsservctl",
+				"nice",
+				"oldfstat",
+				"oldlstat",
+				"oldolduname",
+				"oldstat",
+				"olduname",
+				"pciconfig_iobase",
+				"pciconfig_read",
+				"pciconfig_write",
+				"pkey_alloc",
+				"pkey_free",
+				"pkey_mprotect",
+				"rseq",
+				"sgetmask",
+				"ssetmask",
+				"swapcontext",
+				"swapoff",
+				"swapon",
+				"sysfs",
+				"uselib",
+				"userfaultfd",
+				"ustat",
+				"vm86",
+				"vm86old",
+				"vmsplice",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+		},
+		{
+			Names: []string{
 				"_llseek",
 				"_newselect",
 				"accept",
@@ -254,6 +300,7 @@
 				"pwritev2",
 				"read",
 				"readahead",
+				"readdir",
 				"readlink",
 				"readlinkat",
 				"readv",
@@ -518,6 +565,17 @@
 		},
 		{
 			Names: []string{
+				"open_by_handle_at",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_DAC_READ_SEARCH"},
+			},
+		},
+		{
+			Names: []string{
 				"bpf",
 				"clone",
 				"fanotify_init",
@@ -590,6 +648,24 @@
 		},
 		{
 			Names: []string{
+				"bpf",
+				"fanotify_init",
+				"lookup_dcookie",
+				"perf_event_open",
+				"quotactl",
+				"setdomainname",
+				"sethostname",
+				"setns",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_SYS_ADMIN"},
+			},
+		},
+		{
+			Names: []string{
 				"chroot",
 			},
 			Action: ActAllow,
@@ -600,6 +676,17 @@
 		},
 		{
 			Names: []string{
+				"chroot",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_SYS_CHROOT"},
+			},
+		},
+		{
+			Names: []string{
 				"delete_module",
 				"init_module",
 				"finit_module",
@@ -613,6 +700,20 @@
 		},
 		{
 			Names: []string{
+				"delete_module",
+				"init_module",
+				"finit_module",
+				"query_module",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_SYS_MODULE"},
+			},
+		},
+		{
+			Names: []string{
 				"get_mempolicy",
 				"mbind",
 				"name_to_handle_at",
@@ -626,6 +727,19 @@
 		},
 		{
 			Names: []string{
+				"get_mempolicy",
+				"mbind",
+				"set_mempolicy",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_SYS_NICE"},
+			},
+		},
+		{
+			Names: []string{
 				"acct",
 			},
 			Action: ActAllow,
@@ -636,6 +750,17 @@
 		},
 		{
 			Names: []string{
+				"acct",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_SYS_PACCT"},
+			},
+		},
+		{
+			Names: []string{
 				"kcmp",
 				"process_madvise",
 				"process_vm_readv",
@@ -650,6 +775,21 @@
 		},
 		{
 			Names: []string{
+				"kcmp",
+				"process_madvise",
+				"process_vm_readv",
+				"process_vm_writev",
+				"ptrace",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_SYS_PTRACE"},
+			},
+		},
+		{
+			Names: []string{
 				"iopl",
 				"ioperm",
 			},
@@ -661,6 +801,18 @@
 		},
 		{
 			Names: []string{
+				"iopl",
+				"ioperm",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_SYS_RAWIO"},
+			},
+		},
+		{
+			Names: []string{
 				"settimeofday",
 				"stime",
 				"clock_settime",
@@ -674,6 +826,20 @@
 		},
 		{
 			Names: []string{
+				"settimeofday",
+				"stime",
+				"clock_settime",
+				"clock_settime64",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_SYS_TIME"},
+			},
+		},
+		{
+			Names: []string{
 				"vhangup",
 			},
 			Action: ActAllow,
@@ -684,6 +850,17 @@
 		},
 		{
 			Names: []string{
+				"vhangup",
+			},
+			Action:   ActErrno,
+			ErrnoRet: &eperm,
+			Args:     []*Arg{},
+			Excludes: Filter{
+				Caps: []string{"CAP_SYS_TTY_CONFIG"},
+			},
+		},
+		{
+			Names: []string{
 				"socket",
 			},
 			Action:   ActErrno,
@@ -764,8 +941,9 @@
 	}
 
 	return &Seccomp{
-		DefaultAction: ActErrno,
-		ArchMap:       arches(),
-		Syscalls:      syscalls,
+		DefaultAction:   ActErrno,
+		DefaultErrnoRet: &enosys,
+		ArchMap:         arches(),
+		Syscalls:        syscalls,
 	}
 }
--- a/pkg/seccomp/seccomp.json
+++ b/pkg/seccomp/seccomp.json
@@ -1,5 +1,6 @@
 {
 	"defaultAction": "SCMP_ACT_ERRNO",
+	"defaultErrnoRet": 38,
 	"archMap": [
 		{
 			"architecture": "SCMP_ARCH_X86_64",
@@ -52,6 +53,53 @@
 	"syscalls": [
 		{
 			"names": [
+				"bdflush",
+				"clone3",
+				"io_pgetevents",
+				"io_uring_enter",
+				"io_uring_register",
+				"io_uring_setup",
+				"kexec_file_load",
+				"kexec_load",
+				"membarrier",
+				"migrate_pages",
+				"move_pages",
+				"nfsservctl",
+				"nice",
+				"oldfstat",
+				"oldlstat",
+				"oldolduname",
+				"oldstat",
+				"olduname",
+				"pciconfig_iobase",
+				"pciconfig_read",
+				"pciconfig_write",
+				"pkey_alloc",
+				"pkey_free",
+				"pkey_mprotect",
+				"rseq",
+				"sgetmask",
+				"ssetmask",
+				"swapcontext",
+				"swapoff",
+				"swapon",
+				"sysfs",
+				"uselib",
+				"userfaultfd",
+				"ustat",
+				"vm86",
+				"vm86old",
+				"vmsplice"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"_llseek",
 				"_newselect",
 				"accept",
@@ -255,6 +303,7 @@
 				"pwritev2",
 				"read",
 				"readahead",
+				"readdir",
 				"readlink",
 				"readlinkat",
 				"readv",
@@ -580,6 +629,21 @@
 		},
 		{
 			"names": [
+				"open_by_handle_at"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_DAC_READ_SEARCH"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"bpf",
 				"clone",
 				"fanotify_init",
@@ -672,6 +736,28 @@
 		},
 		{
 			"names": [
+				"bpf",
+				"fanotify_init",
+				"lookup_dcookie",
+				"perf_event_open",
+				"quotactl",
+				"setdomainname",
+				"sethostname",
+				"setns"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_SYS_ADMIN"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"chroot"
 			],
 			"action": "SCMP_ACT_ALLOW",
@@ -686,6 +772,21 @@
 		},
 		{
 			"names": [
+				"chroot"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_SYS_CHROOT"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"delete_module",
 				"init_module",
 				"finit_module",
@@ -703,6 +804,24 @@
 		},
 		{
 			"names": [
+				"delete_module",
+				"init_module",
+				"finit_module",
+				"query_module"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_SYS_MODULE"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"get_mempolicy",
 				"mbind",
 				"name_to_handle_at",
@@ -720,6 +839,23 @@
 		},
 		{
 			"names": [
+				"get_mempolicy",
+				"mbind",
+				"set_mempolicy"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_SYS_NICE"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"acct"
 			],
 			"action": "SCMP_ACT_ALLOW",
@@ -734,6 +870,21 @@
 		},
 		{
 			"names": [
+				"acct"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_SYS_PACCT"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"kcmp",
 				"process_madvise",
 				"process_vm_readv",
@@ -752,6 +903,25 @@
 		},
 		{
 			"names": [
+				"kcmp",
+				"process_madvise",
+				"process_vm_readv",
+				"process_vm_writev",
+				"ptrace"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_SYS_PTRACE"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"iopl",
 				"ioperm"
 			],
@@ -767,6 +937,22 @@
 		},
 		{
 			"names": [
+				"iopl",
+				"ioperm"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_SYS_RAWIO"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"settimeofday",
 				"stime",
 				"clock_settime",
@@ -784,6 +970,24 @@
 		},
 		{
 			"names": [
+				"settimeofday",
+				"stime",
+				"clock_settime",
+				"clock_settime64"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_SYS_TIME"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"vhangup"
 			],
 			"action": "SCMP_ACT_ALLOW",
@@ -798,6 +1002,21 @@
 		},
 		{
 			"names": [
+				"vhangup"
+			],
+			"action": "SCMP_ACT_ERRNO",
+			"args": [],
+			"comment": "",
+			"includes": {},
+			"excludes": {
+				"caps": [
+					"CAP_SYS_TTY_CONFIG"
+				]
+			},
+			"errnoRet": 1
+		},
+		{
+			"names": [
 				"socket"
 			],
 			"action": "SCMP_ACT_ERRNO",
