@@ -645,7 +645,7 @@ impl Wrappable for CreateRequest {
645645 set_keep_caps ( ) ?;
646646 // Set these *first*, before we exec. Otherwise
647647 // we may not be able to switch after dropping caps.
648- apply_gid_uid ( self . exec . gid , self . exec . uid ) ?;
648+ apply_gid_uid ( self . exec . gid , self . exec . uid , self . exec . supplemental_gids . as_ref ( ) ) ?;
649649 // Now, we can synchronize effective/inherited/permitted caps
650650 // as a final step.
651651 apply_capabilities ( self . capabilities . as_ref ( ) ) ?;
@@ -856,7 +856,7 @@ impl Mutatable for CreateDirMutation {
856856 }
857857}
858858
859- fn apply_gid_uid ( gid : Option < u32 > , uid : Option < u32 > ) -> Result < ( ) > {
859+ fn apply_gid_uid ( gid : Option < u32 > , uid : Option < u32 > , supplemental_gids : Option < & Vec < u32 > > ) -> Result < ( ) > {
860860 // NOTE - order is important here - must change GID *before* changing UID, to avoid
861861 // locking oneself out of the GID change with an "operation not permitted" error
862862 if let Some ( target_gid) = gid {
@@ -869,6 +869,16 @@ fn apply_gid_uid(gid: Option<u32>, uid: Option<u32>) -> Result<()> {
869869 }
870870 }
871871
872+ // Set supplemental gids, if any. As with changing the primary gid, this must happen before the UID shift.
873+ if let Some ( target_supplemental_gids) = supplemental_gids {
874+ unsafe {
875+ let gids_libc: Vec < libc:: gid_t > = target_supplemental_gids. iter ( ) . map ( |g| * g as libc:: gid_t ) . collect ( ) ;
876+ if libc:: setgroups ( gids_libc. len ( ) , gids_libc. as_ptr ( ) ) < 0 {
877+ warn ! ( "unable to set supplemental GIDs: {:?}" , Error :: last_os_error( ) ) ;
878+ }
879+ }
880+ }
881+
872882 if let Some ( target_uid) = uid {
873883 unsafe {
874884 // Check this to avoid a spurious log if we don't need to change,
0 commit comments