Skip to content

Commit

Permalink
seccomp: accept strings for errno values
Browse files Browse the repository at this point in the history
simplify maintainance of the seccomp.json file and accept errno as
strings.

It also fixes a portability problem since errno values are arch
dependent.

The existing `DefaultErrnoRet` and `ErrnoRet` are maintained for
backward compatibility but they are obsoleted and will be removed in a
future release.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Nov 9, 2021
1 parent ca3c041 commit f6c766c
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 16 deletions.
12 changes: 12 additions & 0 deletions pkg/seccomp/default_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func DefaultProfile() *Seccomp {
"vmsplice",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
},
Expand Down Expand Up @@ -574,6 +575,7 @@ func DefaultProfile() *Seccomp {
"open_by_handle_at",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Expand Down Expand Up @@ -609,6 +611,7 @@ func DefaultProfile() *Seccomp {
"setns",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Expand All @@ -630,6 +633,7 @@ func DefaultProfile() *Seccomp {
"chroot",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Expand Down Expand Up @@ -657,6 +661,7 @@ func DefaultProfile() *Seccomp {
"query_module",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Expand All @@ -678,6 +683,7 @@ func DefaultProfile() *Seccomp {
"acct",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Expand Down Expand Up @@ -707,6 +713,7 @@ func DefaultProfile() *Seccomp {
"ptrace",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Expand All @@ -730,6 +737,7 @@ func DefaultProfile() *Seccomp {
"ioperm",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Expand Down Expand Up @@ -757,6 +765,7 @@ func DefaultProfile() *Seccomp {
"clock_settime64",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Expand All @@ -778,6 +787,7 @@ func DefaultProfile() *Seccomp {
"vhangup",
},
Action: ActErrno,
Errno: "EPERM",
ErrnoRet: &eperm,
Args: []*Arg{},
Excludes: Filter{
Expand All @@ -789,6 +799,7 @@ func DefaultProfile() *Seccomp {
"socket",
},
Action: ActErrno,
Errno: "EINVAL",
ErrnoRet: &einval,
Args: []*Arg{
{
Expand Down Expand Up @@ -867,6 +878,7 @@ func DefaultProfile() *Seccomp {

return &Seccomp{
DefaultAction: ActErrno,
DefaultErrno: "ENOSYS",
DefaultErrnoRet: &enosys,
ArchMap: arches(),
Syscalls: syscalls,
Expand Down
91 changes: 91 additions & 0 deletions pkg/seccomp/errno_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package seccomp

import (
"golang.org/x/sys/unix"
)

// Error table
var errnoArch = map[string]uint{
"EPERM": uint(unix.EPERM),
"ENOENT": uint(unix.ENOENT),
"ESRCH": uint(unix.ESRCH),
"EIO": uint(unix.EIO),
"ENXIO": uint(unix.ENXIO),
"E2BIG": uint(unix.E2BIG),
"ENOEXEC": uint(unix.ENOEXEC),
"EBADF": uint(unix.EBADF),
"ECHILD": uint(unix.ECHILD),
"EDEADLK": uint(unix.EDEADLK),
"ENOMEM": uint(unix.ENOMEM),
"EACCES": uint(unix.EACCES),
"EFAULT": uint(unix.EFAULT),
"ENOTBLK": uint(unix.ENOTBLK),
"EBUSY": uint(unix.EBUSY),
"EEXIST": uint(unix.EEXIST),
"EXDEV": uint(unix.EXDEV),
"ENODEV": uint(unix.ENODEV),
"ENOTDIR": uint(unix.ENOTDIR),
"EISDIR": uint(unix.EISDIR),
"EINVAL": uint(unix.EINVAL),
"ENFILE": uint(unix.ENFILE),
"EMFILE": uint(unix.EMFILE),
"ENOTTY": uint(unix.ENOTTY),
"ETXTBSY": uint(unix.ETXTBSY),
"EFBIG": uint(unix.EFBIG),
"ENOSPC": uint(unix.ENOSPC),
"ESPIPE": uint(unix.ESPIPE),
"EROFS": uint(unix.EROFS),
"EMLINK": uint(unix.EMLINK),
"EPIPE": uint(unix.EPIPE),
"EDOM": uint(unix.EDOM),
"ERANGE": uint(unix.ERANGE),
"EAGAIN": uint(unix.EAGAIN),
"EINPROGRESS": uint(unix.EINPROGRESS),
"EALREADY": uint(unix.EALREADY),
"ENOTSOCK": uint(unix.ENOTSOCK),
"EDESTADDRREQ": uint(unix.EDESTADDRREQ),
"EMSGSIZE": uint(unix.EMSGSIZE),
"EPROTOTYPE": uint(unix.EPROTOTYPE),
"ENOPROTOOPT": uint(unix.ENOPROTOOPT),
"EPROTONOSUPPORT": uint(unix.EPROTONOSUPPORT),
"ESOCKTNOSUPPORT": uint(unix.ESOCKTNOSUPPORT),
"EOPNOTSUPP": uint(unix.EOPNOTSUPP),
"EPFNOSUPPORT": uint(unix.EPFNOSUPPORT),
"EAFNOSUPPORT": uint(unix.EAFNOSUPPORT),
"EADDRINUSE": uint(unix.EADDRINUSE),
"EADDRNOTAVAIL": uint(unix.EADDRNOTAVAIL),
"ENETDOWN": uint(unix.ENETDOWN),
"ENETUNREACH": uint(unix.ENETUNREACH),
"ENETRESET": uint(unix.ENETRESET),
"ECONNABORTED": uint(unix.ECONNABORTED),
"ECONNRESET": uint(unix.ECONNRESET),
"ENOBUFS": uint(unix.ENOBUFS),
"EISCONN": uint(unix.EISCONN),
"ENOTCONN": uint(unix.ENOTCONN),
"ESHUTDOWN": uint(unix.ESHUTDOWN),
"ETOOMANYREFS": uint(unix.ETOOMANYREFS),
"ETIMEDOUT": uint(unix.ETIMEDOUT),
"ECONNREFUSED": uint(unix.ECONNREFUSED),
"ELOOP": uint(unix.ELOOP),
"ENAMETOOLONG": uint(unix.ENAMETOOLONG),
"EHOSTDOWN": uint(unix.EHOSTDOWN),
"EHOSTUNREACH": uint(unix.EHOSTUNREACH),
"ENOTEMPTY": uint(unix.ENOTEMPTY),
"EUSERS": uint(unix.EUSERS),
"EDQUOT": uint(unix.EDQUOT),
"ESTALE": uint(unix.ESTALE),
"EREMOTE": uint(unix.EREMOTE),
"ENOLCK": uint(unix.ENOLCK),
"ENOSYS": uint(unix.ENOSYS),
"EILSEQ": uint(unix.EILSEQ),
"ENOMEDIUM": uint(unix.ENOMEDIUM),
"EMEDIUMTYPE": uint(unix.EMEDIUMTYPE),
"EOVERFLOW": uint(unix.EOVERFLOW),
"ECANCELED": uint(unix.ECANCELED),
"EIDRM": uint(unix.EIDRM),
"ENOMSG": uint(unix.ENOMSG),
"ENOTSUP": uint(unix.ENOTSUP),
"EBADMSG": uint(unix.EBADMSG),
"ENOTRECOVERABLE": uint(unix.ENOTRECOVERABLE),
"EOWNERDEAD": uint(unix.EOWNERDEAD),
}
34 changes: 23 additions & 11 deletions pkg/seccomp/seccomp.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"defaultAction": "SCMP_ACT_ERRNO",
"defaultErrnoRet": 38,
"defaultErrno": "ENOSYS",
"archMap": [
{
"architecture": "SCMP_ARCH_X86_64",
Expand Down Expand Up @@ -87,7 +88,8 @@
"comment": "",
"includes": {},
"excludes": {},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -650,7 +652,8 @@
"CAP_DAC_READ_SEARCH"
]
},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -693,7 +696,8 @@
"CAP_SYS_ADMIN"
]
},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -722,7 +726,8 @@
"CAP_SYS_CHROOT"
]
},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -757,7 +762,8 @@
"CAP_SYS_MODULE"
]
},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -786,7 +792,8 @@
"CAP_SYS_PACCT"
]
},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -823,7 +830,8 @@
"CAP_SYS_PTRACE"
]
},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -854,7 +862,8 @@
"CAP_SYS_RAWIO"
]
},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -889,7 +898,8 @@
"CAP_SYS_TIME"
]
},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -918,7 +928,8 @@
"CAP_SYS_TTY_CONFIG"
]
},
"errnoRet": 1
"errnoRet": 1,
"errno": "EPERM"
},
{
"names": [
Expand Down Expand Up @@ -946,7 +957,8 @@
"CAP_AUDIT_WRITE"
]
},
"errnoRet": 22
"errnoRet": 22,
"errno": "EINVAL"
},
{
"names": [
Expand Down
33 changes: 30 additions & 3 deletions pkg/seccomp/seccomp_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"encoding/json"
"errors"
"fmt"
"strconv"

"github.com/opencontainers/runtime-spec/specs-go"
libseccomp "github.com/seccomp/libseccomp-golang"
Expand Down Expand Up @@ -66,6 +67,23 @@ func inSlice(slice []string, s string) bool {
return false
}

func getErrno(errno string, def *uint) (*uint, error) {
if errno == "" {
return def, nil
}
v, err := strconv.ParseUint(errno, 10, 32)
if err == nil {
v2 := uint(v)
return &v2, nil
}

v2, found := errnoArch[errno]
if !found {
return nil, fmt.Errorf("unknown errno %s", errno)
}
return &v2, nil
}

func setupSeccomp(config *Seccomp, rs *specs.Spec) (*specs.LinuxSeccomp, error) {
if config == nil {
return nil, nil
Expand Down Expand Up @@ -111,7 +129,11 @@ func setupSeccomp(config *Seccomp, rs *specs.Spec) (*specs.LinuxSeccomp, error)
}

newConfig.DefaultAction = specs.LinuxSeccompAction(config.DefaultAction)
newConfig.DefaultErrnoRet = config.DefaultErrnoRet

newConfig.DefaultErrnoRet, err = getErrno(config.DefaultErrno, config.DefaultErrnoRet)
if err != nil {
return nil, err
}

Loop:
// Loop through all syscall blocks and convert them to libcontainer format after filtering them
Expand Down Expand Up @@ -145,12 +167,17 @@ Loop:
return nil, errors.New("'name' and 'names' were specified in the seccomp profile, use either 'name' or 'names'")
}

errno, err := getErrno(call.Errno, call.ErrnoRet)
if err != nil {
return nil, err
}

if call.Name != "" {
newConfig.Syscalls = append(newConfig.Syscalls, createSpecsSyscall([]string{call.Name}, call.Action, call.Args, call.ErrnoRet))
newConfig.Syscalls = append(newConfig.Syscalls, createSpecsSyscall([]string{call.Name}, call.Action, call.Args, errno))
}

if len(call.Names) > 0 {
newConfig.Syscalls = append(newConfig.Syscalls, createSpecsSyscall(call.Names, call.Action, call.Args, call.ErrnoRet))
newConfig.Syscalls = append(newConfig.Syscalls, createSpecsSyscall(call.Names, call.Action, call.Args, errno))
}
}

Expand Down
10 changes: 8 additions & 2 deletions pkg/seccomp/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ package seccomp

// Seccomp represents the config for a seccomp profile for syscall restriction.
type Seccomp struct {
DefaultAction Action `json:"defaultAction"`
DefaultAction Action `json:"defaultAction"`

// DefaultErrnoRet is obsolete, please use DefaultErrno
DefaultErrnoRet *uint `json:"defaultErrnoRet,omitempty"`
DefaultErrno string `json:"defaultErrno,omitempty"`

// Architectures is kept to maintain backward compatibility with the old
// seccomp profile.
Architectures []Arch `json:"architectures,omitempty"`
Expand Down Expand Up @@ -107,5 +111,7 @@ type Syscall struct {
Comment string `json:"comment"`
Includes Filter `json:"includes"`
Excludes Filter `json:"excludes"`
ErrnoRet *uint `json:"errnoRet,omitempty"`
// ErrnoRet is obsolete, please use Errno
ErrnoRet *uint `json:"errnoRet,omitempty"`
Errno string `json:"errno,omitempty"`
}

0 comments on commit f6c766c

Please sign in to comment.