-
Notifications
You must be signed in to change notification settings - Fork 146
ace: add Linux-specific seccomp isolator #621
Conversation
var seccomp types.AsIsolator | ||
switch mode { | ||
case "remove": | ||
seccomp, err = types.NewLinuxSeccompRemoveSet(errno, strings.Split(patchSeccompSet, ",")...) |
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.
Looks like errno could be unset in this place if it's not in cmdline parameters. Is this desired?
Also this looks like errno should be declared as errno := "EPERM"
around 326 line.
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.
Other possibility - command line help could be misinterpreted as me as example shows ;)
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.
Ok, docs are more clear in this, so IMO cmdline help is not so clear.
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.
errno
is optional, so an empty string is a desired default. Command line help marks it as an optional parameter:
[--seccomp-mode=remove|retain[,errno=EPERM]]
In which way you don't find it clear? Any way I can improve it to be more immediate to grasp?
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.
Sorry for mess. It was unclear for me which errno values could be used in this place. After a break - it's clear for me to comment AFTER reading WHOLE diff...
920fc7e
to
31925ae
Compare
@alban amended as per your suggestions. Maintainers PTAL, if fine I'd like to see this landing soon. |
@@ -250,6 +264,31 @@ func patchManifest(im *schema.ImageManifest) error { | |||
} | |||
} | |||
|
|||
if patchSeccompMode != "" { | |||
i := 0 |
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.
I'm confused by this change; seems like you're being careful to remove any existing isolator by the given name - but we weren't (and still aren't) doing this for the other cases (like patchRevokeCaps
), instead just appending to the list.
I suppose it's underspecified in the spec that the list can contain multiple entries of a particular name, and we're arguably just skirting around this today by having GetByName return the last in the list. But can we split this out so that we perform consistently for the new isolator types, and then clear that up in a subsequent change?
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.
Correct, I made it explicit in the two seccomp isolators, but behavior for others is not specified. At which level do you want to split this out? Something like introducing a ReplaceIsolatorsByName(Isolator, []string)
?
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.
hmm; I don't want to drag you into too much of a yakshave here. you've just unfortunately highlighted this issue that's now going to nag me :-)
Perhaps the minimal change to this diff to appease my pedantry would be to add sections to the other isolators to say that they "may be listed multiple times but only the last will be considered" or something to that effect. Then we're not conflating that behavioural change with the addition of seccomp stuff.
Then, subsequently, we could have ReplaceIsolatorsByName
as you suggest, and tighten up the requirements for the other isolators too. WDYT?
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.
I need to rework this anyway: as you tangentially highlighted, I'm replacing just the last isolators in the array instead of all of them. As such, I need something like ReplaceIsolatorsByName
even if just for seccomp.
I don't think it makes much sense to partially clarify an unspecified behavior now in a half-baked way, just to re-visit and perhaps change it soon later. Plus, there are several other corner-cases which may be worth to address (eg. precedence of multiple isolators in pod+app scopes). Some details have been unspecified so far and I also like to disambiguate them, but I don't agree on rushing to do it here.
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.
I don't think it's half-baked, it's just specifying the current (unfortunate) behaviour. How do you want to move forward here?
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.
Leave it unspecified for the moment and then clarify a sane behavior once for all. I think somewhere else in the code there are already checks/assumptions about unique isolator entries, and I pretty much prefer tightening the specs instead of codifying accidental behaviors.
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.
OK, can you file a follow up for that and we can get this in?
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.
Sure! Follow-up is at #625.
3e2e69b
to
a655b6e
Compare
@lucab ready for review? |
@jonboulle rebased once more as travis catched an additional error case. It should be ready for another round now, yes. |
if err := i.Value().AssertValid(); err != nil { | ||
return err | ||
} | ||
if typesMap[i.Name]+1 > i.Value().MaxInstances() { |
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.
This check returning an error about duplicates presumes that MaxInstances is always 1 - perhaps "isolators set contains too many of type %s" or something
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.
Ack, changed to a more neutral wording.
a655b6e
to
9aa8eda
Compare
@jonboulle latest revision accounts for your further review (also left some additional comments inline). |
@@ -284,6 +319,47 @@ func patchManifest(im *schema.ImageManifest) error { | |||
return nil | |||
} | |||
|
|||
// parseSeccompArgs parses seccomp mode and set CLI flags, preparing an | |||
// appropriate seccomp isolator. | |||
func parseSeccompArgs(patchSeccompMode string, patchSeccompSet string) (types.AsIsolator, error) { |
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.
Why does this return AsIsolator and not just Isolator?
return err | ||
} | ||
if typesMap[i.Name]+1 > i.Value().MaxInstances() { | ||
return fmt.Errorf(`isolators set contains too many instances of type %s"`, i.Name) |
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.
Check out https://github.com/appc/spec/blob/master/schema/types/errors.go#L26 for an alternative way to go here
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.
Thanks for the hint, I see this is part of what we were discussing today. I think it won't fit with the surrounding style here, but I'll consider it for the future.
9aa8eda
to
fc30bbf
Compare
@jonboulle would you mind another round? |
b183ae9
to
b931ddc
Compare
@jonboulle @alban anything else needing rework here? |
// ReplaceIsolatorsByName overrides matching isolator types with a new | ||
// isolator, deleting them all and appending the new one instead | ||
func (is *Isolators) ReplaceIsolatorsByName(newIs Isolator, oldNames []ACIdentifier) uint { | ||
var numReplacements uint = 0 |
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.
Why bothering counting numReplacements? the only caller of this function ignore the returned value.
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.
That's its only way to signal if it actually replaced anything. While the current caller doesn't use it, I don't think it's a good idea to remove this observable return value completely.
b931ddc
to
1c5a245
Compare
A couple small open questions around style but generally this LGTM. @lucab let me know if you want to change those or just move forward with this as-is. |
1c5a245
to
682d131
Compare
set []string | ||
errno string | ||
|
||
expectedSet []LinuxSeccompEntry |
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.
you went in the wrong direction here - the rest of the file is pretty consistent with w/want :-(
LGTM |
This is a proposal for two Linux-specific security isolators based on seccomp filters. It follows closely the capabilities isolators, where two modes are provided: "remove-set" (blacklisting) and "retain-set" (whitelisting).
Given the huge number of syscalls that can be specified this way and the on-going discussion about sensible defaults, this specification doesn't hardcode any list but let implementations some freedom to provide groups/wildcards via
@
-prefixed special values. Users can decide to provide their own custom filters, or just opt-in/opt-out those implementations-provided filters.Fixes #529