diff --git a/server/container_create.go b/server/container_create.go index 6501db79..b576cc1e 100644 --- a/server/container_create.go +++ b/server/container_create.go @@ -1037,6 +1037,12 @@ func (s *Server) createSandboxContainer(ctx context.Context, containerID string, containerCwd = runtimeCwd } specgen.SetProcessCwd(containerCwd) + if err := setupWorkingDirectory(mountPoint, mountLabel, containerCwd); err != nil { + if err1 := s.StorageRuntimeServer().StopContainer(containerID); err1 != nil { + return nil, fmt.Errorf("can't umount container after cwd error %v: %v", err, err1) + } + return nil, err + } var secretMounts []rspec.Mount if len(s.config.DefaultMounts) > 0 { @@ -1215,3 +1221,19 @@ func clearReadOnly(m *rspec.Mount) { } m.Options = opt } + +func setupWorkingDirectory(rootfs, mountLabel, containerCwd string) error { + fp, err := symlink.FollowSymlinkInScope(filepath.Join(rootfs, containerCwd), rootfs) + if err != nil { + return err + } + if err := os.MkdirAll(fp, 0755); err != nil { + return err + } + if mountLabel != "" { + if err1 := label.Relabel(fp, mountLabel, true); err1 != nil && err1 != unix.ENOTSUP { + return fmt.Errorf("relabel failed %s: %v", fp, err1) + } + } + return nil +} diff --git a/test/ctr.bats b/test/ctr.bats index e13b4e9d..fecd5860 100644 --- a/test/ctr.bats +++ b/test/ctr.bats @@ -896,3 +896,32 @@ function teardown() { cleanup_pods stop_crio } + +@test "ctr correctly setup working directory" { + start_crio + run crioctl pod run --config "$TESTDATA"/sandbox_config.json + echo "$output" + [ "$status" -eq 0 ] + pod_id="$output" + notexistcwd=$(cat "$TESTDATA"/container_config.json | python -c 'import json,sys;obj=json.load(sys.stdin);obj["working_dir"] = "/thisshouldntexistatall"; json.dump(obj, sys.stdout)') + echo "$notexistcwd" > "$TESTDIR"/container_cwd_notexist.json + run crioctl ctr create --config "$TESTDIR"/container_cwd_notexist.json --pod "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + ctr_id="$output" + run crioctl ctr start --id "$ctr_id" + echo "$output" + [ "$status" -eq 0 ] + + filecwd=$(cat "$TESTDATA"/container_config.json | python -c 'import json,sys;obj=json.load(sys.stdin);obj["working_dir"] = "/etc/passwd"; obj["metadata"]["name"] = "container2"; json.dump(obj, sys.stdout)') + echo "$filecwd" > "$TESTDIR"/container_cwd_file.json + run crioctl ctr create --config "$TESTDIR"/container_cwd_file.json --pod "$pod_id" + echo "$output" + [ "$status" -ne 0 ] + ctr_id="$output" + [[ "$output" =~ "not a directory" ]] + + cleanup_ctrs + cleanup_pods + stop_crio +}