@@ -11,7 +11,6 @@ import (
1111 "runtime"
1212 "runtime/debug"
1313 "strconv"
14- "strings"
1514 "syscall"
1615
1716 "github.com/containerd/console"
@@ -185,8 +184,8 @@ func startInitialization() (retErr error) {
185184 defer pidfdSocket .Close ()
186185 }
187186
188- // clear the current process's environment to clean any libcontainer
189- // specific env vars .
187+ // From here on, we don't need current process environment. It is not
188+ // used directly anywhere below this point, but let's clear it anyway .
190189 os .Clearenv ()
191190
192191 defer func () {
@@ -209,9 +208,11 @@ func startInitialization() (retErr error) {
209208}
210209
211210func containerInit (t initType , config * initConfig , pipe * syncSocket , consoleSocket , pidfdSocket , fifoFile , logPipe * os.File ) error {
212- if err := populateProcessEnvironment (config .Env ); err != nil {
211+ env , homeSet , err := prepareEnv (config .Env )
212+ if err != nil {
213213 return err
214214 }
215+ config .Env = env
215216
216217 // Clean the RLIMIT_NOFILE cache in go runtime.
217218 // Issue: https://github.com/opencontainers/runc/issues/4195
@@ -225,6 +226,7 @@ func containerInit(t initType, config *initConfig, pipe *syncSocket, consoleSock
225226 pidfdSocket : pidfdSocket ,
226227 config : config ,
227228 logPipe : logPipe ,
229+ addHome : ! homeSet ,
228230 }
229231 return i .Init ()
230232 case initStandard :
@@ -236,36 +238,13 @@ func containerInit(t initType, config *initConfig, pipe *syncSocket, consoleSock
236238 config : config ,
237239 fifoFile : fifoFile ,
238240 logPipe : logPipe ,
241+ addHome : ! homeSet ,
239242 }
240243 return i .Init ()
241244 }
242245 return fmt .Errorf ("unknown init type %q" , t )
243246}
244247
245- // populateProcessEnvironment loads the provided environment variables into the
246- // current processes's environment.
247- func populateProcessEnvironment (env []string ) error {
248- for _ , pair := range env {
249- name , val , ok := strings .Cut (pair , "=" )
250- if ! ok {
251- return errors .New ("invalid environment variable: missing '='" )
252- }
253- if name == "" {
254- return errors .New ("invalid environment variable: name cannot be empty" )
255- }
256- if strings .IndexByte (name , 0 ) >= 0 {
257- return fmt .Errorf ("invalid environment variable %q: name contains nul byte (\\ x00)" , name )
258- }
259- if strings .IndexByte (val , 0 ) >= 0 {
260- return fmt .Errorf ("invalid environment variable %q: value contains nul byte (\\ x00)" , name )
261- }
262- if err := os .Setenv (name , val ); err != nil {
263- return err
264- }
265- }
266- return nil
267- }
268-
269248// verifyCwd ensures that the current directory is actually inside the mount
270249// namespace root of the current process.
271250func verifyCwd () error {
@@ -294,8 +273,8 @@ func verifyCwd() error {
294273
295274// finalizeNamespace drops the caps, sets the correct user
296275// and working dir, and closes any leaked file descriptors
297- // before executing the command inside the namespace
298- func finalizeNamespace (config * initConfig ) error {
276+ // before executing the command inside the namespace.
277+ func finalizeNamespace (config * initConfig , addHome bool ) error {
299278 // Ensure that all unwanted fds we may have accidentally
300279 // inherited are marked close-on-exec so they stay out of the
301280 // container
@@ -341,7 +320,7 @@ func finalizeNamespace(config *initConfig) error {
341320 if err := system .SetKeepCaps (); err != nil {
342321 return fmt .Errorf ("unable to set keep caps: %w" , err )
343322 }
344- if err := setupUser (config ); err != nil {
323+ if err := setupUser (config , addHome ); err != nil {
345324 return fmt .Errorf ("unable to setup user: %w" , err )
346325 }
347326 // Change working directory AFTER the user has been set up, if we haven't done it yet.
@@ -459,8 +438,9 @@ func syncParentSeccomp(pipe *syncSocket, seccompFd int) error {
459438 return readSync (pipe , procSeccompDone )
460439}
461440
462- // setupUser changes the groups, gid, and uid for the user inside the container
463- func setupUser (config * initConfig ) error {
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 {
464444 // Set up defaults.
465445 defaultExecUser := user.ExecUser {
466446 Uid : 0 ,
@@ -541,11 +521,9 @@ func setupUser(config *initConfig) error {
541521 return err
542522 }
543523
544- // if we didn't get HOME already, set it based on the user's HOME
545- if envHome := os .Getenv ("HOME" ); envHome == "" {
546- if err := os .Setenv ("HOME" , execUser .Home ); err != nil {
547- return err
548- }
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 )
549527 }
550528 return nil
551529}
0 commit comments