Module Name:    src
Committed By:   pooka
Date:           Fri Jan  7 19:37:52 UTC 2011

Modified Files:
        src/lib/librumpclient: rumpclient.c
        src/lib/librumpuser: sp_common.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/lib/librumpclient/rumpclient.c
cvs rdiff -u -r1.19 -r1.20 src/lib/librumpuser/sp_common.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/librumpclient/rumpclient.c
diff -u src/lib/librumpclient/rumpclient.c:1.12 src/lib/librumpclient/rumpclient.c:1.13
--- src/lib/librumpclient/rumpclient.c:1.12	Thu Jan  6 06:57:14 2011
+++ src/lib/librumpclient/rumpclient.c	Fri Jan  7 19:37:51 2011
@@ -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;
 

Index: src/lib/librumpuser/sp_common.c
diff -u src/lib/librumpuser/sp_common.c:1.19 src/lib/librumpuser/sp_common.c:1.20
--- src/lib/librumpuser/sp_common.c:1.19	Thu Jan  6 06:57:14 2011
+++ src/lib/librumpuser/sp_common.c	Fri Jan  7 19:37:52 2011
@@ -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;
 }

Reply via email to