Add an --exec_file argument to allow argv[0] to differ from the binary being exec'd.
authorTony Young <tonyy@google.com>
Thu, 8 Jun 2017 23:57:04 +0000 (23:57 +0000)
committerTony Young <tony@rfw.name>
Fri, 9 Jun 2017 00:00:12 +0000 (00:00 +0000)
cmdline.c
common.h
config.c
subproc.c

index 8924af747703c1f11c28a9d3e96e708a58738c25..59d54c1c72c15215208d6ffe7dc4de4bf01971d0 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -66,6 +66,7 @@ struct custom_option custom_opts[] = {
      "\tr: Immediately launch a single process on the console, keep doing it "
      "forever [MODE_STANDALONE_RERUN]"},
     {{"config", required_argument, NULL, 'C'}, "Configuration file in the config.proto ProtoBuf format"},
+    {{"exec_file", required_argument, NULL, 'x'}, "File to exec (default: argv[0])"},
     {{"chroot", required_argument, NULL, 'c'}, "Directory containing / of the jail (default: none)"},
     {{"rw", no_argument, NULL, 0x601}, "Mount / and /proc as RW (default: RO)"},
     {{"user", required_argument, NULL, 'u'}, "Username/uid of processess inside the jail (default: your current uid). You can also use inside_ns_uid:outside_ns_uid:count convention here. Can be specified multiple times"},
@@ -300,6 +301,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
 {
   /*  *INDENT-OFF* */
   (*nsjconf) = (const struct nsjconf_t){
+      .exec_file = NULL,
       .hostname = "NSJAIL",
       .cwd = "/",
       .chroot = NULL,
@@ -386,12 +388,15 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
        int opt_index = 0;
        for (;;) {
                int c = getopt_long(argc, argv,
-                                   "H:D:C:c:p:i:u:g:l:t:M:Ndvqeh?E:R:B:T:P:I:U:G:", opts,
+                                   "x:H:D:C:c:p:i:u:g:l:t:M:Ndvqeh?E:R:B:T:P:I:U:G:", opts,
                                    &opt_index);
                if (c == -1) {
                        break;
                }
                switch (c) {
+               case 'x':
+                       nsjconf->exec_file = optarg;
+                       break;
                case 'H':
                        nsjconf->hostname = optarg;
                        break;
@@ -784,6 +789,9 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                cmdlineUsage(argv[0]);
                return false;
        }
+       if (nsjconf->exec_file == NULL) {
+               nsjconf->exec_file = nsjconf->argv[0];
+       }
 
        return true;
 }
index e85ff880a28941013800f15fef67977317369f24..9e91589b7098ce11af82e86ca397ebc8fdc0bfee 100644 (file)
--- a/common.h
+++ b/common.h
@@ -113,6 +113,7 @@ enum llevel_t {
 };
 
 struct nsjconf_t {
+       const char *exec_file;
        const char *hostname;
        const char *cwd;
        char *const *argv;
index ed727418fdbf08f55bc2f650d8ce8730fe857ad9..e255240d49d80f5e34961167128688b1599d79bb 100644 (file)
--- a/config.c
+++ b/config.c
@@ -232,6 +232,7 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
                        argv[i + 1] = utilStrDup(njc->exec_bin->arg[i]);
                }
                argv[njc->exec_bin->n_arg + 1] = NULL;
+               nsjconf->exec_file = argv[0];
                nsjconf->argv = argv;
        }
 
index e398a641efa40a98e588e300dcec9f011b92e28c..71f7f17b635f1908716d4f84f9b03348e352affe 100644 (file)
--- a/subproc.c
+++ b/subproc.c
@@ -165,7 +165,7 @@ static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int
 
        char cs_addr[64];
        netConnToText(fd_in, true /* remote */ , cs_addr, sizeof(cs_addr), NULL);
-       LOG_I("Executing '%s' for '%s'", nsjconf->argv[0], cs_addr);
+       LOG_I("Executing '%s' for '%s'", nsjconf->exec_file, cs_addr);
 
        for (size_t i = 0; nsjconf->argv[i]; i++) {
                LOG_D(" Arg[%zu]: '%s'", i, nsjconf->argv[i]);
@@ -175,9 +175,9 @@ static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int
        if (sandboxApply(nsjconf) == false) {
                exit(1);
        }
-       execv(nsjconf->argv[0], &nsjconf->argv[0]);
+       execv(nsjconf->exec_file, &nsjconf->argv[0]);
 
-       PLOG_E("execve('%s') failed", nsjconf->argv[0]);
+       PLOG_E("execve('%s') failed", nsjconf->exec_file);
 
        _exit(1);
 }