Source-Changes-HG archive

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

[src/trunk]: src/lib Make rumpclient impervious to LD_PRELOAD syscall hijacki...



details:   https://anonhg.NetBSD.org/src/rev/6e9434d9bd58
branches:  trunk
changeset: 760570:6e9434d9bd58
user:      pooka <pooka%NetBSD.org@localhost>
date:      Fri Jan 07 19:37:51 2011 +0000

description:
Make rumpclient impervious to LD_PRELOAD syscall hijacking by using
dlsym(RTLD_NEXT) to lookup a host_syscall() function pointer which
is used instead of syscall() to communicate with the kernel server.

WARNING: popular opinion classifies this as "ugly code".  if you
have a weak heart/mind/soul/sole meuniere, read max. 1 line of the
diff per day, preferably with food.

diffstat:

 lib/librumpclient/rumpclient.c |  54 ++++++++++++++++++++++++++++++++++++-----
 lib/librumpuser/sp_common.c    |  20 ++++++++++----
 2 files changed, 61 insertions(+), 13 deletions(-)

diffs (196 lines):

diff -r 94318e2eba35 -r 6e9434d9bd58 lib/librumpclient/rumpclient.c
--- a/lib/librumpclient/rumpclient.c    Fri Jan 07 18:24:53 2011 +0000
+++ b/lib/librumpclient/rumpclient.c    Fri Jan 07 19:37:51 2011 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpclient.c,v 1.12 2011/01/06 06:57:14 pooka Exp $   */
+/*      $NetBSD: rumpclient.c,v 1.13 2011/01/07 19:37:51 pooka Exp $   */
 
 /*
  * Copyright (c) 2010, 2011 Antti Kantee.  All Rights Reserved.
@@ -41,8 +41,10 @@
 #include <netinet/tcp.h>
 
 #include <assert.h>
+#include <dlfcn.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <link.h>
 #include <poll.h>
 #include <pthread.h>
 #include <signal.h>
@@ -54,6 +56,18 @@
 
 #include <rump/rumpclient.h>
 
+#define HOSTOPS
+int    (*host_socket)(int, int, int);
+int    (*host_close)(int);
+int    (*host_connect)(int, const struct sockaddr *, socklen_t);
+int    (*host_poll)(struct pollfd *, nfds_t, int);
+int    (*host_pollts)(struct pollfd *, nfds_t, const struct timespec *,
+                     const sigset_t *);
+ssize_t        (*host_read)(int, void *, size_t);
+ssize_t (*host_sendto)(int, const void *, size_t, int,
+                      const struct sockaddr *, socklen_t);
+int    (*host_setsockopt)(int, int, int, const void *, socklen_t);
+
 #include "sp_common.c"
 
 static struct spclient clispc = {
@@ -99,7 +113,7 @@
                        case 0:
                                releasercvlock(spc);
                                pthread_mutex_unlock(&spc->spc_mtx);
-                               pollts(&pfd, 1, NULL, mask);
+                               host_pollts(&pfd, 1, NULL, mask);
                                pthread_mutex_lock(&spc->spc_mtx);
                                continue;
                        case -1:
@@ -375,11 +389,11 @@
        int s, error;
        ssize_t n;
 
-       s = socket(parsetab[ptab_idx].domain, SOCK_STREAM, 0);
+       s = host_socket(parsetab[ptab_idx].domain, SOCK_STREAM, 0);
        if (s == -1)
                return -1;
 
-       if (connect(s, serv_sa, (socklen_t)serv_sa->sa_len) == -1) {
+       if (host_connect(s, serv_sa, (socklen_t)serv_sa->sa_len) == -1) {
                error = errno;
                fprintf(stderr, "rump_sp: client connect failed\n");
                errno = error;
@@ -393,7 +407,7 @@
                return -1;
        }
 
-       if ((n = read(s, banner, sizeof(banner)-1)) < 0) {
+       if ((n = host_read(s, banner, sizeof(banner)-1)) < 0) {
                error = errno;
                fprintf(stderr, "rump_sp: failed to read banner\n");
                errno = error;
@@ -417,12 +431,38 @@
        return 0;
 }
 
+void *(*rumpclient_dlsym)(void *, const char *);
+
 int
 rumpclient_init()
 {
        char *p;
        int error;
 
+       /* dlsym overrided by rumphijack? */
+       if (!rumpclient_dlsym)
+               rumpclient_dlsym = dlsym;
+
+       /*
+        * sag mir, wo die symbol sind.  zogen fort, der krieg beginnt.
+        * wann wird man je verstehen?  wann wird man je verstehen?
+        */
+#define FINDSYM2(_name_,_syscall_)                                     \
+       if ((host_##_name_ = rumpclient_dlsym(RTLD_NEXT,                \
+           #_syscall_)) == NULL)                                       \
+               /* host_##_name_ = _syscall_ */;
+#define FINDSYM(_name_) FINDSYM2(_name_,_name_)
+       FINDSYM2(socket,__socket30);
+       FINDSYM(close);
+       FINDSYM(connect);
+       FINDSYM(poll);
+       FINDSYM(pollts);
+       FINDSYM(read);
+       FINDSYM(sendto);
+       FINDSYM(setsockopt);
+#undef FINDSYM
+#undef FINDSY2
+
        if ((p = getenv("RUMP_SERVER")) == NULL) {
                errno = ENOENT;
                return -1;
@@ -440,7 +480,7 @@
        if (error) {
                pthread_mutex_destroy(&clispc.spc_mtx);
                pthread_cond_destroy(&clispc.spc_cv);
-               close(clispc.spc_fd);
+               host_close(clispc.spc_fd);
                errno = error;
                return -1;
        }
@@ -481,7 +521,7 @@
 {
        int error;
 
-       close(clispc.spc_fd);
+       host_close(clispc.spc_fd);
        memset(&clispc, 0, sizeof(clispc));
        clispc.spc_fd = -1;
 
diff -r 94318e2eba35 -r 6e9434d9bd58 lib/librumpuser/sp_common.c
--- a/lib/librumpuser/sp_common.c       Fri Jan 07 18:24:53 2011 +0000
+++ b/lib/librumpuser/sp_common.c       Fri Jan 07 19:37:51 2011 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: sp_common.c,v 1.19 2011/01/06 06:57:14 pooka Exp $    */
+/*      $NetBSD: sp_common.c,v 1.20 2011/01/07 19:37:52 pooka Exp $    */
 
 /*
  * Copyright (c) 2010, 2011 Antti Kantee.  All Rights Reserved.
@@ -71,6 +71,13 @@
 #define DPRINTF(x)
 #endif
 
+#ifndef HOSTOPS
+#define host_poll poll
+#define host_read read
+#define host_sendto sendto
+#define host_setsockopt setsockopt
+#endif
+
 /*
  * Bah, I hate writing on-off-wire conversions in C
  */
@@ -254,14 +261,15 @@
 
        for (sent = 0, n = 0; sent < dlen; ) {
                if (n) {
-                       if (poll(&pfd, 1, INFTIM) == -1) {
+                       if (host_poll(&pfd, 1, INFTIM) == -1) {
                                if (errno == EINTR)
                                        continue;
                                return errno;
                        }
                }
 
-               n = send(fd, sdata + sent, dlen - sent, MSG_NOSIGNAL);
+               n = host_sendto(fd, sdata + sent, dlen - sent,
+                   MSG_NOSIGNAL, NULL, 0);
                if (n == 0) {
                        return ENOTCONN;
                }
@@ -361,7 +369,7 @@
 
                left = HDRSZ - spc->spc_off;
                /*LINTED: cast ok */
-               n = read(fd, (uint8_t *)&spc->spc_hdr + spc->spc_off, left);
+               n = host_read(fd, (uint8_t*)&spc->spc_hdr + spc->spc_off, left);
                if (n == 0) {
                        return -1;
                }
@@ -403,7 +411,7 @@
 
        if (left == 0)
                return 1;
-       n = read(fd, spc->spc_buf + (spc->spc_off - HDRSZ), left);
+       n = host_read(fd, spc->spc_buf + (spc->spc_off - HDRSZ), left);
        if (n == 0) {
                return -1;
        }
@@ -508,7 +516,7 @@
        int x;
 
        x = 1;
-       setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &x, sizeof(x));
+       host_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &x, sizeof(x));
 
        return 0;
 }



Home | Main Index | Thread Index | Old Index