diff --git a/capability/capability.go b/capability/capability.go index 1b36f5f..a8f6187 100644 --- a/capability/capability.go +++ b/capability/capability.go @@ -59,6 +59,12 @@ type Capabilities interface { // Apply apply the capabilities settings, so all changes will take // effect. Apply(kind CapType) error + + SetAmbient(cap ...Cap) error + + RemoveAmbient(cap ...Cap) error + + ClearAmbient() error } // NewPid initializes a new [Capabilities] object for given pid when diff --git a/capability/capability_linux.go b/capability/capability_linux.go index 6f00f78..e2ea63e 100644 --- a/capability/capability_linux.go +++ b/capability/capability_linux.go @@ -364,12 +364,15 @@ func (c *capsV3) Apply(kind CapType) error { } if kind&AMBS == AMBS { + err = c.ClearAmbient() + if err != nil && !ignorableError(err) { + return err + } for i := Cap(0); i <= last; i++ { - action := pr_CAP_AMBIENT_LOWER - if c.Get(AMBIENT, i) { - action = pr_CAP_AMBIENT_RAISE + if !c.Get(AMBIENT, i) { + continue } - err = prctl(pr_CAP_AMBIENT, action, uintptr(i), 0, 0) + err = c.SetAmbient(i) if err != nil && !ignorableError(err) { return err } @@ -379,6 +382,36 @@ func (c *capsV3) Apply(kind CapType) error { return nil } +func (c *capsV3) setAmbient(raise bool, cap ...Cap) error { + action := pr_CAP_AMBIENT_LOWER + if raise { + action = pr_CAP_AMBIENT_RAISE + } + for _, val := range cap { + err := prctl(pr_CAP_AMBIENT, action, uintptr(val), 0, 0) + if err != nil && !ignorableError(err) { + return err + } + } + return nil +} + +func (c *capsV3) SetAmbient(cap ...Cap) error { + return c.setAmbient(true, cap...) +} + +func (c *capsV3) RemoveAmbient(cap ...Cap) error { + return c.setAmbient(false, cap...) +} + +func (c *capsV3) ClearAmbient() error { + err := prctl(pr_CAP_AMBIENT, pr_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) + if err != nil && ignorableError(err) { + return nil + } + return err +} + func newFile(path string) (c Capabilities, err error) { c = &capsFile{path: path} return @@ -534,3 +567,15 @@ func (c *capsFile) Apply(kind CapType) (err error) { } return } + +func (c *capsFile) SetAmbient(cap ...Cap) error { + return errors.New("ambient cap is not supported for a file") +} + +func (c *capsFile) RemoveAmbient(cap ...Cap) error { + return errors.New("ambient cap is not supported for a file") +} + +func (c *capsFile) ClearAmbient() error { + return errors.New("ambient cap is not supported for a file") +}