@@ -14,7 +14,6 @@ import (
1414 "syscall"
1515
1616 "github.com/containerd/console"
17- "github.com/moby/sys/user"
1817 "github.com/opencontainers/runtime-spec/specs-go"
1918 "github.com/sirupsen/logrus"
2019 "github.com/vishvananda/netlink"
@@ -57,8 +56,9 @@ type initConfig struct {
5756 ProcessLabel string `json:"process_label"`
5857 AppArmorProfile string `json:"apparmor_profile"`
5958 NoNewPrivileges bool `json:"no_new_privileges"`
60- User string `json:"user"`
61- AdditionalGroups []string `json:"additional_groups"`
59+ UID int `json:"uid"`
60+ GID int `json:"gid"`
61+ AdditionalGroups []int `json:"additional_groups"`
6262 Config * configs.Config `json:"config"`
6363 Networks []* network `json:"network"`
6464 PassedFilesCount int `json:"passed_files_count"`
@@ -208,7 +208,7 @@ func startInitialization() (retErr error) {
208208}
209209
210210func containerInit (t initType , config * initConfig , pipe * syncSocket , consoleSocket , pidfdSocket , fifoFile , logPipe * os.File ) error {
211- env , homeSet , err := prepareEnv (config .Env )
211+ env , err := prepareEnv (config .Env , config . UID )
212212 if err != nil {
213213 return err
214214 }
@@ -226,7 +226,6 @@ func containerInit(t initType, config *initConfig, pipe *syncSocket, consoleSock
226226 pidfdSocket : pidfdSocket ,
227227 config : config ,
228228 logPipe : logPipe ,
229- addHome : ! homeSet ,
230229 }
231230 return i .Init ()
232231 case initStandard :
@@ -238,7 +237,6 @@ func containerInit(t initType, config *initConfig, pipe *syncSocket, consoleSock
238237 config : config ,
239238 fifoFile : fifoFile ,
240239 logPipe : logPipe ,
241- addHome : ! homeSet ,
242240 }
243241 return i .Init ()
244242 }
@@ -274,7 +272,7 @@ func verifyCwd() error {
274272// finalizeNamespace drops the caps, sets the correct user
275273// and working dir, and closes any leaked file descriptors
276274// before executing the command inside the namespace.
277- func finalizeNamespace (config * initConfig , addHome bool ) error {
275+ func finalizeNamespace (config * initConfig ) error {
278276 // Ensure that all unwanted fds we may have accidentally
279277 // inherited are marked close-on-exec so they stay out of the
280278 // container
@@ -320,7 +318,7 @@ func finalizeNamespace(config *initConfig, addHome bool) error {
320318 if err := system .SetKeepCaps (); err != nil {
321319 return fmt .Errorf ("unable to set keep caps: %w" , err )
322320 }
323- if err := setupUser (config , addHome ); err != nil {
321+ if err := setupUser (config ); err != nil {
324322 return fmt .Errorf ("unable to setup user: %w" , err )
325323 }
326324 // Change working directory AFTER the user has been set up, if we haven't done it yet.
@@ -438,52 +436,11 @@ func syncParentSeccomp(pipe *syncSocket, seccompFd int) error {
438436 return readSync (pipe , procSeccompDone )
439437}
440438
441- // setupUser changes the groups, gid, and uid for the user inside the container,
442- // and appends user's HOME to config.Env if addHome is true.
443- func setupUser (config * initConfig , addHome bool ) error {
444- // Set up defaults.
445- defaultExecUser := user.ExecUser {
446- Uid : 0 ,
447- Gid : 0 ,
448- Home : "/" ,
449- }
450-
451- passwdPath , err := user .GetPasswdPath ()
452- if err != nil {
453- return err
454- }
455-
456- groupPath , err := user .GetGroupPath ()
457- if err != nil {
458- return err
459- }
460-
461- execUser , err := user .GetExecUserPath (config .User , & defaultExecUser , passwdPath , groupPath )
462- if err != nil {
463- return err
464- }
465-
466- var addGroups []int
467- if len (config .AdditionalGroups ) > 0 {
468- addGroups , err = user .GetAdditionalGroupsPath (config .AdditionalGroups , groupPath )
469- if err != nil {
470- return err
471- }
472- }
473-
474- if config .RootlessEUID {
475- // We cannot set any additional groups in a rootless container and thus
476- // we bail if the user asked us to do so. TODO: We currently can't do
477- // this check earlier, but if libcontainer.Process.User was typesafe
478- // this might work.
479- if len (addGroups ) > 0 {
480- return errors .New ("cannot set any additional groups in a rootless container" )
481- }
482- }
483-
439+ // setupUser changes the groups, gid, and uid for the user inside the container.
440+ func setupUser (config * initConfig ) error {
484441 // Before we change to the container's user make sure that the processes
485442 // STDIO is correctly owned by the user that we are switching to.
486- if err := fixStdioPermissions (execUser ); err != nil {
443+ if err := fixStdioPermissions (config . UID ); err != nil {
487444 return err
488445 }
489446
@@ -502,36 +459,30 @@ func setupUser(config *initConfig, addHome bool) error {
502459 allowSupGroups := ! config .RootlessEUID && string (bytes .TrimSpace (setgroups )) != "deny"
503460
504461 if allowSupGroups {
505- suppGroups := append (execUser .Sgids , addGroups ... )
506- if err := unix .Setgroups (suppGroups ); err != nil {
462+ if err := unix .Setgroups (config .AdditionalGroups ); err != nil {
507463 return & os.SyscallError {Syscall : "setgroups" , Err : err }
508464 }
509465 }
510466
511- if err := unix .Setgid (execUser . Gid ); err != nil {
467+ if err := unix .Setgid (config . GID ); err != nil {
512468 if err == unix .EINVAL {
513- return fmt .Errorf ("cannot setgid to unmapped gid %d in user namespace" , execUser . Gid )
469+ return fmt .Errorf ("cannot setgid to unmapped gid %d in user namespace" , config . GID )
514470 }
515471 return err
516472 }
517- if err := unix .Setuid (execUser . Uid ); err != nil {
473+ if err := unix .Setuid (config . UID ); err != nil {
518474 if err == unix .EINVAL {
519- return fmt .Errorf ("cannot setuid to unmapped uid %d in user namespace" , execUser . Uid )
475+ return fmt .Errorf ("cannot setuid to unmapped uid %d in user namespace" , config . UID )
520476 }
521477 return err
522478 }
523-
524- // If we didn't get HOME already, set it based on the user's HOME.
525- if addHome {
526- config .Env = append (config .Env , "HOME=" + execUser .Home )
527- }
528479 return nil
529480}
530481
531- // fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified user .
482+ // fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified uid .
532483// The ownership needs to match because it is created outside of the container and needs to be
533484// localized.
534- func fixStdioPermissions (u * user. ExecUser ) error {
485+ func fixStdioPermissions (uid int ) error {
535486 var null unix.Stat_t
536487 if err := unix .Stat ("/dev/null" , & null ); err != nil {
537488 return & os.PathError {Op : "stat" , Path : "/dev/null" , Err : err }
@@ -544,7 +495,7 @@ func fixStdioPermissions(u *user.ExecUser) error {
544495
545496 // Skip chown if uid is already the one we want or any of the STDIO descriptors
546497 // were redirected to /dev/null.
547- if int (s .Uid ) == u . Uid || s .Rdev == null .Rdev {
498+ if int (s .Uid ) == uid || s .Rdev == null .Rdev {
548499 continue
549500 }
550501
@@ -554,7 +505,7 @@ func fixStdioPermissions(u *user.ExecUser) error {
554505 // that users expect to be able to actually use their console. Without
555506 // this code, you couldn't effectively run as a non-root user inside a
556507 // container and also have a console set up.
557- if err := file .Chown (u . Uid , int (s .Gid )); err != nil {
508+ if err := file .Chown (uid , int (s .Gid )); err != nil {
558509 // If we've hit an EINVAL then s.Gid isn't mapped in the user
559510 // namespace. If we've hit an EPERM then the inode's current owner
560511 // is not mapped in our user namespace (in particular,
0 commit comments