@@ -24,6 +24,7 @@ import (
2424 "testing"
2525
2626 "github.com/containerd/containerd/containers"
27+ "github.com/containerd/containerd/pkg/cap"
2728 "github.com/containerd/containerd/pkg/testutil"
2829 "github.com/containerd/continuity/fs/fstest"
2930 specs "github.com/opencontainers/runtime-spec/specs-go"
@@ -216,6 +217,91 @@ sys:x:3:root,bin,adm
216217 }
217218}
218219
220+ // withAllKnownCaps sets all known capabilities.
221+ // This function differs from the exported function
222+ // by also setting inheritable capabilities.
223+ func withAllKnownCaps (s * specs.Spec ) error {
224+ caps := cap .Known ()
225+ if err := WithCapabilities (caps )(context .Background (), nil , nil , s ); err != nil {
226+ return err
227+ }
228+ s .Process .Capabilities .Inheritable = caps
229+ return nil
230+ }
231+
232+ func TestSetCaps (t * testing.T ) {
233+ t .Parallel ()
234+
235+ var s specs.Spec
236+
237+ // Add base set of capabilities
238+ if err := WithCapabilities ([]string {"CAP_CHOWN" })(context .Background (), nil , nil , & s ); err != nil {
239+ t .Fatal (err )
240+ }
241+ for i , cl := range [][]string {
242+ s .Process .Capabilities .Bounding ,
243+ s .Process .Capabilities .Effective ,
244+ s .Process .Capabilities .Permitted ,
245+ } {
246+ if ! capsContain (cl , "CAP_CHOWN" ) {
247+ t .Errorf ("cap list %d does not contain added cap" , i )
248+ }
249+ if len (cl ) != 1 {
250+ t .Errorf ("cap list %d does not have only 1 cap" , i )
251+ }
252+ }
253+ if len (s .Process .Capabilities .Inheritable ) != 0 {
254+ t .Errorf ("inheritable cap list is not empty" )
255+ }
256+
257+ // Add all caps then overwrite with single cap
258+ if err := withAllKnownCaps (& s ); err != nil {
259+ t .Fatal (err )
260+ }
261+ if err := WithCapabilities ([]string {"CAP_CHOWN" })(context .Background (), nil , nil , & s ); err != nil {
262+ t .Fatal (err )
263+ }
264+ for i , cl := range [][]string {
265+ s .Process .Capabilities .Bounding ,
266+ s .Process .Capabilities .Effective ,
267+ s .Process .Capabilities .Permitted ,
268+ s .Process .Capabilities .Inheritable ,
269+ } {
270+ if ! capsContain (cl , "CAP_CHOWN" ) {
271+ t .Errorf ("cap list %d does not contain added cap" , i )
272+ }
273+ if len (cl ) != 1 {
274+ t .Errorf ("cap list %d does not have only 1 cap" , i )
275+ }
276+ }
277+
278+ // Add all caps, drop single cap, then overwrite with single cap
279+ if err := withAllKnownCaps (& s ); err != nil {
280+ t .Fatal (err )
281+ }
282+ if err := WithDroppedCapabilities ([]string {"CAP_CHOWN" })(context .Background (), nil , nil , & s ); err != nil {
283+ t .Fatal (err )
284+ }
285+ if err := WithCapabilities ([]string {"CAP_CHOWN" })(context .Background (), nil , nil , & s ); err != nil {
286+ t .Fatal (err )
287+ }
288+ for i , cl := range [][]string {
289+ s .Process .Capabilities .Bounding ,
290+ s .Process .Capabilities .Effective ,
291+ s .Process .Capabilities .Permitted ,
292+ } {
293+ if ! capsContain (cl , "CAP_CHOWN" ) {
294+ t .Errorf ("cap list %d does not contain added cap" , i )
295+ }
296+ if len (cl ) != 1 {
297+ t .Errorf ("cap list %d does not have only 1 cap" , i )
298+ }
299+ }
300+ if len (s .Process .Capabilities .Inheritable ) != 0 {
301+ t .Errorf ("inheritable cap list is not empty" )
302+ }
303+ }
304+
219305func TestAddCaps (t * testing.T ) {
220306 t .Parallel ()
221307
@@ -233,14 +319,17 @@ func TestAddCaps(t *testing.T) {
233319 t .Errorf ("cap list %d does not contain added cap" , i )
234320 }
235321 }
322+ if len (s .Process .Capabilities .Inheritable ) != 0 {
323+ t .Errorf ("inheritable cap list is not empty" )
324+ }
236325}
237326
238327func TestDropCaps (t * testing.T ) {
239328 t .Parallel ()
240329
241330 var s specs.Spec
242331
243- if err := WithAllKnownCapabilities ( context . Background (), nil , nil , & s ); err != nil {
332+ if err := withAllKnownCaps ( & s ); err != nil {
244333 t .Fatal (err )
245334 }
246335 if err := WithDroppedCapabilities ([]string {"CAP_CHOWN" })(context .Background (), nil , nil , & s ); err != nil {
@@ -251,14 +340,15 @@ func TestDropCaps(t *testing.T) {
251340 s .Process .Capabilities .Bounding ,
252341 s .Process .Capabilities .Effective ,
253342 s .Process .Capabilities .Permitted ,
343+ s .Process .Capabilities .Inheritable ,
254344 } {
255345 if capsContain (cl , "CAP_CHOWN" ) {
256346 t .Errorf ("cap list %d contains dropped cap" , i )
257347 }
258348 }
259349
260350 // Add all capabilities back and drop a different cap.
261- if err := WithAllKnownCapabilities ( context . Background (), nil , nil , & s ); err != nil {
351+ if err := withAllKnownCaps ( & s ); err != nil {
262352 t .Fatal (err )
263353 }
264354 if err := WithDroppedCapabilities ([]string {"CAP_FOWNER" })(context .Background (), nil , nil , & s ); err != nil {
@@ -269,6 +359,7 @@ func TestDropCaps(t *testing.T) {
269359 s .Process .Capabilities .Bounding ,
270360 s .Process .Capabilities .Effective ,
271361 s .Process .Capabilities .Permitted ,
362+ s .Process .Capabilities .Inheritable ,
272363 } {
273364 if capsContain (cl , "CAP_FOWNER" ) {
274365 t .Errorf ("cap list %d contains dropped cap" , i )
@@ -289,6 +380,25 @@ func TestDropCaps(t *testing.T) {
289380 s .Process .Capabilities .Bounding ,
290381 s .Process .Capabilities .Effective ,
291382 s .Process .Capabilities .Permitted ,
383+ s .Process .Capabilities .Inheritable ,
384+ } {
385+ if len (cl ) != 0 {
386+ t .Errorf ("cap list %d is not empty" , i )
387+ }
388+ }
389+
390+ // Add all capabilities back and drop all
391+ if err := withAllKnownCaps (& s ); err != nil {
392+ t .Fatal (err )
393+ }
394+ if err := WithCapabilities (nil )(context .Background (), nil , nil , & s ); err != nil {
395+ t .Fatal (err )
396+ }
397+ for i , cl := range [][]string {
398+ s .Process .Capabilities .Bounding ,
399+ s .Process .Capabilities .Effective ,
400+ s .Process .Capabilities .Permitted ,
401+ s .Process .Capabilities .Inheritable ,
292402 } {
293403 if len (cl ) != 0 {
294404 t .Errorf ("cap list %d is not empty" , i )
0 commit comments