diff options
author | Fabricio Voznika <fvoznika@google.com> | 2018-09-19 17:14:20 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-09-19 17:15:14 -0700 |
commit | e3952733011df912ecaa48974832a054a45c345a (patch) | |
tree | fccc5d39886cfa3d881d86504df06e5b0aed4118 /runsc/cmd/capability.go | |
parent | 2ad3228cd0f226804cfc7ae3ae7fff561caa2eda (diff) |
Fix sandbox and gofer capabilities
Capabilities.Set() adds capabilities,
but doesn't remove existing ones that might have been loaded. Fixed
the code and added tests.
PiperOrigin-RevId: 213726369
Change-Id: Id7fa6fce53abf26c29b13b9157bb4c6616986fba
Diffstat (limited to 'runsc/cmd/capability.go')
-rw-r--r-- | runsc/cmd/capability.go | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/runsc/cmd/capability.go b/runsc/cmd/capability.go index e2410d4ad..affbb7ce3 100644 --- a/runsc/cmd/capability.go +++ b/runsc/cmd/capability.go @@ -16,56 +16,67 @@ package cmd import ( "fmt" - "os" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/syndtr/gocapability/capability" "gvisor.googlesource.com/gvisor/pkg/log" ) +var allCapTypes = []capability.CapType{ + capability.BOUNDS, + capability.EFFECTIVE, + capability.PERMITTED, + capability.INHERITABLE, + capability.AMBIENT, +} + // applyCaps applies the capabilities in the spec to the current thread. // // Note that it must be called with current thread locked. func applyCaps(caps *specs.LinuxCapabilities) error { - setter, err := capability.NewPid2(os.Getpid()) + // Load current capabilities to trim the ones not permitted. + curCaps, err := capability.NewPid2(0) if err != nil { return err } - if err := setter.Load(); err != nil { + if err := curCaps.Load(); err != nil { return err } - bounding, err := trimCaps(caps.Bounding, setter) + // Create an empty capability set to populate. + newCaps, err := capability.NewPid2(0) if err != nil { return err } - setter.Set(capability.BOUNDS, bounding...) - effective, err := trimCaps(caps.Effective, setter) - if err != nil { - return err - } - setter.Set(capability.EFFECTIVE, effective...) - - permitted, err := trimCaps(caps.Permitted, setter) - if err != nil { - return err + for _, c := range allCapTypes { + if !newCaps.Empty(c) { + panic("unloaded capabilities must be empty") + } + set, err := trimCaps(getCaps(c, caps), curCaps) + if err != nil { + return err + } + newCaps.Set(c, set...) } - setter.Set(capability.PERMITTED, permitted...) - inheritable, err := trimCaps(caps.Inheritable, setter) - if err != nil { - return err - } - setter.Set(capability.INHERITABLE, inheritable...) + return newCaps.Apply(capability.CAPS | capability.BOUNDS | capability.AMBS) +} - ambient, err := trimCaps(caps.Ambient, setter) - if err != nil { - return err +func getCaps(which capability.CapType, caps *specs.LinuxCapabilities) []string { + switch which { + case capability.BOUNDS: + return caps.Bounding + case capability.EFFECTIVE: + return caps.Effective + case capability.PERMITTED: + return caps.Permitted + case capability.INHERITABLE: + return caps.Inheritable + case capability.AMBIENT: + return caps.Ambient } - setter.Set(capability.AMBIENT, ambient...) - - return setter.Apply(capability.CAPS | capability.BOUNDS | capability.AMBS) + panic(fmt.Sprint("invalid capability type:", which)) } func trimCaps(names []string, setter capability.Capabilities) ([]capability.Cap, error) { |