-
Notifications
You must be signed in to change notification settings - Fork 18.8k
seccomp: allow ptrace(2) for 4.8+ kernels #38137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -366,6 +366,18 @@ | |
"includes": {}, | ||
"excludes": {} | ||
}, | ||
{ | ||
"names": [ | ||
"ptrace" | ||
], | ||
"action": "SCMP_ACT_ALLOW", | ||
"args": null, | ||
"comment": "", | ||
"includes": { | ||
"minKernel": "4.8.0" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know generally we tried to avoid kernel version checks; Will this be an issue if distros backport this fix? (i.e., would there be another approach so that the default could manually be overridden at compile time?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If a distro backports they will just not get the ptrace support even if it may be secure for their kernel as well. User can still fix it in that case by providing a custom profile or upgrading the kernel. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, not sure if there's a cleaner solution. Was just thinking if (e.g.) Red Hat decides to backport, and Docker wants to ship Docker EE packages for RHEL with a correct profile There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can ship a different default profile anyway, so I don't think this is an issue. |
||
}, | ||
"excludes": {} | ||
}, | ||
{ | ||
"names": [ | ||
"personality" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure I like defining local closures like this, can you just make it a helper function external to this? (yes, Go should allow local functions...) |
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in the error case should we not just include the rule anyway? ie fail closed not error. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should fail only in the case where profile had a version that couldn't be parsed. I think that case is similar to the other validation, eg. the |
||
} 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'") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically the kernel version is |
||
}, | ||
}, | ||
{ | ||
Names: []string{"personality"}, | ||
Action: types.ActAllow, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using empty array
[]
instead ofnull
for consistency.