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