diff options
author | Ian Lewis <ianlewis@google.com> | 2020-06-11 19:29:34 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-06-11 19:31:24 -0700 |
commit | 8ea99d58ffd708aa7a26be58d89cb817d8eceec6 (patch) | |
tree | d5ff8477c5f13082364398cc20e73781322921a0 /runsc | |
parent | 5a894e35a090232085fbb20c71d1787c266bd995 (diff) |
Set the HOME environment variable for sub-containers.
Fixes #701
PiperOrigin-RevId: 316025635
Diffstat (limited to 'runsc')
-rw-r--r-- | runsc/boot/loader.go | 15 | ||||
-rw-r--r-- | runsc/container/multi_container_test.go | 80 |
2 files changed, 95 insertions, 0 deletions
diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 002479612..b05a8bd45 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -754,6 +754,21 @@ func (l *Loader) startContainer(spec *specs.Spec, conf *Config, cid string, file return err } + // Add the HOME enviroment variable if it is not already set. + var envv []string + if kernel.VFS2Enabled { + envv, err = user.MaybeAddExecUserHomeVFS2(ctx, procArgs.MountNamespaceVFS2, + procArgs.Credentials.RealKUID, procArgs.Envv) + + } else { + envv, err = user.MaybeAddExecUserHome(ctx, procArgs.MountNamespace, + procArgs.Credentials.RealKUID, procArgs.Envv) + } + if err != nil { + return err + } + procArgs.Envv = envv + // Create and start the new process. tg, _, err := l.k.CreateProcess(procArgs) if err != nil { diff --git a/runsc/container/multi_container_test.go b/runsc/container/multi_container_test.go index c2b54696c..a27a01942 100644 --- a/runsc/container/multi_container_test.go +++ b/runsc/container/multi_container_test.go @@ -1698,3 +1698,83 @@ func TestMultiContainerRunNonRoot(t *testing.T) { t.Fatalf("child container failed, waitStatus: %v", ws) } } + +// TestMultiContainerHomeEnvDir tests that the HOME environment variable is set +// for root containers, sub-containers, and execed processes. +func TestMultiContainerHomeEnvDir(t *testing.T) { + // TODO(gvisor.dev/issue/1487): VFSv2 configs failing. + // NOTE: Don't use overlay since we need changes to persist to the temp dir + // outside the sandbox. + for testName, conf := range configs(t, noOverlay...) { + t.Run(testName, func(t *testing.T) { + + rootDir, cleanup, err := testutil.SetupRootDir() + if err != nil { + t.Fatalf("error creating root dir: %v", err) + } + defer cleanup() + conf.RootDir = rootDir + + // Create temp files we can write the value of $HOME to. + homeDirs := map[string]*os.File{} + for _, name := range []string{"root", "sub", "exec"} { + homeFile, err := ioutil.TempFile(testutil.TmpDir(), name) + if err != nil { + t.Fatalf("creating temp file: %v", err) + } + homeDirs[name] = homeFile + } + + // We will sleep in the root container in order to ensure that + // the root container doesn't terminate before sub containers can be + // created. + rootCmd := []string{"/bin/sh", "-c", fmt.Sprintf("printf \"$HOME\" > %s; sleep 1000", homeDirs["root"].Name())} + subCmd := []string{"/bin/sh", "-c", fmt.Sprintf("printf \"$HOME\" > %s", homeDirs["sub"].Name())} + execCmd := []string{"/bin/sh", "-c", fmt.Sprintf("printf \"$HOME\" > %s", homeDirs["exec"].Name())} + + // Setup the containers, a root container and sub container. + specConfig, ids := createSpecs(rootCmd, subCmd) + containers, cleanup, err := startContainers(conf, specConfig, ids) + if err != nil { + t.Fatalf("error starting containers: %v", err) + } + defer cleanup() + + // Exec into the root container synchronously. + args := &control.ExecArgs{Argv: execCmd} + if _, err := containers[0].executeSync(args); err != nil { + t.Errorf("error executing %+v: %v", args, err) + } + + // Wait for the subcontainer to finish. + _, err = containers[1].Wait() + if err != nil { + t.Errorf("wait on child container: %v", err) + } + + // Wait for the root container to run. + expectedPL := []*control.Process{ + newProcessBuilder().Cmd("sh").Process(), + newProcessBuilder().Cmd("sleep").Process(), + } + if err := waitForProcessList(containers[0], expectedPL); err != nil { + t.Errorf("failed to wait for sleep to start: %v", err) + } + + // Check the written files. + for name, tmpFile := range homeDirs { + dirBytes, err := ioutil.ReadAll(tmpFile) + if err != nil { + t.Fatalf("reading %s temp file: %v", name, err) + } + got := string(dirBytes) + + want := "/" + if got != want { + t.Errorf("%s $HOME incorrect: got: %q, want: %q", name, got, want) + } + } + + }) + } +} |