@@ -33,7 +33,7 @@ import (
3333 "github.com/containerd/containerd/namespaces"
3434 "github.com/containerd/containerd/platforms"
3535 "github.com/containerd/continuity/fs"
36- "github.com/opencontainers/image-spec/specs-go/v1"
36+ v1 "github.com/opencontainers/image-spec/specs-go/v1"
3737 "github.com/opencontainers/runc/libcontainer/user"
3838 specs "github.com/opencontainers/runtime-spec/specs-go"
3939 "github.com/pkg/errors"
@@ -741,9 +741,11 @@ func WithCapabilities(caps []string) SpecOpts {
741741}
742742
743743// WithAllCapabilities sets all linux capabilities for the process
744- var WithAllCapabilities = WithCapabilities (getAllCapabilities ())
744+ var WithAllCapabilities = WithCapabilities (GetAllCapabilities ())
745745
746- func getAllCapabilities () []string {
746+ // GetAllCapabilities returns all caps up to CAP_LAST_CAP
747+ // or CAP_BLOCK_SUSPEND on RHEL6
748+ func GetAllCapabilities () []string {
747749 last := capability .CAP_LAST_CAP
748750 // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
749751 if last == capability .Cap (63 ) {
@@ -759,6 +761,61 @@ func getAllCapabilities() []string {
759761 return caps
760762}
761763
764+ func capsContain (caps []string , s string ) bool {
765+ for _ , c := range caps {
766+ if c == s {
767+ return true
768+ }
769+ }
770+ return false
771+ }
772+
773+ func removeCap (caps * []string , s string ) {
774+ for i , c := range * caps {
775+ if c == s {
776+ * caps = append ((* caps )[:i ], (* caps )[i + 1 :]... )
777+ }
778+ }
779+ }
780+
781+ // WithAddedCapabilities adds the provided capabilities
782+ func WithAddedCapabilities (caps []string ) SpecOpts {
783+ return func (_ context.Context , _ Client , _ * containers.Container , s * Spec ) error {
784+ setCapabilities (s )
785+ for _ , c := range caps {
786+ for _ , cl := range []* []string {
787+ & s .Process .Capabilities .Bounding ,
788+ & s .Process .Capabilities .Effective ,
789+ & s .Process .Capabilities .Permitted ,
790+ & s .Process .Capabilities .Inheritable ,
791+ } {
792+ if ! capsContain (* cl , c ) {
793+ * cl = append (* cl , c )
794+ }
795+ }
796+ }
797+ return nil
798+ }
799+ }
800+
801+ // WithDroppedCapabilities removes the provided capabilities
802+ func WithDroppedCapabilities (caps []string ) SpecOpts {
803+ return func (_ context.Context , _ Client , _ * containers.Container , s * Spec ) error {
804+ setCapabilities (s )
805+ for _ , c := range caps {
806+ for _ , cl := range []* []string {
807+ & s .Process .Capabilities .Bounding ,
808+ & s .Process .Capabilities .Effective ,
809+ & s .Process .Capabilities .Permitted ,
810+ & s .Process .Capabilities .Inheritable ,
811+ } {
812+ removeCap (cl , c )
813+ }
814+ }
815+ return nil
816+ }
817+ }
818+
762819// WithAmbientCapabilities set the Linux ambient capabilities for the process
763820// Ambient capabilities should only be set for non-root users or the caller should
764821// understand how these capabilities are used and set
0 commit comments