@@ -38,6 +38,7 @@ import (
38
38
39
39
. "github.com/onsi/ginkgo/v2"
40
40
. "github.com/onsi/gomega"
41
+ . "github.com/onsi/gomega/gstruct"
41
42
)
42
43
43
44
const (
@@ -307,57 +308,6 @@ var _ = framework.KubeDescribe("Security Context", func() {
307
308
Expect (groups ).To (ContainElement ("5678" ))
308
309
})
309
310
310
- It ("if the container's primary UID belongs to some groups in the image, runtime should add SupplementalGroups to them" , func () {
311
- By ("create pod" )
312
- podID , podConfig , podLogDir = createPodSandboxWithLogDirectory (rc )
313
-
314
- By ("create container for security context SupplementalGroups" )
315
- supplementalGroup := int64 (1234 )
316
- containerName := "container-with-SupplementalGroups-and-predefined-group-image-test-" + framework .NewUUID ()
317
- logPath := containerName + ".log"
318
- containerConfig := & runtimeapi.ContainerConfig {
319
- Metadata : framework .BuildContainerMetadata (containerName , framework .DefaultAttempt ),
320
- Image : & runtimeapi.ImageSpec {Image : testImagePreDefinedGroup },
321
- Command : []string {"sh" , "-c" , "id -G; while :; do sleep 1; done" },
322
- Linux : & runtimeapi.LinuxContainerConfig {
323
- SecurityContext : & runtimeapi.LinuxContainerSecurityContext {
324
- RunAsUser : & runtimeapi.Int64Value {Value : imagePredefinedGroupUID },
325
- SupplementalGroups : []int64 {supplementalGroup },
326
- },
327
- },
328
- LogPath : logPath ,
329
- }
330
- containerID := framework .CreateContainer (rc , ic , containerConfig , podID , podConfig )
331
-
332
- By ("start container" )
333
- startContainer (rc , containerID )
334
- Eventually (func (g Gomega ) {
335
- g .Expect (getContainerStatus (rc , containerID ).State ).To (Equal (runtimeapi .ContainerState_CONTAINER_RUNNING ))
336
- g .Expect (parseLogLine (podConfig , logPath )).NotTo (BeEmpty ())
337
- }, time .Minute , time .Second * 4 ).Should (Succeed ())
338
-
339
- // In testImagePreDefinedGroup,
340
- // - its default user is default-user(uid=1000)
341
- // - default-user belongs to group-defined-in-image(gid=50000)
342
- //
343
- // thus, supplementary group of the container processes should be
344
- // - 1000: self
345
- // - 1234: SupplementalGroups
346
- // - 50000: groups define in the container image
347
- //
348
- // $ id -G
349
- // 1000 1234 5678 50000
350
- expectedOutput := fmt .Sprintf ("%d %d %d\n " , imagePredefinedGroupUID , supplementalGroup , imagePredefinedGroupGID )
351
-
352
- By ("verify groups for the first process of the container" )
353
- verifyLogContents (podConfig , logPath , expectedOutput , stdoutType )
354
-
355
- By ("verify groups for 'exec'-ed process of container" )
356
- command := []string {"id" , "-G" }
357
- o := execSyncContainer (rc , containerID , command )
358
- Expect (o ).To (BeEquivalentTo (expectedOutput ))
359
- })
360
-
361
311
It ("runtime should support RunAsUser" , func () {
362
312
By ("create pod" )
363
313
podID , podConfig = framework .CreatePodSandboxForContainer (rc )
@@ -640,6 +590,151 @@ var _ = framework.KubeDescribe("Security Context", func() {
640
590
})
641
591
})
642
592
593
+ Context ("SupplementalGroupsPolicy" , func () {
594
+ BeforeEach (func (ctx context.Context ) {
595
+ By ("skip if the runtime does not support SupplementalGroupsPolicy" )
596
+ statusResponse , err := rc .Status (ctx , false )
597
+ Expect (err ).NotTo (HaveOccurred ())
598
+ if ! (statusResponse .Features != nil && statusResponse .Features .SupplementalGroupsPolicy ) {
599
+ Skip ("The runtime does not support SupplementalGroupsPolicy feature" )
600
+ }
601
+ })
602
+
603
+ When ("SupplementalGroupsPolicy=Merge (Default)" , func () {
604
+ It ("if the container's primary UID belongs to some groups in the image, runtime should add SupplementalGroups to them" , func () {
605
+ By ("create pod" )
606
+ podID , podConfig , podLogDir = createPodSandboxWithLogDirectory (rc )
607
+
608
+ By ("create container for security context SupplementalGroups" )
609
+ supplementalGroup := int64 (1234 )
610
+ containerName := "container-with-SupplementalGroupsPolicyMerge-" + framework .NewUUID ()
611
+ logPath := containerName + ".log"
612
+ containerConfig := & runtimeapi.ContainerConfig {
613
+ Metadata : framework .BuildContainerMetadata (containerName , framework .DefaultAttempt ),
614
+ Image : & runtimeapi.ImageSpec {Image : testImagePreDefinedGroup },
615
+ Command : []string {"sh" , "-c" , "id -G; while :; do sleep 1; done" },
616
+ Linux : & runtimeapi.LinuxContainerConfig {
617
+ SecurityContext : & runtimeapi.LinuxContainerSecurityContext {
618
+ RunAsUser : & runtimeapi.Int64Value {Value : imagePredefinedGroupUID },
619
+ SupplementalGroups : []int64 {supplementalGroup },
620
+ // SupplementalGroupsPolicy_Merge is default(0)
621
+ // SupplementalGroupsPolicy: runtimeapi.SupplementalGroupsPolicy_Merge,
622
+ },
623
+ },
624
+ LogPath : logPath ,
625
+ }
626
+ containerID := framework .CreateContainer (rc , ic , containerConfig , podID , podConfig )
627
+
628
+ By ("start container" )
629
+ startContainer (rc , containerID )
630
+
631
+ Eventually (func (g Gomega ) {
632
+ containerStatus := getContainerStatus (rc , containerID )
633
+ g .Expect (containerStatus .State ).To (Equal (runtimeapi .ContainerState_CONTAINER_RUNNING ))
634
+ // In testImagePreDefinedGroup,
635
+ // - its default user is default-user(uid=1000)
636
+ // - default-user belongs to group-defined-in-image(gid=50000) in /etc/group
637
+ // And, SupplementalGroupsPolicy is Merge(default)
638
+ //
639
+ // Thus, firstly attached process identity of the first container processes should be
640
+ // - uid: 1000 (RunAsUser)
641
+ // - gid: 1000 (default group for uid=1000)
642
+ // - supplementary groups
643
+ // - 1000: self
644
+ // - 1234: SupplementalGroups
645
+ // - 50000: groups defined in the container image (/etc/group)
646
+ g .Expect (containerStatus .User ).To (PointTo (MatchFields (IgnoreExtras , Fields {
647
+ "Linux" : PointTo (MatchFields (IgnoreExtras , Fields {
648
+ "Uid" : Equal (imagePredefinedGroupUID ),
649
+ "Gid" : Equal (imagePredefinedGroupUID ),
650
+ // we can not assume the order of gids
651
+ "SupplementalGroups" : And (ContainElements (imagePredefinedGroupUID , supplementalGroup , imagePredefinedGroupGID ), HaveLen (3 )),
652
+ })),
653
+ })))
654
+ g .Expect (parseLogLine (podConfig , logPath )).NotTo (BeEmpty ())
655
+ }, time .Minute , time .Second * 4 ).Should (Succeed ())
656
+
657
+ // $ id -G
658
+ // 1000 1234 50000
659
+ expectedOutput := fmt .Sprintf ("%d %d %d\n " , imagePredefinedGroupUID , supplementalGroup , imagePredefinedGroupGID )
660
+
661
+ By ("verify groups for the first process of the container" )
662
+ verifyLogContents (podConfig , logPath , expectedOutput , stdoutType )
663
+
664
+ By ("verify groups for 'exec'-ed process of container" )
665
+ command := []string {"id" , "-G" }
666
+ o := execSyncContainer (rc , containerID , command )
667
+ Expect (o ).To (BeEquivalentTo (expectedOutput ))
668
+ })
669
+ })
670
+ When ("SupplementalGroupsPolicy=Strict" , func () {
671
+ It ("even if the container's primary UID belongs to some groups in the image, runtime should not add SupplementalGroups to them" , func () {
672
+ By ("create pod" )
673
+ podID , podConfig , podLogDir = createPodSandboxWithLogDirectory (rc )
674
+
675
+ By ("create container for security context SupplementalGroups" )
676
+ supplementalGroup := int64 (1234 )
677
+ containerName := "container-with-SupplementalGroupsPolicyMerge-" + framework .NewUUID ()
678
+ logPath := containerName + ".log"
679
+ containerConfig := & runtimeapi.ContainerConfig {
680
+ Metadata : framework .BuildContainerMetadata (containerName , framework .DefaultAttempt ),
681
+ Image : & runtimeapi.ImageSpec {Image : testImagePreDefinedGroup },
682
+ Command : []string {"sh" , "-c" , "id -G; while :; do sleep 1; done" },
683
+ Linux : & runtimeapi.LinuxContainerConfig {
684
+ SecurityContext : & runtimeapi.LinuxContainerSecurityContext {
685
+ RunAsUser : & runtimeapi.Int64Value {Value : imagePredefinedGroupUID },
686
+ SupplementalGroups : []int64 {supplementalGroup },
687
+ SupplementalGroupsPolicy : runtimeapi .SupplementalGroupsPolicy_Strict ,
688
+ },
689
+ },
690
+ LogPath : logPath ,
691
+ }
692
+ containerID := framework .CreateContainer (rc , ic , containerConfig , podID , podConfig )
693
+
694
+ By ("start container" )
695
+ startContainer (rc , containerID )
696
+
697
+ Eventually (func (g Gomega ) {
698
+ containerStatus := getContainerStatus (rc , containerID )
699
+ g .Expect (containerStatus .State ).To (Equal (runtimeapi .ContainerState_CONTAINER_RUNNING ))
700
+ // In testImagePreDefinedGroup,
701
+ // - its default user is default-user(uid=1000)
702
+ // - default-user belongs to group-defined-in-image(gid=50000) in /etc/group
703
+ // And, SupplementalGroupsPolicy is Strict
704
+ //
705
+ // Thus, firstly attached process identity of the first container processes should be
706
+ // (5000(defined in /etc/group) is not appended to supplementary groups)
707
+ // - uid: 1000 (RunAsUser)
708
+ // - gid: 1000 (default group for uid=1000)
709
+ // - supplementary groups
710
+ // - 1000: self
711
+ // - 1234: SupplementalGroups
712
+ g .Expect (containerStatus .User ).To (PointTo (MatchFields (IgnoreExtras , Fields {
713
+ "Linux" : PointTo (MatchFields (IgnoreExtras , Fields {
714
+ "Uid" : Equal (imagePredefinedGroupUID ),
715
+ "Gid" : Equal (imagePredefinedGroupUID ),
716
+ // we can not assume the order of gids
717
+ "SupplementalGroups" : And (ContainElements (imagePredefinedGroupUID , supplementalGroup ), HaveLen (2 )),
718
+ })),
719
+ })))
720
+ g .Expect (parseLogLine (podConfig , logPath )).NotTo (BeEmpty ())
721
+ }, time .Minute , time .Second * 4 ).Should (Succeed ())
722
+
723
+ // $ id -G
724
+ // 1000 1234
725
+ expectedOutput := fmt .Sprintf ("%d %d\n " , imagePredefinedGroupUID , supplementalGroup )
726
+
727
+ By ("verify groups for the first process of the container" )
728
+ verifyLogContents (podConfig , logPath , expectedOutput , stdoutType )
729
+
730
+ By ("verify groups for 'exec'-ed process of container" )
731
+ command := []string {"id" , "-G" }
732
+ o := execSyncContainer (rc , containerID , command )
733
+ Expect (o ).To (BeEquivalentTo (expectedOutput ))
734
+ })
735
+ })
736
+ })
737
+
643
738
// TODO(random-liu): We should set apparmor to unconfined in seccomp test to prevent
644
739
// them from interfering with each other.
645
740
Context ("SeccompProfilePath" , func () {
0 commit comments