Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/librumphijack Use the env variable RUMPHIJACK to specify...



details:   https://anonhg.NetBSD.org/src/rev/41bf26f22251
branches:  trunk
changeset: 762252:41bf26f22251
user:      pooka <pooka%NetBSD.org@localhost>
date:      Fri Feb 18 11:41:32 2011 +0000

description:
Use the env variable RUMPHIJACK to specify what facilities should
be hijacked.  If it's not specified, the default is
"path=/rump,socket=all:nolocal".

So, if you're moof and want to relive your domain/os days (??),
you can do this:

pain-rustique:51:~> setenv RUMPHIJACK 'path=//'
pain-rustique:52:~> df //dev
Filesystem   1K-blocks       Used      Avail %Cap Mounted on
rumpfs                1          1          0 100% /
pain-rustique:53:~> df /dev
Filesystem   1K-blocks       Used      Avail %Cap Mounted on
/dev/wd0a       1019864     280640     688232  28% /

diffstat:

 lib/librumphijack/hijack.c |  169 +++++++++++++++++++++++++++++++++++++-------
 1 files changed, 139 insertions(+), 30 deletions(-)

diffs (267 lines):

diff -r b5bd9b6a023d -r 41bf26f22251 lib/librumphijack/hijack.c
--- a/lib/librumphijack/hijack.c        Fri Feb 18 10:50:56 2011 +0000
+++ b/lib/librumphijack/hijack.c        Fri Feb 18 11:41:32 2011 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: hijack.c,v 1.48 2011/02/17 17:18:08 pooka Exp $       */
+/*      $NetBSD: hijack.c,v 1.49 2011/02/18 11:41:32 pooka Exp $       */
 
 /*-
  * Copyright (c) 2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: hijack.c,v 1.48 2011/02/17 17:18:08 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.49 2011/02/18 11:41:32 pooka Exp $");
 
 #define __ssp_weak_name(fun) _hijack_ ## fun
 
@@ -300,15 +300,124 @@
        return (void *)rv;
 }
 
-static int pwdinrump = 0;
+/*
+ * This tracks if our process is in a subdirectory of /rump.
+ * It's preserved over exec.
+ */
+static bool pwdinrump = false;
+
+/*
+ * These variables are set from the RUMPHIJACK string and control
+ * which operations can product rump kernel file descriptors.
+ * This should be easily extendable for future needs.
+ */
+#define RUMPHIJACK_DEFAULT "path=/rump,socket=all:nolocal"
+static bool rumpsockets[PF_MAX];
+static const char *rumpprefix;
+static size_t rumpprefixlen;
+
+static struct {
+       int pf;
+       const char *name;
+} socketmap[] = {
+       { PF_INET, "inet" },
+       { PF_LINK, "link" },
+       { PF_ROUTE, "route" },
+       { PF_INET6, "inet6" },
+       { -1, NULL }
+};
+
+static void
+sockparser(char *buf)
+{
+       char *p, *l;
+       bool value;
+       int i;
+
+       /* if "all" is present, it must be specified first */
+       if (strncmp(buf, "all", strlen("all")) == 0) {
+               for (i = 0; i < __arraycount(rumpsockets); i++) {
+                       rumpsockets[i] = true;
+               }
+               buf += strlen("all");
+               if (*buf == ':')
+                       buf++;
+       }
+
+       for (p = strtok_r(buf, ":", &l); p; p = strtok_r(NULL, ":", &l)) {
+               value = true;
+               if (strncmp(p, "no", strlen("no")) == 0) {
+                       value = false;
+                       p += strlen("no");
+               }
 
-/* low calorie sockets? */
-static bool hostlocalsockets = true;
+               for (i = 0; socketmap[i].name; i++) {
+                       if (strcmp(p, socketmap[i].name) == 0) {
+                               rumpsockets[socketmap[i].pf] = value;
+                               break;
+                       }
+               }
+               if (socketmap[i].name == NULL) {
+                       warnx("invalid socket specifier %s", p);
+               }
+       }
+}
+
+static void
+pathparser(char *buf)
+{
+
+       if (*buf != '/')
+               errx(1, "hijack path specifier must begin with ``/''");
+
+       if ((rumpprefix = strdup(buf)) == NULL)
+               err(1, "strdup");
+       rumpprefixlen = strlen(rumpprefix);
+}
+
+static struct {
+       void (*parsefn)(char *);
+       const char *name;
+} hijackparse[] = {
+       { sockparser, "socket" },
+       { pathparser, "path" },
+       { NULL, NULL },
+};
+
+static void
+parsehijack(char *hijack)
+{
+       char *p, *p2, *l;
+       const char *hijackcopy;
+       int i;
+
+       if ((hijackcopy = strdup(hijack)) == NULL)
+               err(1, "strdup");
+
+       /* disable everything explicitly */
+       for (i = 0; i < PF_MAX; i++)
+               rumpsockets[i] = false;
+
+       for (p = strtok_r(hijack, ",", &l); p; p = strtok_r(NULL, ",", &l)) {
+               p2 = strchr(p, '=');
+               if (!p2)
+                       errx(1, "invalid hijack specifier: %s", hijackcopy);
+
+               for (i = 0; hijackparse[i].parsefn; i++) {
+                       if (strncmp(hijackparse[i].name, p,
+                           (size_t)(p2-p)) == 0) {
+                               hijackparse[i].parsefn(p2+1);
+                               break;
+                       }
+               }
+       }
+
+}
 
 static void __attribute__((constructor))
 rcinit(void)
 {
-       char buf[64];
+       char buf[1024];
        extern void *(*rumpclient_dlsym)(void *, const char *);
        unsigned i, j;
 
@@ -349,6 +458,12 @@
        if (rumpclient_init() == -1)
                err(1, "rumpclient init");
 
+       /* check which syscalls we're supposed to hijack */
+       if (getenv_r("RUMPHIJACK", buf, sizeof(buf)) == -1) {
+               strcpy(buf, RUMPHIJACK_DEFAULT);
+       }
+       parsehijack(buf);
+
        /* set client persistence level */
        if (getenv_r("RUMPHIJACK_RETRYCONNECT", buf, sizeof(buf)) != -1) {
                if (strcmp(buf, "die") == 0)
@@ -375,7 +490,7 @@
                unsetenv("RUMPHIJACK__DUP2MASK");
        }
        if (getenv_r("RUMPHIJACK__PWDINRUMP", buf, sizeof(buf)) == 0) {
-               pwdinrump = strtoul(buf, NULL, 10);
+               pwdinrump = true;
                unsetenv("RUMPHIJACK__PWDINRUMP");
        }
 }
