Merge pull request #2424 from giuseppe/errno-ret

libcontainer: honor seccomp errnoRet
This commit is contained in:
Mrunal Patel 2020-05-20 07:41:01 -07:00 committed by GitHub
commit 9a808dd014
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 98 additions and 15 deletions

2
go.mod
View File

@ -13,7 +13,7 @@ require (
github.com/golang/protobuf v1.3.5 github.com/golang/protobuf v1.3.5
github.com/moby/sys/mountinfo v0.1.3 github.com/moby/sys/mountinfo v0.1.3
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
github.com/opencontainers/runtime-spec v1.0.2 github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2
github.com/opencontainers/selinux v1.5.1 github.com/opencontainers/selinux v1.5.1
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/seccomp/libseccomp-golang v0.9.1 github.com/seccomp/libseccomp-golang v0.9.1

2
go.sum
View File

@ -29,6 +29,8 @@ github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 h1:7InQ7/zrOh6Sl
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2 h1:9mv9SC7GWmRWE0J/+oD8w3GsN2KYGKtg6uwLN7hfP5E=
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo= github.com/opencontainers/selinux v1.4.0 h1:cpiX/2wWIju/6My60T6/z9CxNG7c8xTQyEmA9fChpUo=
github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/opencontainers/selinux v1.4.0/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/opencontainers/selinux v1.5.1 h1:jskKwSMFYqyTrHEuJgQoUlTcId0av64S6EWObrIfn5Y= github.com/opencontainers/selinux v1.5.1 h1:jskKwSMFYqyTrHEuJgQoUlTcId0av64S6EWObrIfn5Y=

View File

@ -70,9 +70,10 @@ type Arg struct {
// Syscall is a rule to match a syscall in Seccomp // Syscall is a rule to match a syscall in Seccomp
type Syscall struct { type Syscall struct {
Name string `json:"name"` Name string `json:"name"`
Action Action `json:"action"` Action Action `json:"action"`
Args []*Arg `json:"args"` ErrnoRet *uint `json:"errnoRet"`
Args []*Arg `json:"args"`
} }
// TODO Windows. Many of these fields should be factored out into those parts // TODO Windows. Many of these fields should be factored out into those parts

View File

@ -12,6 +12,78 @@ import (
libseccomp "github.com/seccomp/libseccomp-golang" libseccomp "github.com/seccomp/libseccomp-golang"
) )
func TestSeccompDenyGetcwdWithErrno(t *testing.T) {
if testing.Short() {
return
}
rootfs, err := newRootfs()
if err != nil {
t.Fatal(err)
}
defer remove(rootfs)
errnoRet := uint(syscall.ESRCH)
config := newTemplateConfig(rootfs)
config.Seccomp = &configs.Seccomp{
DefaultAction: configs.Allow,
Syscalls: []*configs.Syscall{
{
Name: "getcwd",
Action: configs.Errno,
ErrnoRet: &errnoRet,
},
},
}
container, err := newContainer(config)
if err != nil {
t.Fatal(err)
}
defer container.Destroy()
buffers := newStdBuffers()
pwd := &libcontainer.Process{
Cwd: "/",
Args: []string{"pwd"},
Env: standardEnvironment,
Stdin: buffers.Stdin,
Stdout: buffers.Stdout,
Stderr: buffers.Stderr,
Init: true,
}
err = container.Run(pwd)
if err != nil {
t.Fatal(err)
}
ps, err := pwd.Wait()
if err == nil {
t.Fatal("Expecting error (negative return code); instead exited cleanly!")
}
var exitCode int
status := ps.Sys().(syscall.WaitStatus)
if status.Exited() {
exitCode = status.ExitStatus()
} else if status.Signaled() {
exitCode = -int(status.Signal())
} else {
t.Fatalf("Unrecognized exit reason!")
}
if exitCode == 0 {
t.Fatalf("Getcwd should fail with negative exit code, instead got %d!", exitCode)
}
expected := "pwd: getcwd: No such process"
actual := strings.Trim(buffers.Stderr.String(), "\n")
if actual != expected {
t.Fatalf("Expected output %s but got %s\n", expected, actual)
}
}
func TestSeccompDenyGetcwd(t *testing.T) { func TestSeccompDenyGetcwd(t *testing.T) {
if testing.Short() { if testing.Short() {
return return

View File

@ -38,7 +38,7 @@ func InitSeccomp(config *configs.Seccomp) error {
return errors.New("cannot initialize Seccomp - nil config passed") return errors.New("cannot initialize Seccomp - nil config passed")
} }
defaultAction, err := getAction(config.DefaultAction) defaultAction, err := getAction(config.DefaultAction, nil)
if err != nil { if err != nil {
return errors.New("error initializing seccomp - invalid default action") return errors.New("error initializing seccomp - invalid default action")
} }
@ -102,17 +102,23 @@ func IsEnabled() bool {
} }
// Convert Libcontainer Action to Libseccomp ScmpAction // Convert Libcontainer Action to Libseccomp ScmpAction
func getAction(act configs.Action) (libseccomp.ScmpAction, error) { func getAction(act configs.Action, errnoRet *uint) (libseccomp.ScmpAction, error) {
switch act { switch act {
case configs.Kill: case configs.Kill:
return actKill, nil return actKill, nil
case configs.Errno: case configs.Errno:
if errnoRet != nil {
return libseccomp.ActErrno.SetReturnCode(int16(*errnoRet)), nil
}
return actErrno, nil return actErrno, nil
case configs.Trap: case configs.Trap:
return actTrap, nil return actTrap, nil
case configs.Allow: case configs.Allow:
return actAllow, nil return actAllow, nil
case configs.Trace: case configs.Trace:
if errnoRet != nil {
return libseccomp.ActTrace.SetReturnCode(int16(*errnoRet)), nil
}
return actTrace, nil return actTrace, nil
case configs.Log: case configs.Log:
return actLog, nil return actLog, nil
@ -177,7 +183,7 @@ func matchCall(filter *libseccomp.ScmpFilter, call *configs.Syscall) error {
} }
// Convert the call's action to the libseccomp equivalent // Convert the call's action to the libseccomp equivalent
callAct, err := getAction(call.Action) callAct, err := getAction(call.Action, call.ErrnoRet)
if err != nil { if err != nil {
return fmt.Errorf("action in seccomp profile is invalid: %s", err) return fmt.Errorf("action in seccomp profile is invalid: %s", err)
} }

View File

@ -855,9 +855,10 @@ func SetupSeccomp(config *specs.LinuxSeccomp) (*configs.Seccomp, error) {
for _, name := range call.Names { for _, name := range call.Names {
newCall := configs.Syscall{ newCall := configs.Syscall{
Name: name, Name: name,
Action: newAction, Action: newAction,
Args: []*configs.Arg{}, ErrnoRet: call.ErrnoRet,
Args: []*configs.Arg{},
} }
// Loop through all the arguments of the syscall and convert them // Loop through all the arguments of the syscall and convert them
for _, arg := range call.Args { for _, arg := range call.Args {

View File

@ -667,9 +667,10 @@ type LinuxSeccompArg struct {
// LinuxSyscall is used to match a syscall in Seccomp // LinuxSyscall is used to match a syscall in Seccomp
type LinuxSyscall struct { type LinuxSyscall struct {
Names []string `json:"names"` Names []string `json:"names"`
Action LinuxSeccompAction `json:"action"` Action LinuxSeccompAction `json:"action"`
Args []LinuxSeccompArg `json:"args,omitempty"` ErrnoRet *uint `json:"errnoRet,omitempty"`
Args []LinuxSeccompArg `json:"args,omitempty"`
} }
// LinuxIntelRdt has container runtime resource constraints for Intel RDT // LinuxIntelRdt has container runtime resource constraints for Intel RDT

View File

@ -11,7 +11,7 @@ const (
VersionPatch = 2 VersionPatch = 2
// VersionDev indicates development branch. Releases will be empty string. // VersionDev indicates development branch. Releases will be empty string.
VersionDev = "" VersionDev = "-dev"
) )
// Version is the specification version that the package types support. // Version is the specification version that the package types support.

2
vendor/modules.txt vendored
View File

@ -37,7 +37,7 @@ github.com/moby/sys/mountinfo
# github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 # github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
## explicit ## explicit
github.com/mrunalp/fileutils github.com/mrunalp/fileutils
# github.com/opencontainers/runtime-spec v1.0.2 # github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2
## explicit ## explicit
github.com/opencontainers/runtime-spec/specs-go github.com/opencontainers/runtime-spec/specs-go
# github.com/opencontainers/selinux v1.5.1 # github.com/opencontainers/selinux v1.5.1