Source-Changes-HG archive

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

[src/trunk]: src/lib/librumphijack Add ``blanket''. It acts like path, excep...



details:   https://anonhg.NetBSD.org/src/rev/239dc8acdd80
branches:  trunk
changeset: 763036:239dc8acdd80
user:      pooka <pooka%NetBSD.org@localhost>
date:      Tue Mar 08 20:59:01 2011 +0000

description:
Add ``blanket''.  It acts like path, except that the prefix does
_not_ get removed if the call goes to the rump namespace.

So, now it's possible to use e.g. tcpdump (and most other utilities
which hardcore a /dev pathname) on a rump kernel:

golem> setenv RUMPHIJACK blanket=/dev/bpf
golem> tcpdump -n -i virt0
tcpdump: WARNING: SIOCGIFADDR: virt0: Device not configured
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on virt0, link-type EN10MB (Ethernet), capture size 96 bytes
21:55:38.925596 IP 192.168.2.101 > 204.152.190.12: ICMP echo request, id 47811, seq 0, length 64
21:55:39.095596 IP 204.152.190.12 > 192.168.2.101: ICMP echo reply, id 47811, seq 0, length 64

(if you additionally set socket=all in RUMPHIJACK, tcpdump doesn't
whine about the "not configured" interface)

diffstat:

 lib/librumphijack/hijack.c     |  143 +++++++++++++++++++++++++++-------------
 lib/librumphijack/rumphijack.3 |   45 ++++++++++++-
 2 files changed, 137 insertions(+), 51 deletions(-)

diffs (truncated from 346 to 300 lines):

diff -r 6c7b2f724501 -r 239dc8acdd80 lib/librumphijack/hijack.c
--- a/lib/librumphijack/hijack.c        Tue Mar 08 19:25:32 2011 +0000
+++ b/lib/librumphijack/hijack.c        Tue Mar 08 20:59:01 2011 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: hijack.c,v 1.74 2011/03/01 10:54:06 pooka Exp $       */
+/*      $NetBSD: hijack.c,v 1.75 2011/03/08 20:59:01 pooka Exp $       */
 
 /*-
  * Copyright (c) 2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: hijack.c,v 1.74 2011/03/01 10:54:06 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.75 2011/03/08 20:59:01 pooka Exp $");
 
 #define __ssp_weak_name(fun) _hijack_ ## fun
 
@@ -237,8 +237,16 @@
 static int     (*host_execve)(const char *, char *const[], char *const[]);
 static void *  (*host_mmap)(void *, size_t, int, int, int, off_t);
 
-static bool    fd_isrump(int);
-static bool    path_isrump(const char *);
+/*
+ * This tracks if our process is in a subdirectory of /rump.
+ * It's preserved over exec.
+ */
+static bool pwdinrump;
+
+enum pathtype { PATH_HOST, PATH_RUMP, PATH_RUMPBLANKET };
+
+static bool            fd_isrump(int);
+static enum pathtype   path_isrump(const char *);
 
 /*
  * Maintain a mapping table for the usual dup2 suspects.
@@ -381,12 +389,14 @@
 type name args                                                         \
 {                                                                      \
        type (*fun) proto;                                              \
+       enum pathtype pt;                                               \
                                                                        \
        DPRINTF(("%s -> %s (%s)\n", __STRING(name), path,               \
            whichpath(path)));                                          \
-       if (path_isrump(path)) {                                        \
+       if ((pt = path_isrump(path)) != PATH_HOST) {                    \
                fun = syscalls[rcname].bs_rump;                         \
-               path = path_host2rump(path);                            \
+               if (pt == PATH_RUMP)                                    \
+                       path = path_host2rump(path);                    \
        } else {                                                        \
                fun = syscalls[rcname].bs_host;                         \
        }                                                               \
@@ -395,12 +405,6 @@
 }
 
 /*
- * 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.
@@ -483,12 +487,46 @@
        rumpprefixlen = strlen(rumpprefix);
 }
 
+static struct blanket {
+       const char *pfx;
+       size_t len;
+} *blanket;
+static int nblanket;
+
+static void
+blanketparser(char *buf)
+{
+       char *p, *l;
+       int i;
+
+       for (nblanket = 0, p = buf; p; p = strchr(p+1, ':'), nblanket++)
+               continue;
+
+       blanket = malloc(nblanket * sizeof(*blanket));
+       if (blanket == NULL)
+               err(1, "alloc blanket %d", nblanket);
+
+       for (p = strtok_r(buf, ":", &l), i = 0; p;
+           p = strtok_r(NULL, ":", &l), i++) {
+               blanket[i].pfx = strdup(p);
+               if (blanket[i].pfx == NULL)
+                       err(1, "strdup blanket");
+               blanket[i].len = strlen(p);
+
+               if (blanket[i].len == 0 || *blanket[i].pfx != '/')
+                       errx(1, "invalid blanket specifier %s", p);
+               if (*(blanket[i].pfx + blanket[i].len-1) == '/')
+                       errx(1, "invalid blanket specifier %s", p);
+       }
+}
+
 static struct {
        void (*parsefn)(char *);
        const char *name;
 } hijackparse[] = {
        { sockparser, "socket" },
        { pathparser, "path" },
+       { blanketparser, "blanket" },
        { NULL, NULL },
 };
 
@@ -651,19 +689,28 @@
 
 #define assertfd(_fd_) assert(ISDUP2D(_fd_) || (_fd_) >= HIJACK_FDOFF)
 
-static bool
+static enum pathtype
 path_isrump(const char *path)
 {
+       int i;
 
-       if (rumpprefix == NULL)
-               return false;
+       if (rumpprefix == NULL && nblanket == 0)
+               return PATH_HOST;
 
        if (*path == '/') {
-               if (strncmp(path, rumpprefix, rumpprefixlen) == 0)
-                       return true;
-               return false;
+               if (rumpprefix) {
+                       if (strncmp(path, rumpprefix, rumpprefixlen) == 0) {
+                               return PATH_RUMP;
+                       }
+               }
+               for (i = 0; i < nblanket; i++) {
+                       if (strncmp(path, blanket[i].pfx, blanket[i].len) == 0)
+                               return PATH_RUMPBLANKET;
+               }
+
+               return PATH_HOST;
        } else {
-               return pwdinrump;
+               return pwdinrump ? PATH_RUMP : PATH_HOST;
        }
 }
 
@@ -737,12 +784,14 @@
        int (*op_open)(const char *, int, ...);
        bool isrump;
        va_list ap;
+       enum pathtype pt;
        int fd;
 
        DPRINTF(("open -> %s (%s)\n", path, whichpath(path)));
 
-       if (path_isrump(path)) {
-               path = path_host2rump(path);
+       if ((pt = path_isrump(path)) != PATH_HOST) {
+               if (pt == PATH_RUMP)
+                       path = path_host2rump(path);
                op_open = GETSYSCALL(rump, OPEN);
                isrump = true;
        } else {
@@ -767,25 +816,20 @@
 chdir(const char *path)
 {
        int (*op_chdir)(const char *);
-       bool isrump;
+       enum pathtype pt;
        int rv;
 
-       if (path_isrump(path)) {
+       if ((pt = path_isrump(path)) != PATH_HOST) {
                op_chdir = GETSYSCALL(rump, CHDIR);
-               isrump = true;
-               path = path_host2rump(path);
+               if (pt == PATH_RUMP)
+                       path = path_host2rump(path);
        } else {
                op_chdir = GETSYSCALL(host, CHDIR);
-               isrump = false;
        }
 
        rv = op_chdir(path);
-       if (rv == 0) {
-               if (isrump)
-                       pwdinrump = true;
-               else
-                       pwdinrump = false;
-       }
+       if (rv == 0)
+               pwdinrump = pt != PATH_HOST;
 
        return rv;
 }
@@ -808,10 +852,7 @@
 
        rv = op_fchdir(fd);
        if (rv == 0) {
-               if (isrump)
-                       pwdinrump = true;
-               else
-                       pwdinrump = false;
+               pwdinrump = isrump;
        }
 
        return rv;
@@ -821,12 +862,11 @@
 __getcwd(char *bufp, size_t len)
 {
        int (*op___getcwd)(char *, size_t);
+       size_t prefixgap;
+       bool iamslash;
        int rv;
 
-       if (pwdinrump) {
-               size_t prefixgap;
-               bool iamslash;
-
+       if (pwdinrump && rumpprefix) {
                if (rumpprefix[rumpprefixlen-1] == '/')
                        iamslash = true;
                else
@@ -856,30 +896,37 @@
                /* don't append extra slash in the purely-slash case */
                if (rv == 2 && !iamslash)
                        bufp[rumpprefixlen] = '\0';
-
-               return rv;
+       } else if (pwdinrump) {
+               /* assume blanket.  we can't provide a prefix here */
+               op___getcwd = GETSYSCALL(rump, __GETCWD);
+               rv = op___getcwd(bufp, len);
        } else {
                op___getcwd = GETSYSCALL(host, __GETCWD);
-               return op___getcwd(bufp, len);
+               rv = op___getcwd(bufp, len);
        }
+
+       return rv;
 }
 
 int
 rename(const char *from, const char *to)
 {
        int (*op_rename)(const char *, const char *);
+       enum pathtype ptf, ptt;
 
-       if (path_isrump(from)) {
-               if (!path_isrump(to)) {
+       if ((ptf = path_isrump(from)) != PATH_HOST) {
+               if ((ptt = path_isrump(to)) == PATH_HOST) {
                        errno = EXDEV;
                        return -1;
                }
 
-               from = path_host2rump(from);
-               to = path_host2rump(to);
+               if (ptf == PATH_RUMP)
+                       from = path_host2rump(from);
+               if (ptt == PATH_RUMP)
+                       to = path_host2rump(to);
                op_rename = GETSYSCALL(rump, RENAME);
        } else {
-               if (path_isrump(to)) {
+               if (path_isrump(to) != PATH_HOST) {
                        errno = EXDEV;
                        return -1;
                }
diff -r 6c7b2f724501 -r 239dc8acdd80 lib/librumphijack/rumphijack.3
--- a/lib/librumphijack/rumphijack.3    Tue Mar 08 19:25:32 2011 +0000
+++ b/lib/librumphijack/rumphijack.3    Tue Mar 08 20:59:01 2011 +0000
@@ -1,4 +1,4 @@
-.\"     $NetBSD: rumphijack.3,v 1.5 2011/02/20 14:21:04 pooka Exp $
+.\"     $NetBSD: rumphijack.3,v 1.6 2011/03/08 20:59:01 pooka Exp $
 .\"
 .\" Copyright (c) 2011 Antti Kantee.  All rights reserved.
 .\"
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd February 18, 2011
+.Dd March 8, 2011
 .Dt RUMPHIJACK 3
 .Os
 .Sh NAME
@@ -53,7 +53,7 @@
 .Dq name=value
 tuples.
 The possible lefthandside names are:
-.Bl -tag -width xxsocketxx
+.Bl -tag -width xxblanketxx
 .It Dq path
 Pathname-based system calls are hijacked if the path the system
 call is directed to resides under



Home | Main Index | Thread Index | Old Index