@@ -413,15 +528,17 @@
 
 #define assertfd(_fd_) assert(ISDUP2D(_fd_) || (_fd_) >= HIJACK_FDOFF)
 
-#define RUMPPREFIX "/rump"
-static int
+static bool
 path_isrump(const char *path)
 {
 
+       if (rumpprefix == NULL)
+               return false;
+
        if (*path == '/') {
-               if (strncmp(path, RUMPPREFIX, sizeof(RUMPPREFIX)-1) == 0)
-                       return 1;
-               return 0;
+               if (strncmp(path, rumpprefix, rumpprefixlen) == 0)
+                       return true;
+               return false;
        } else {
                return pwdinrump;
        }
@@ -434,7 +551,7 @@
        const char *rv;
 
        if (*path == '/') {
-               rv = path + (sizeof(RUMPPREFIX)-1);
+               rv = path + rumpprefixlen;
                if (*rv == '\0')
                        rv = rootpath;
        } else {
@@ -577,17 +694,17 @@
 {
        int (*op_socket)(int, int, int);
        int fd;
-       bool dohost;
+       bool isrump;
 
-       dohost = hostlocalsockets && (domain == AF_LOCAL);
+       isrump = domain < PF_MAX && rumpsockets[domain];
 
-       if (dohost)
+       if (isrump)
+               op_socket = GETSYSCALL(rump, SOCKET);
+       else
                op_socket = GETSYSCALL(host, SOCKET);
-       else
-               op_socket = GETSYSCALL(rump, SOCKET);
        fd = op_socket(domain, type, protocol);
 
-       if (!dohost)
+       if (isrump)
                fd = fd_rump2host(fd);
        else
                fd = fd_dupgood(fd);
@@ -874,7 +991,7 @@
 {
        char buf[128];
        char *dup2str;
-       char *pwdinrumpstr;
+       const char *pwdinrumpstr;
        char **newenv;
        size_t nelem;
        int rv, sverrno;
@@ -892,14 +1009,7 @@
        }
 
        if (pwdinrump) {
-               snprintf(buf, sizeof(buf), "RUMPHIJACK__PWDINRUMP=%u",
-                   pwdinrump);
-               pwdinrumpstr = malloc(strlen(buf)+1);
-               if (pwdinrumpstr == NULL) {
-                       free(dup2str);
-                       return ENOMEM;
-               }
-               strcpy(pwdinrumpstr, buf);
+               pwdinrumpstr = "RUMPHIJACK__PWDINRUMP=true";
                bonus++;
        } else {
                pwdinrumpstr = NULL;
@@ -910,7 +1020,6 @@
        newenv = malloc(sizeof(*newenv) * nelem+bonus);
        if (newenv == NULL) {
                free(dup2str);
-               free(pwdinrumpstr);
                return ENOMEM;
        }
        memcpy(newenv, envp, nelem*sizeof(*newenv));
@@ -919,7 +1028,7 @@
                i++;
        }
        if (pwdinrumpstr) {
-               newenv[nelem+i] = pwdinrumpstr;
+               newenv[nelem+i] = __UNCONST(pwdinrumpstr);
                i++;
        }
        newenv[nelem+i] = NULL;



Home | Main Index | Thread Index | Old Index