Skip to content

Commit

Permalink
workdir: preserve cwd if possible when no --workdir is passed.
Browse files Browse the repository at this point in the history
  • Loading branch information
Snaipe committed May 13, 2020
1 parent f325ae7 commit ac265e1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
36 changes: 34 additions & 2 deletions enter.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* in the LICENSE file.
*/

#include <assert.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
Expand Down Expand Up @@ -133,6 +134,33 @@ int enter(struct entry_settings *opts)
err(1, "setuid");
}

char cwd[PATH_MAX];
char *workdir = opts->workdir;
if ((!workdir || workdir[0] == '\0')) {
if (getcwd(cwd, sizeof (cwd)) == NULL) {
err(1, "getcwd");
}

assert(cwd[0] == '/' && "cwd must be an absolute path");
assert(root[0] == '/' && "root must be an absolute path");

/* Pure textual prefixing -- if the root is a prefix of the cwd, we remove
it. This must be done on two absolute paths.
As an exception, if root is /, the prefix is not removed. */
size_t rootlen = strlen(root);
if (strcmp(root, "/") == 0) {
workdir = cwd;
} else if (strncmp(root, cwd, rootlen) == 0) {
workdir = cwd + rootlen;
}
}
/* Our tentative to use the cwd failed, or it worked and the cwd _is_ the
new root. In both cases, the workdir must be /. */
if (!workdir || workdir[0] == '\0') {
workdir = "/";
}

/* Unshare all relevant namespaces. It's hard to check in advance which
namespaces are supported, so we unshare them one by one in order. */

Expand Down Expand Up @@ -410,8 +438,12 @@ int enter(struct entry_settings *opts)
}
}
}
if (chdir(opts->workdir) == -1) {
err(1, "chdir");
if (chdir(workdir) == -1) {
warn("chdir(\"%s\")", workdir);
warnx("falling back work directory to /.");
if (chdir("/") == -1) {
err(1, "chdir(\"/\")");
}
}

execvpe(opts->pathname, opts->argv, opts->envp);
Expand Down
6 changes: 1 addition & 5 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,7 @@ int main(int argc, char *argv[], char *envp[])
opts.argv = new_argv;
opts.envp = envp;

if (!opts.workdir || opts.workdir[0] == 0) {
/* We don't want to remain outside the chroot. */
opts.workdir = "/";
}
if (opts.workdir[0] != '/') {
if (opts.workdir && opts.workdir[0] != '\0' && opts.workdir[0] != '/') {
errx(1, "workdir must be an absolute path.");
}

Expand Down

0 comments on commit ac265e1

Please sign in to comment.