jail: call build_envp() just before execve()
[project/procd.git] / jail / jail.c
index 97ddaab..e86ee14 100644 (file)
 #include <libubox/uloop.h>
 
 #define STACK_SIZE     (1024 * 1024)
-#define OPT_ARGS       "S:C:n:r:w:d:psuloc"
+#define OPT_ARGS       "S:C:n:h:r:w:d:psuloc"
 
 static struct {
        char *name;
+       char *hostname;
        char **jail_argv;
        char *seccomp;
        char *capabilities;
@@ -138,16 +139,6 @@ static int build_jail_fs(void)
                return -1;
        }
 
-       if (add_path_and_deps(*opts.jail_argv, 1, -1, 0)) {
-               ERROR("failed to load dependencies\n");
-               return -1;
-       }
-
-       if (opts.seccomp && add_path_and_deps("libpreload-seccomp.so", 1, -1, 1)) {
-               ERROR("failed to load libpreload-seccomp.so\n");
-               return -1;
-       }
-
        if (mount_all(jail_root)) {
                ERROR("mount_all() failed\n");
                return -1;
@@ -161,6 +152,10 @@ static int build_jail_fs(void)
                ERROR("pivot_root failed: %s\n", strerror(errno));
                return -1;
        }
+       if (chdir("/")) {
+               ERROR("chdir(/) failed: %s\n", strerror(errno));
+               return -1;
+       }
 
        snprintf(dirbuf, sizeof(dirbuf), "/old%s", jail_root);
        rmdir(dirbuf);
@@ -216,6 +211,7 @@ static void usage(void)
        fprintf(stderr, "  -c\t\tset PR_SET_NO_NEW_PRIVS\n");
        fprintf(stderr, "  -n <name>\tthe name of the jail\n");
        fprintf(stderr, "namespace jail options:\n");
+       fprintf(stderr, "  -h <hostname>\tchange the hostname of the jail\n");
        fprintf(stderr, "  -r <file>\treadonly files that should be staged\n");
        fprintf(stderr, "  -w <file>\twriteable files that should be staged\n");
        fprintf(stderr, "  -p\t\tjail has /proc\n");
@@ -234,10 +230,6 @@ and will only drop capabilities/apply seccomp filter.\n\n");
 
 static int exec_jail(void)
 {
-       char **envp = build_envp(opts.seccomp);
-       if (!envp)
-               exit(EXIT_FAILURE);
-
        if (opts.capabilities && drop_capabilities(opts.capabilities))
                exit(EXIT_FAILURE);
 
@@ -246,6 +238,10 @@ static int exec_jail(void)
                exit(EXIT_FAILURE);
        }
 
+       char **envp = build_envp(opts.seccomp);
+       if (!envp)
+               exit(EXIT_FAILURE);
+
        INFO("exec-ing %s\n", *opts.jail_argv);
        execve(*opts.jail_argv, opts.jail_argv, envp);
        /* we get there only if execve fails */
@@ -255,8 +251,8 @@ static int exec_jail(void)
 
 static int spawn_jail(void *_notused)
 {
-       if (opts.name && sethostname(opts.name, strlen(opts.name))) {
-               ERROR("failed to sethostname: %s\n", strerror(errno));
+       if (opts.hostname && sethostname(opts.hostname, strlen(opts.hostname))) {
+               ERROR("sethostname(%s) failed: %s\n", opts.hostname, strerror(errno));
        }
 
        if (build_jail_fs()) {
@@ -334,6 +330,9 @@ int main(int argc, char **argv)
                case 'n':
                        opts.name = optarg;
                        break;
+               case 'h':
+                       opts.hostname = optarg;
+                       break;
                case 'r':
                        opts.namespace = 1;
                        add_path_and_deps(optarg, 1, 0, 0);
@@ -370,6 +369,16 @@ int main(int argc, char **argv)
 
        opts.jail_argv = &argv[optind];
 
+       if (opts.namespace && add_path_and_deps(*opts.jail_argv, 1, -1, 0)) {
+               ERROR("failed to load dependencies\n");
+               return -1;
+       }
+
+       if (opts.namespace && opts.seccomp && add_path_and_deps("libpreload-seccomp.so", 1, -1, 1)) {
+               ERROR("failed to load libpreload-seccomp.so\n");
+               return -1;
+       }
+
        if (opts.name)
                prctl(PR_SET_NAME, opts.name, NULL, NULL, NULL);