From 269a7175554646ee8de59a86ded8124f1d497a18 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Thu, 14 Jan 2016 18:21:36 -0500 Subject: [PATCH] Make cwd required Signed-off-by: Mrunal Patel --- libcontainer/init_linux.go | 6 ++---- libcontainer/integration/checkpoint_test.go | 2 ++ libcontainer/integration/exec_test.go | 16 ++++++++++++++++ libcontainer/integration/execin_test.go | 14 ++++++++++++++ libcontainer/integration/seccomp_test.go | 3 +++ libcontainer/integration/utils_test.go | 1 + spec.go | 15 ++++++++++++++- start.go | 1 + 8 files changed, 53 insertions(+), 5 deletions(-) diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index 57e53782..2d252bbf 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -134,10 +134,8 @@ func finalizeNamespace(config *initConfig) error { if err := w.drop(); err != nil { return err } - if config.Cwd != "" { - if err := syscall.Chdir(config.Cwd); err != nil { - return err - } + if err := syscall.Chdir(config.Cwd); err != nil { + return err } return nil } diff --git a/libcontainer/integration/checkpoint_test.go b/libcontainer/integration/checkpoint_test.go index 62cab2a3..a71c172a 100644 --- a/libcontainer/integration/checkpoint_test.go +++ b/libcontainer/integration/checkpoint_test.go @@ -82,6 +82,7 @@ func TestCheckpoint(t *testing.T) { var stdout bytes.Buffer pconfig := libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -150,6 +151,7 @@ func TestCheckpoint(t *testing.T) { } restoreProcessConfig := &libcontainer.Process{ + Cwd: "/", Stdin: restoreStdinR, Stdout: &stdout, } diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go index 6be1dd60..ca8609c8 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go @@ -208,6 +208,7 @@ func TestEnter(t *testing.T) { var stdout, stdout2 bytes.Buffer pconfig := libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "cat && readlink /proc/self/ns/pid"}, Env: standardEnvironment, Stdin: stdinR, @@ -224,6 +225,7 @@ func TestEnter(t *testing.T) { stdinR2, stdinW2, err := os.Pipe() ok(t, err) pconfig2 := libcontainer.Process{ + Cwd: "/", Env: standardEnvironment, } pconfig2.Args = []string{"sh", "-c", "cat && readlink /proc/self/ns/pid"} @@ -290,6 +292,7 @@ func TestProcessEnv(t *testing.T) { var stdout bytes.Buffer pconfig := libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "env"}, Env: []string{ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", @@ -341,6 +344,7 @@ func TestProcessCaps(t *testing.T) { var stdout bytes.Buffer pconfig := libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "cat /proc/self/status"}, Env: standardEnvironment, Capabilities: processCaps, @@ -411,6 +415,7 @@ func TestAdditionalGroups(t *testing.T) { var stdout bytes.Buffer pconfig := libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "id", "-Gn"}, Env: standardEnvironment, Stdin: nil, @@ -471,6 +476,7 @@ func testFreeze(t *testing.T, systemd bool) { ok(t, err) pconfig := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -667,6 +673,7 @@ func TestContainerState(t *testing.T) { t.Fatal(err) } p := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -717,6 +724,7 @@ func TestPassExtraFiles(t *testing.T) { pipeout1, pipein1, err := os.Pipe() pipeout2, pipein2, err := os.Pipe() process := libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "cd /proc/$$/fd; echo -n *; echo -n 1 >3; echo -n 2 >4"}, Env: []string{"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}, ExtraFiles: []*os.File{pipein1, pipein2}, @@ -800,6 +808,7 @@ func TestMountCmds(t *testing.T) { defer container.Destroy() pconfig := libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "env"}, Env: standardEnvironment, } @@ -846,6 +855,7 @@ func TestSysctl(t *testing.T) { var stdout bytes.Buffer pconfig := libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "cat /proc/sys/kernel/shmmni"}, Env: standardEnvironment, Stdin: nil, @@ -985,6 +995,7 @@ func TestOomScoreAdj(t *testing.T) { var stdout bytes.Buffer pconfig := libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "cat /proc/self/oom_score_adj"}, Env: standardEnvironment, Stdin: nil, @@ -1037,6 +1048,7 @@ func TestHook(t *testing.T) { var stdout bytes.Buffer pconfig := libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "ls /test"}, Env: standardEnvironment, Stdin: nil, @@ -1143,6 +1155,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) { ok(t, err) pconfig := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -1170,6 +1183,7 @@ func TestRootfsPropagationSlaveMount(t *testing.T) { ok(t, err) pconfig2 := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat", "/proc/self/mountinfo"}, Env: standardEnvironment, Stdin: stdinR2, @@ -1259,6 +1273,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) { ok(t, err) pconfig := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -1288,6 +1303,7 @@ func TestRootfsPropagationSharedMount(t *testing.T) { processCaps := append(config.Capabilities, "CAP_SYS_ADMIN") pconfig2 := &libcontainer.Process{ + Cwd: "/", Args: []string{"mount", "--bind", dir2cont, dir2cont}, Env: standardEnvironment, Stdin: stdinR2, diff --git a/libcontainer/integration/execin_test.go b/libcontainer/integration/execin_test.go index 2eb510da..a80c9581 100644 --- a/libcontainer/integration/execin_test.go +++ b/libcontainer/integration/execin_test.go @@ -28,6 +28,7 @@ func TestExecIn(t *testing.T) { stdinR, stdinW, err := os.Pipe() ok(t, err) process := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -39,6 +40,7 @@ func TestExecIn(t *testing.T) { buffers := newStdBuffers() ps := &libcontainer.Process{ + Cwd: "/", Args: []string{"ps"}, Env: standardEnvironment, Stdin: buffers.Stdin, @@ -73,6 +75,7 @@ func TestExecInRlimit(t *testing.T) { stdinR, stdinW, err := os.Pipe() ok(t, err) process := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -84,6 +87,7 @@ func TestExecInRlimit(t *testing.T) { buffers := newStdBuffers() ps := &libcontainer.Process{ + Cwd: "/", Args: []string{"/bin/sh", "-c", "ulimit -n"}, Env: standardEnvironment, Stdin: buffers.Stdin, @@ -119,6 +123,7 @@ func TestExecInError(t *testing.T) { stdinR, stdinW, err := os.Pipe() ok(t, err) process := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -136,6 +141,7 @@ func TestExecInError(t *testing.T) { for i := 0; i < 42; i++ { var out bytes.Buffer unexistent := &libcontainer.Process{ + Cwd: "/", Args: []string{"unexistent"}, Env: standardEnvironment, Stdout: &out, @@ -169,6 +175,7 @@ func TestExecInTTY(t *testing.T) { stdinR, stdinW, err := os.Pipe() ok(t, err) process := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -180,6 +187,7 @@ func TestExecInTTY(t *testing.T) { var stdout bytes.Buffer ps := &libcontainer.Process{ + Cwd: "/", Args: []string{"ps"}, Env: standardEnvironment, } @@ -224,6 +232,7 @@ func TestExecInEnvironment(t *testing.T) { stdinR, stdinW, err := os.Pipe() ok(t, err) process := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -235,6 +244,7 @@ func TestExecInEnvironment(t *testing.T) { buffers := newStdBuffers() process2 := &libcontainer.Process{ + Cwd: "/", Args: []string{"env"}, Env: []string{ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", @@ -286,6 +296,7 @@ func TestExecinPassExtraFiles(t *testing.T) { t.Fatal(err) } process := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -301,6 +312,7 @@ func TestExecinPassExtraFiles(t *testing.T) { pipeout1, pipein1, err := os.Pipe() pipeout2, pipein2, err := os.Pipe() inprocess := &libcontainer.Process{ + Cwd: "/", Args: []string{"sh", "-c", "cd /proc/$$/fd; echo -n *; echo -n 1 >3; echo -n 2 >4"}, Env: []string{"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}, ExtraFiles: []*os.File{pipein1, pipein2}, @@ -357,6 +369,7 @@ func TestExecInOomScoreAdj(t *testing.T) { stdinR, stdinW, err := os.Pipe() ok(t, err) process := &libcontainer.Process{ + Cwd: "/", Args: []string{"cat"}, Env: standardEnvironment, Stdin: stdinR, @@ -368,6 +381,7 @@ func TestExecInOomScoreAdj(t *testing.T) { buffers := newStdBuffers() ps := &libcontainer.Process{ + Cwd: "/", Args: []string{"/bin/sh", "-c", "cat /proc/self/oom_score_adj"}, Env: standardEnvironment, Stdin: buffers.Stdin, diff --git a/libcontainer/integration/seccomp_test.go b/libcontainer/integration/seccomp_test.go index b653d8dc..820773e6 100644 --- a/libcontainer/integration/seccomp_test.go +++ b/libcontainer/integration/seccomp_test.go @@ -42,6 +42,7 @@ func TestSeccompDenyGetcwd(t *testing.T) { buffers := newStdBuffers() pwd := &libcontainer.Process{ + Cwd: "/", Args: []string{"pwd"}, Env: standardEnvironment, Stdin: buffers.Stdin, @@ -116,6 +117,7 @@ func TestSeccompPermitWriteConditional(t *testing.T) { buffers := newStdBuffers() dmesg := &libcontainer.Process{ + Cwd: "/", Args: []string{"busybox", "ls", "/"}, Env: standardEnvironment, Stdin: buffers.Stdin, @@ -176,6 +178,7 @@ func TestSeccompDenyWriteConditional(t *testing.T) { buffers := newStdBuffers() dmesg := &libcontainer.Process{ + Cwd: "/", Args: []string{"busybox", "ls", "does_not_exist"}, Env: standardEnvironment, Stdin: buffers.Stdin, diff --git a/libcontainer/integration/utils_test.go b/libcontainer/integration/utils_test.go index 7773665b..3dcd0bb1 100644 --- a/libcontainer/integration/utils_test.go +++ b/libcontainer/integration/utils_test.go @@ -113,6 +113,7 @@ func runContainer(config *configs.Config, console string, args ...string) (buffe defer container.Destroy() buffers = newStdBuffers() process := &libcontainer.Process{ + Cwd: "/", Args: args, Env: standardEnvironment, Stdin: buffers.Stdin, diff --git a/spec.go b/spec.go index 6c5e4790..c4d0edf4 100644 --- a/spec.go +++ b/spec.go @@ -53,6 +53,7 @@ var specCommand = cli.Command{ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "TERM=xterm", }, + Cwd: "/", }, Hostname: "shell", Mounts: []specs.MountPoint{ @@ -290,6 +291,15 @@ var mountPropagationMapping = map[string]int{ "": syscall.MS_PRIVATE | syscall.MS_REC, } +// validateSpec validates the fields in the spec +// TODO: Add validation for other fields where applicable +func validateSpec(spec *specs.LinuxSpec, rspec *specs.LinuxRuntimeSpec) error { + if spec.Process.Cwd == "" { + return fmt.Errorf("Cwd property must not be empty") + } + return nil +} + // loadSpec loads the specification from the provided path. // If the path is empty then the default path will be "config.json" func loadSpec(cPath, rPath string) (spec *specs.LinuxSpec, rspec *specs.LinuxRuntimeSpec, err error) { @@ -317,7 +327,10 @@ func loadSpec(cPath, rPath string) (spec *specs.LinuxSpec, rspec *specs.LinuxRun if err = json.NewDecoder(rf).Decode(&rspec); err != nil { return spec, rspec, err } - return spec, rspec, checkSpecVersion(spec) + if err := checkSpecVersion(spec); err != nil { + return spec, rspec, err + } + return spec, rspec, validateSpec(spec, rspec) } // checkSpecVersion makes sure that the spec version matches runc's while we are in the initial diff --git a/start.go b/start.go index 6c34bee1..8f2d8584 100644 --- a/start.go +++ b/start.go @@ -108,6 +108,7 @@ func startContainer(context *cli.Context, spec *specs.LinuxSpec, rspec *specs.Li // ensure that the container is always removed if we were the process // that created it. defer destroy(container) + process := newProcess(spec.Process) // Support on-demand socket activation by passing file descriptors into the container init process.