From 1124543ca8071074a537a15db251af46a5189907 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 2 Nov 2018 21:00:15 -0700 Subject: [PATCH] seccomp: allow ptrace for 4.8+ kernels 4.8+ kernels have fixed the ptrace security issues so we can allow ptrace(2) on the default seccomp profile if we do the kernel version check. https://github.com/torvalds/linux/commit/93e35efb8de45393cf61ed07f7b407629bf698ea Signed-off-by: Tonis Tiigi --- api/types/seccomp.go | 5 +++-- profiles/seccomp/default.json | 12 +++++++++++ profiles/seccomp/seccomp.go | 32 ++++++++++++++++++++++++++++- profiles/seccomp/seccomp_default.go | 7 +++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/api/types/seccomp.go b/api/types/seccomp.go index 67a41e1a89..2259c6be1e 100644 --- a/api/types/seccomp.go +++ b/api/types/seccomp.go @@ -77,8 +77,9 @@ type Arg struct { // Filter is used to conditionally apply Seccomp rules type Filter struct { - Caps []string `json:"caps,omitempty"` - Arches []string `json:"arches,omitempty"` + Caps []string `json:"caps,omitempty"` + Arches []string `json:"arches,omitempty"` + MinKernel string `json:"minKernel,omitempty"` } // Syscall is used to match a group of syscalls in Seccomp diff --git a/profiles/seccomp/default.json b/profiles/seccomp/default.json index 0d954bb6d0..3aa42f4253 100755 --- a/profiles/seccomp/default.json +++ b/profiles/seccomp/default.json @@ -366,6 +366,18 @@ "includes": {}, "excludes": {} }, + { + "names": [ + "ptrace" + ], + "action": "SCMP_ACT_ALLOW", + "args": null, + "comment": "", + "includes": { + "minKernel": "4.8.0" + }, + "excludes": {} + }, { "names": [ "personality" diff --git a/profiles/seccomp/seccomp.go b/profiles/seccomp/seccomp.go index 4438670a58..589a6f4b16 100644 --- a/profiles/seccomp/seccomp.go +++ b/profiles/seccomp/seccomp.go @@ -8,7 +8,8 @@ import ( "fmt" "github.com/docker/docker/api/types" - "github.com/opencontainers/runtime-spec/specs-go" + "github.com/docker/docker/pkg/parsers/kernel" + specs "github.com/opencontainers/runtime-spec/specs-go" libseccomp "github.com/seccomp/libseccomp-golang" ) @@ -95,6 +96,21 @@ func setupSeccomp(config *types.Seccomp, rs *specs.Spec) (*specs.LinuxSeccomp, e newConfig.DefaultAction = specs.LinuxSeccompAction(config.DefaultAction) + var currentKernelVersion *kernel.VersionInfo + kernelGreaterEqualThan := func(v string) (bool, error) { + version, err := kernel.ParseRelease(v) + if err != nil { + return false, err + } + if currentKernelVersion == nil { + currentKernelVersion, err = kernel.GetKernelVersion() + if err != nil { + return false, err + } + } + return kernel.CompareKernelVersion(*version, *currentKernelVersion) <= 0, nil + } + Loop: // Loop through all syscall blocks and convert them to libcontainer format after filtering them for _, call := range config.Syscalls { @@ -110,6 +126,13 @@ Loop: } } } + if call.Excludes.MinKernel != "" { + if ok, err := kernelGreaterEqualThan(call.Excludes.MinKernel); err != nil { + return nil, err + } else if ok { + continue Loop + } + } if len(call.Includes.Arches) > 0 { if !inSlice(call.Includes.Arches, arch) { continue Loop @@ -122,6 +145,13 @@ Loop: } } } + if call.Includes.MinKernel != "" { + if ok, err := kernelGreaterEqualThan(call.Includes.MinKernel); err != nil { + return nil, err + } else if !ok { + continue 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'") diff --git a/profiles/seccomp/seccomp_default.go b/profiles/seccomp/seccomp_default.go index 60550124da..709f553824 100644 --- a/profiles/seccomp/seccomp_default.go +++ b/profiles/seccomp/seccomp_default.go @@ -356,6 +356,13 @@ func DefaultProfile() *types.Seccomp { Action: types.ActAllow, Args: []*types.Arg{}, }, + { + Names: []string{"ptrace"}, + Action: types.ActAllow, + Includes: types.Filter{ + MinKernel: "4.8.0", + }, + }, { Names: []string{"personality"}, Action: types.ActAllow,