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.
This commit is contained in:
parent
0e137f7821
commit
91aad9bd60
|
@ -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 @@ __RCSID("$NetBSD");
|
|||
#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 @@ __RCSID("$NetBSD");
|
|||
|
||||
#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 @@ waitresp(struct spclient *spc, struct respwait *rw, sigset_t *mask)
|
|||
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 @@ doconnect(void)
|
|||
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 @@ doconnect(void)
|
|||
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 @@ doconnect(void)
|
|||
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 @@ rumpclient_init()
|
|||
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 @@ rumpclient_fork_init(struct rumpclient_fork *rpf)
|
|||
{
|
||||
int error;
|
||||
|
||||
close(clispc.spc_fd);
|
||||
host_close(clispc.spc_fd);
|
||||
memset(&clispc, 0, sizeof(clispc));
|
||||
clispc.spc_fd = -1;
|
||||
|
||||
|
|
|
@ -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 @@ mydprintf(const char *fmt, ...)
|
|||
#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 @@ dosend(struct spclient *spc, const void *data, size_t dlen)
|
|||
|
||||
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 @@ readframe(struct spclient *spc)
|
|||
|
||||
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 @@ readframe(struct spclient *spc)
|
|||
|
||||
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 @@ tcp_connecthook(int s)
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue