Source-Changes-HG archive

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

[src/trunk]: src/lib/librumphijack Make fdoffset configurable. Also, enforce...



details:   https://anonhg.NetBSD.org/src/rev/7428bbfcc9d4
branches:  trunk
changeset: 763233:7428bbfcc9d4
user:      pooka <pooka%NetBSD.org@localhost>
date:      Mon Mar 14 15:13:26 2011 +0000

description:
Make fdoffset configurable.  Also, enforce that host descriptors
are smaller than the offset.

diffstat:

 lib/librumphijack/hijack.c |  63 ++++++++++++++++++++++++++++++++-------------
 1 files changed, 44 insertions(+), 19 deletions(-)

diffs (183 lines):

diff -r 8764605ec053 -r 7428bbfcc9d4 lib/librumphijack/hijack.c
--- a/lib/librumphijack/hijack.c        Mon Mar 14 14:54:07 2011 +0000
+++ b/lib/librumphijack/hijack.c        Mon Mar 14 15:13:26 2011 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: hijack.c,v 1.84 2011/03/10 23:02:56 pooka Exp $       */
+/*      $NetBSD: hijack.c,v 1.85 2011/03/14 15:13:26 pooka Exp $       */
 
 /*-
  * Copyright (c) 2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: hijack.c,v 1.84 2011/03/10 23:02:56 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.85 2011/03/14 15:13:26 pooka Exp $");
 
 #define __ssp_weak_name(fun) _hijack_ ## fun
 
@@ -274,6 +274,9 @@
 static bool            fd_isrump(int);
 static enum pathtype   path_isrump(const char *);
 
+/* default FD_SETSIZE is 256 ==> default fdoff is 128 */
+static int hijack_fdoff = FD_SETSIZE/2;
+
 /*
  * Maintain a mapping table for the usual dup2 suspects.
  * Could use atomic ops to operate on dup2vec, but an application
@@ -647,6 +650,23 @@
        errx(1, "sysctl value should be y(es)/n(o), gave: %s", buf);
 }
 
+static void
+fdoffparser(char *buf)
+{
+       unsigned long fdoff;
+       char *ep;
+
+       if (*buf == '-') {
+               errx(1, "fdoff must not be negative");
+       }
+       fdoff = strtoul(buf, &ep, 10);
+       if (*ep != '\0')
+               errx(1, "invalid fdoff specifier \"%s\"", buf);
+       if (fdoff >= INT_MAX/2 || fdoff < 3)
+               errx(1, "fdoff out of range");
+       hijack_fdoff = fdoff;
+}
+
 static struct {
        void (*parsefn)(char *);
        const char *name;
@@ -657,6 +677,7 @@
        { blanketparser, "blanket", true },
        { vfsparser, "vfs", true },
        { sysctlparser, "sysctl", false },
+       { fdoffparser, "fdoffset", true },
        { NULL, NULL, false },
 };
 
@@ -783,16 +804,13 @@
        }
 }
 
-/* Need runtime selection.  low for now due to FD_SETSIZE */
-#define HIJACK_FDOFF 128
-
 static int
 fd_rump2host(int fd)
 {
 
        if (fd == -1)
                return fd;
-       return fd + HIJACK_FDOFF;
+       return fd + hijack_fdoff;
 }
 
 static int
@@ -814,7 +832,7 @@
 {
 
        if (!isdup2d(fd))
-               return fd - HIJACK_FDOFF;
+               return fd - hijack_fdoff;
        else
                return mapdup2(fd);
 }
@@ -823,10 +841,10 @@
 fd_isrump(int fd)
 {
 
-       return isdup2d(fd) || fd >= HIJACK_FDOFF;
+       return isdup2d(fd) || fd >= hijack_fdoff;
 }
 
-#define assertfd(_fd_) assert(ISDUP2D(_fd_) || (_fd_) >= HIJACK_FDOFF)
+#define assertfd(_fd_) assert(ISDUP2D(_fd_) || (_fd_) >= hijack_fdoff)
 
 static enum pathtype
 path_isrump(const char *path)
@@ -885,8 +903,8 @@
        if (fd_isrump(oldd)) {
                op_fcntl = GETSYSCALL(rump, FCNTL);
                oldd = fd_host2rump(oldd);
-               if (minfd >= HIJACK_FDOFF)
-                       minfd -= HIJACK_FDOFF;
+               if (minfd >= hijack_fdoff)
+                       minfd -= hijack_fdoff;
                isrump = 1;
        } else {
                op_fcntl = GETSYSCALL(host, FCNTL);
@@ -903,15 +921,22 @@
 }
 
 /*
- * dup a host file descriptor so that it doesn't collide with the dup2mask
+ * Check that host fd value does not exceed fdoffset and if necessary
+ * dup the file descriptor so that it doesn't collide with the dup2mask.
  */
 static int
-fd_dupgood(int fd)
+fd_host2host(int fd)
 {
        int (*op_fcntl)(int, int, ...) = GETSYSCALL(host, FCNTL);
        int (*op_close)(int) = GETSYSCALL(host, CLOSE);
        int ofd, i;
 
+       if (fd >= hijack_fdoff) {
+               op_close(fd);
+               errno = ENFILE;
+               return -1;
+       }
+
        for (i = 1; isdup2d(fd); i++) {
                ofd = fd;
                fd = op_fcntl(ofd, F_DUPFD, i);
@@ -949,7 +974,7 @@
        if (isrump)
                fd = fd_rump2host(fd);
        else
-               fd = fd_dupgood(fd);
+               fd = fd_host2host(fd);
 
        DPRINTF(("open <- %d (%s)\n", fd, whichfd(fd)));
        return fd;
@@ -1099,7 +1124,7 @@
        if (isrump)
                fd = fd_rump2host(fd);
        else
-               fd = fd_dupgood(fd);
+               fd = fd_host2host(fd);
        DPRINTF(("socket <- %d\n", fd));
 
        return fd;
@@ -1125,7 +1150,7 @@
        if (fd != -1 && isrump)
                fd = fd_rump2host(fd);
        else
-               fd = fd_dupgood(fd);
+               fd = fd_host2host(fd);
 
        DPRINTF((" <- %d\n", fd));
 
@@ -1177,7 +1202,7 @@
                 * So, if fd < HIJACKOFF, we want to do a host closem.
                 */
 
-               if (fd < HIJACK_FDOFF) {
+               if (fd < hijack_fdoff) {
                        int closemfd = fd;
 
                        if (rumpclient__closenotify(&closemfd,
@@ -1203,8 +1228,8 @@
                        }
                }
                
-               if (fd >= HIJACK_FDOFF)
-                       fd -= HIJACK_FDOFF;
+               if (fd >= hijack_fdoff)
+                       fd -= hijack_fdoff;
                else
                        fd = 0;
                fd = MAX(maxdup2+1, fd);



Home | Main Index | Thread Index | Old Index