Intercept.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. /*
  2. * ZeroTier One - Network Virtualization Everywhere
  3. * Copyright (C) 2011-2015 ZeroTier, Inc.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * --
  19. *
  20. * ZeroTier may be used and distributed under the terms of the GPLv3, which
  21. * are available at: http://www.gnu.org/licenses/gpl-3.0.html
  22. *
  23. * If you would like to embed ZeroTier into a commercial application or
  24. * redistribute it in a modified binary form, please contact ZeroTier Networks
  25. * LLC. Start here: http://www.zerotier.com/
  26. */
  27. #ifdef USE_GNU_SOURCE
  28. #define _GNU_SOURCE
  29. #endif
  30. /* Name used in err msgs */
  31. char *progname = "";
  32. #include <unistd.h>
  33. #include <stdint.h>
  34. #include <pthread.h>
  35. #include <stdio.h>
  36. #include <dlfcn.h>
  37. #include <strings.h>
  38. #include <netinet/in.h>
  39. #include <sys/time.h>
  40. #include <pwd.h>
  41. #include <errno.h>
  42. #include <linux/errno.h>
  43. #include <stdarg.h>
  44. #include <netdb.h>
  45. #include <string.h>
  46. #include <stdlib.h>
  47. #include <sys/syscall.h>
  48. #include <sys/types.h>
  49. #include <sys/socket.h>
  50. #include <sys/poll.h>
  51. #include <sys/un.h>
  52. #include <arpa/inet.h>
  53. #include "Intercept.h"
  54. #include "Common.h"
  55. #ifdef CHECKS
  56. #include <sys/resource.h>
  57. #include <linux/net.h> /* for NPROTO */
  58. #define SOCK_MAX (SOCK_PACKET + 1)
  59. #define SOCK_TYPE_MASK 0xf
  60. #endif
  61. /* Global Declarations */
  62. #ifdef USE_SOCKS_DNS
  63. static int (*realresinit)(void);
  64. #endif
  65. static int (*realconnect)(CONNECT_SIG);
  66. static int (*realselect)(SELECT_SIG);
  67. static int (*realbind)(BIND_SIG);
  68. static int (*realaccept)(ACCEPT_SIG);
  69. static int (*reallisten)(LISTEN_SIG);
  70. static int (*realsocket)(SOCKET_SIG);
  71. static int (*realsetsockopt)(SETSOCKOPT_SIG);
  72. static int (*realgetsockopt)(GETSOCKOPT_SIG);
  73. static int (*realaccept4)(ACCEPT4_SIG);
  74. static long (*realsyscall)(SYSCALL_SIG);
  75. static int (*realclose)(CLOSE_SIG);
  76. //static int (*realclone)(CLONE_SIG);
  77. //static int (*realpoll)(POLL_SIG);
  78. static int (*realdup2)(DUP2_SIG);
  79. static int (*realdup3)(DUP3_SIG);
  80. /* Exported Function Prototypes */
  81. void my_init(void);
  82. int connect(CONNECT_SIG);
  83. int select(SELECT_SIG);
  84. int bind(BIND_SIG);
  85. int accept(ACCEPT_SIG);
  86. int listen(LISTEN_SIG);
  87. int socket(SOCKET_SIG);
  88. int setsockopt(SETSOCKOPT_SIG);
  89. int getsockopt(GETSOCKOPT_SIG);
  90. int accept4(ACCEPT4_SIG);
  91. long syscall(SYSCALL_SIG);
  92. int close(CLOSE_SIG);
  93. //int clone(CLONE_SIG);
  94. //int poll(POLL_SIG);
  95. int dup2(DUP2_SIG);
  96. int dup3(DUP3_SIG);
  97. #ifdef USE_SOCKS_DNS
  98. int res_init(void);
  99. #endif
  100. int connect_to_service(void);
  101. int init_service_connection();
  102. void dwr(const char *fmt, ...);
  103. void load_symbols(void);
  104. void set_up_intercept();
  105. int checkpid();
  106. #define SERVICE_CONNECT_ATTEMPTS 30
  107. #define RPC_FD 1023
  108. ssize_t sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd);
  109. /* threading */
  110. pthread_mutex_t lock;
  111. pthread_mutex_t loglock;
  112. void handle_error(char *name, char *info, int err)
  113. {
  114. #ifdef ERRORS_ARE_FATAL
  115. if(err < 0) {
  116. dwr("handle_error(%s)=%d: FATAL: %s\n", name, err, info);
  117. //exit(-1);
  118. }
  119. #endif
  120. #ifdef VERBOSE
  121. dwr("%s()=%d\n", name, err);
  122. #endif
  123. }
  124. static unsigned long rpc_count = 0;
  125. /*------------------------------------------------------------------------------
  126. ------------------- Intercept<--->Service Comm mechanisms-----------------------
  127. ------------------------------------------------------------------------------*/
  128. static int is_initialized = 0;
  129. static int fdret_sock; // used for fd-transfers
  130. static int newfd; // used for "this_end" socket
  131. static int thispid;
  132. static char* af_sock_name = "/tmp/.ztnc_e5cd7a9e1c5311ab";
  133. /*
  134. * Check for forking
  135. */
  136. int checkpid() {
  137. if(thispid != getpid()) {
  138. printf("clone/fork detected. re-initializing this instance.\n");
  139. set_up_intercept();
  140. fdret_sock = init_service_connection();
  141. thispid = getpid();
  142. }
  143. return 0;
  144. }
  145. /*
  146. * Sends an RPC command to the service
  147. */
  148. int send_command(int rpc_fd, char *cmd)
  149. {
  150. #ifdef DEBUG
  151. /*
  152. dwr(" - IDX_PID = %d\n", IDX_PID);
  153. dwr(" - IDX_TID = %d\n", IDX_TID);
  154. dwr(" - IDX_COUNT = %d\n", IDX_COUNT);
  155. dwr(" - IDX_TIME = %d\n", IDX_TIME);
  156. dwr(" - IDX_PAYLOAD = %d\n", IDX_PAYLOAD);
  157. */
  158. /*
  159. #define IDX_PID 0
  160. #define IDX_TID sizeof(pid_t)
  161. #define IDX_COUNT IDX_TID + sizeof(pid_t)
  162. #define IDX_TIME IDX_COUNT + sizeof(int)
  163. #define IDX_CMD IDX_TIME + 20 // 20 being the length of the timestamp string
  164. #define IDX_PAYLOAD IDX_TIME + sizeof(char)
  165. */
  166. // [pid_t] [pid_t] [rpc_count] [int] [...]
  167. char metabuf[BUF_SZ]; // portion of buffer which contains RPC meta-data for debugging
  168. memset(metabuf, '\0', BUF_SZ);
  169. pid_t pid = syscall(SYS_getpid);
  170. pid_t tid = syscall(SYS_gettid);
  171. int payload_idx = sizeof(pid_t)*2 + sizeof(rpc_count);
  172. rpc_count++;
  173. char timestring[20];
  174. time_t timestamp;
  175. timestamp = time(NULL);
  176. strftime(timestring, sizeof(timestring), "%H:%M:%S", localtime(&timestamp));
  177. memcpy(&metabuf[IDX_PID], &pid, sizeof(pid_t) ); // pid
  178. memcpy(&metabuf[IDX_TID], &tid, sizeof(pid_t) ); // tid
  179. memcpy(&metabuf[IDX_COUNT], &rpc_count, sizeof(rpc_count) ); // rpc_count
  180. memcpy(&metabuf[IDX_TIME], &timestring, 20 ); // timestamp
  181. #endif
  182. // copy payload into final command buffer
  183. int copied = BUF_SZ-IDX_PAYLOAD;
  184. memcpy(&metabuf[IDX_PAYLOAD], cmd, 200);
  185. //dwr(" RX: (pid=%d, tid=%d, rpc_count=%d, timestamp=%s, cmd=%d\n", pid, tid, rpc_count, timestring, cmd[0]);
  186. int n_write = write(rpc_fd, &metabuf, BUF_SZ);
  187. if(n_write < 0){
  188. dwr("Error writing command to service (CMD = %d)\n", cmd[0]);
  189. errno = 0;
  190. return -1;
  191. }
  192. return 0;
  193. }
  194. /*
  195. * Reads a return value from the service and sets errno (if applicable)
  196. */
  197. int get_retval()
  198. {
  199. dwr("get_retval()\n");
  200. if(fdret_sock >= 0) {
  201. int retval;
  202. int sz = sizeof(char) + sizeof(retval) + sizeof(errno);
  203. char retbuf[BUF_SZ];
  204. memset(&retbuf, '\0', sz);
  205. int n_read = read(fdret_sock, &retbuf, sz);
  206. if(n_read > 0) {
  207. memcpy(&retval, &retbuf[1], sizeof(retval));
  208. memcpy(&errno, &retbuf[1+sizeof(retval)], sizeof(errno));
  209. return retval;
  210. }
  211. }
  212. dwr("unable to read return value\n");
  213. return -1;
  214. }
  215. /* Check whether the socket is mapped to the service or not. We
  216. need to know if this is a regular AF_LOCAL socket or an end of a socketpair
  217. that the service uses. We don't want to keep state in the intercept, so
  218. we simply ask the service via an RPC */
  219. int is_mapped_to_service(int sockfd)
  220. {
  221. dwr("is_mapped_to_service()\n");
  222. char cmd[BUF_SZ];
  223. memset(cmd, '\0', BUF_SZ);
  224. cmd[0] = RPC_MAP_REQ;
  225. memcpy(&cmd[1], &sockfd, sizeof(sockfd));
  226. pthread_mutex_lock(&lock);
  227. if(send_command(fdret_sock, cmd) < 0)
  228. return -1;
  229. int err = get_retval();
  230. pthread_mutex_unlock(&lock);
  231. return err;
  232. }
  233. /*------------------------------------------------------------------------------
  234. ---------- Unix-domain socket lazy initializer (for fd-transfers)--------------
  235. ------------------------------------------------------------------------------*/
  236. /* Sets up the connection pipes and sockets to the service */
  237. int init_service_connection()
  238. {
  239. dwr("init_service_connection()\n");
  240. if(!is_initialized) {
  241. struct sockaddr_un addr;
  242. int tfd = -1, attempts = 0, conn_err = -1;
  243. memset(&addr, 0, sizeof(addr));
  244. addr.sun_family = AF_UNIX;
  245. strncpy(addr.sun_path, af_sock_name, sizeof(addr.sun_path)-1);
  246. if ( (tfd = realsocket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
  247. perror("socket error");
  248. exit(-1);
  249. }
  250. while(conn_err < 0 && attempts < SERVICE_CONNECT_ATTEMPTS) {
  251. conn_err = realconnect(tfd, (struct sockaddr*)&addr, sizeof(addr));
  252. if(conn_err < 0) {
  253. dwr("re-attempting connection in %ds\n", 1+attempts);
  254. sleep(1);
  255. }
  256. else {
  257. dwr("AF_UNIX connection established: %d\n", tfd);
  258. is_initialized = 1;
  259. int newtfd = realdup2(tfd, 1023);
  260. dwr("dup'd to rpc_fd = %d\n", newtfd);
  261. close(tfd);
  262. return newtfd;
  263. }
  264. attempts++;
  265. }
  266. }
  267. return -1;
  268. }
  269. /*------------------------------------------------------------------------------
  270. ------------------------ ctors and dtors (and friends)-------------------------
  271. ------------------------------------------------------------------------------*/
  272. void my_dest(void) __attribute__ ((destructor));
  273. void my_dest(void) {
  274. //dwr("closing connections to service...\n");
  275. close(fdret_sock);
  276. pthread_mutex_destroy(&lock);
  277. }
  278. void load_symbols(void)
  279. {
  280. #ifdef USE_OLD_DLSYM
  281. void *lib;
  282. #endif
  283. /* possibly add check to beginning of each method to avoid needing to cll the constructor */
  284. if(thispid == getpid()) {
  285. dwr("detected duplicate call to global ctor (pid=%d).\n", thispid);
  286. }
  287. //dwr(" -- pid = %d\n", getpid());
  288. //dwr(" -- uid = %d\n", getuid());
  289. thispid = getpid();
  290. #ifndef USE_OLD_DLSYM
  291. realconnect = dlsym(RTLD_NEXT, "connect");
  292. realbind = dlsym(RTLD_NEXT, "bind");
  293. realaccept = dlsym(RTLD_NEXT, "accept");
  294. reallisten = dlsym(RTLD_NEXT, "listen");
  295. realsocket = dlsym(RTLD_NEXT, "socket");
  296. realbind = dlsym(RTLD_NEXT, "bind");
  297. realselect = dlsym(RTLD_NEXT, "select");
  298. realsetsockopt = dlsym(RTLD_NEXT, "setsockopt");
  299. realgetsockopt = dlsym(RTLD_NEXT, "getsockopt");
  300. realaccept4 = dlsym(RTLD_NEXT, "accept4");
  301. //realclone = dlsym(RTLD_NEXT, "clone");
  302. realclose = dlsym(RTLD_NEXT, "close");
  303. realsyscall = dlsym(RTLD_NEXT, "syscall");
  304. //realsyscall = dlsym(RTLD_NEXT, "poll");
  305. realdup2 = dlsym(RTLD_NEXT, "dup2");
  306. realdup3 = dlsym(RTLD_NEXT, "dup3");
  307. #ifdef USE_SOCKS_DNS
  308. realresinit = dlsym(RTLD_NEXT, "res_init");
  309. #endif
  310. #else
  311. lib = dlopen(LIBCONNECT, RTLD_LAZY);
  312. realconnect = dlsym(lib, "connect");
  313. realbind = dlsym(lib, "bind");
  314. realaccept = dlsym(lib, "accept");
  315. reallisten = dlsym(lib, "listen");
  316. realsocket = dlsym(lib, "socket");
  317. realselect = dlsym(lib, "select");
  318. realsetsockopt = dlsym(lib, "setsockopt");
  319. realgetsockopt = dlsym(lib, "getsockopt");
  320. realaccept4 = dlsym(lib), "accept4");
  321. //realclone = dlsym(lib, "clone");
  322. realclose = dlsym(lib, "close");
  323. realsyscall = dlsym(lib, "syscall");
  324. //realsyscall = dlsym(lib, "poll");
  325. realdup2 = dlsym(RTLD_NEXT, "dup2");
  326. realdup3 = dlsym(RTLD_NEXT, "dup3");
  327. #ifdef USE_SOCKS_DNS
  328. realresinit = dlsym(lib, "res_init");
  329. #endif
  330. dlclose(lib);
  331. lib = dlopen(LIBC, RTLD_LAZY);
  332. dlclose(lib);
  333. #endif
  334. }
  335. /* Private Function Prototypes */
  336. void _init(void) __attribute__ ((constructor));
  337. void _init(void) {
  338. set_up_intercept();
  339. }
  340. /* get symbols and initialize mutexes */
  341. void set_up_intercept()
  342. {
  343. load_symbols();
  344. if(pthread_mutex_init(&lock, NULL) != 0) {
  345. printf("error while initializing service call mutex\n");
  346. }
  347. if(pthread_mutex_init(&loglock, NULL) != 0) {
  348. printf("error while initializing log mutex mutex\n");
  349. }
  350. }
  351. /*------------------------------------------------------------------------------
  352. --------------------------------- setsockopt() ---------------------------------
  353. ------------------------------------------------------------------------------*/
  354. /* int socket, int level, int option_name, const void *option_value, socklen_t option_len */
  355. int setsockopt(SETSOCKOPT_SIG)
  356. {
  357. dwr("\n\nsetsockopt(%d)\n", socket);
  358. /*
  359. if(is_mapped_to_service(socket) < 0) { // First, check if the service manages this
  360. return realsetsockopt(socket, level, option_name, option_value, option_len);
  361. }
  362. */
  363. //return(realsetsockopt(socket, level, option_name, option_value, option_len));
  364. if(level == SOL_IPV6 && option_name == IPV6_V6ONLY)
  365. return 0;
  366. if(level == SOL_IP && option_name == IP_TTL)
  367. return 0;
  368. if(level == IPPROTO_TCP || (level == SOL_SOCKET && option_name == SO_KEEPALIVE))
  369. return 0;
  370. /* make sure we don't touch any standard outputs */
  371. if(socket == STDIN_FILENO || socket == STDOUT_FILENO || socket == STDERR_FILENO)
  372. return(realsetsockopt(socket, level, option_name, option_value, option_len));
  373. int err = realsetsockopt(socket, level, option_name, option_value, option_len);
  374. if(err < 0){
  375. //perror("setsockopt():\n");
  376. }
  377. return 0;
  378. }
  379. /*------------------------------------------------------------------------------
  380. --------------------------------- getsockopt() ---------------------------------
  381. ------------------------------------------------------------------------------*/
  382. /* int sockfd, int level, int optname, void *optval, socklen_t *optlen */
  383. int getsockopt(GETSOCKOPT_SIG)
  384. {
  385. dwr("\n\ngetsockopt(%d)\n", sockfd);
  386. /*
  387. if(is_mapped_to_service(sockfd) < 0) { // First, check if the service manages this
  388. return realgetsockopt(sockfd, level, optname, optval, optlen);
  389. }
  390. */
  391. int err = realgetsockopt(sockfd, level, optname, optval, optlen);
  392. // FIXME: this condition will need a little more intelligence later on
  393. // -- we will need to know if this fd is a local we are spoofing, or a true local
  394. if(optname == SO_TYPE)
  395. {
  396. int* val = (int*)optval;
  397. *val = 2;
  398. optval = (void*)val;
  399. }
  400. if(err < 0){
  401. //perror("setsockopt():\n");
  402. }
  403. return 0;
  404. }
  405. /*------------------------------------------------------------------------------
  406. ----------------------------------- socket() -----------------------------------
  407. ------------------------------------------------------------------------------*/
  408. /* int socket_family, int socket_type, int protocol
  409. socket() intercept function */
  410. int socket(SOCKET_SIG)
  411. {
  412. dwr("\n\nsocket()*:\n");
  413. int err;
  414. #ifdef CHECKS
  415. /* Check that type makes sense */
  416. int flags = socket_type & ~SOCK_TYPE_MASK;
  417. if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
  418. errno = EINVAL;
  419. handle_error("socket1", "", -1);
  420. return -1;
  421. }
  422. socket_type &= SOCK_TYPE_MASK;
  423. /* Check protocol is in range */
  424. if (socket_family < 0 || socket_family >= NPROTO){
  425. errno = EAFNOSUPPORT;
  426. handle_error("socket2", "", -1);
  427. return -1;
  428. }
  429. if (socket_type < 0 || socket_type >= SOCK_MAX) {
  430. errno = EINVAL;
  431. handle_error("socket3", "", -1);
  432. return -1;
  433. }
  434. /* Check that we haven't hit the soft-limit file descriptors allowed */
  435. /* FIXME: Find number of open fds
  436. struct rlimit rl;
  437. getrlimit(RLIMIT_NOFILE, &rl);
  438. if(sockfd >= rl.rlim_cur){
  439. errno = EMFILE;
  440. return -1;
  441. }
  442. */
  443. /* FIXME: detect ENFILE condition */
  444. #endif
  445. char cmd[BUF_SZ];
  446. fdret_sock = !is_initialized ? init_service_connection() : fdret_sock;
  447. if(fdret_sock < 0) {
  448. dwr("BAD service connection. exiting.\n");
  449. handle_error("socket4", "", -1);
  450. exit(-1);
  451. }
  452. if(socket_family == AF_LOCAL
  453. || socket_family == AF_NETLINK
  454. || socket_family == AF_UNIX) {
  455. int err = realsocket(socket_family, socket_type, protocol);
  456. dwr("realsocket, err = %d\n", err);
  457. handle_error("socket5", "", err);
  458. return err;
  459. }
  460. /* Assemble and send RPC */
  461. struct socket_st rpc_st;
  462. rpc_st.socket_family = socket_family;
  463. rpc_st.socket_type = socket_type;
  464. rpc_st.protocol = protocol;
  465. rpc_st.__tid = syscall(SYS_gettid);
  466. memset(cmd, '\0', BUF_SZ);
  467. cmd[0] = RPC_SOCKET;
  468. dwr("pid = %d\n", thispid);
  469. memcpy(&cmd[1]+sizeof(pid_t), &rpc_st, sizeof(struct socket_st));
  470. pthread_mutex_lock(&lock);
  471. send_command(fdret_sock, cmd);
  472. /* get new fd */
  473. char rbuf[16];
  474. ssize_t sz = sock_fd_read(fdret_sock, rbuf, sizeof(rbuf), &newfd);
  475. int tmp = newfd;
  476. dwr("read %d bytes (%s)\n", sz, &rbuf);
  477. if(sz > 0)
  478. {
  479. dwr("sending fd = %d to Service over (%d)\n", newfd, fdret_sock);
  480. /* send our local-fd number back to service so
  481. it can complete its mapping table entry */
  482. memset(cmd, '\0', BUF_SZ);
  483. cmd[0] = RPC_MAP;
  484. memcpy(&cmd[1], &newfd, sizeof(newfd));
  485. if(newfd > -1) { // FIXME: check logic
  486. send_command(fdret_sock, cmd);
  487. pthread_mutex_unlock(&lock);
  488. errno = ERR_OK; // OK
  489. handle_error("socket6", "", newfd);
  490. return newfd;
  491. }
  492. else { // Try to read retval+errno since we RXed a bad fd
  493. dwr("Error, service sent bad fd.\n");
  494. err = get_retval();
  495. pthread_mutex_unlock(&lock);
  496. handle_error("socket7", "", -1);
  497. return err;
  498. }
  499. }
  500. else {
  501. dwr("Error while receiving new FD.\n");
  502. err = get_retval();
  503. pthread_mutex_unlock(&lock);
  504. handle_error("socket8", "", -1);
  505. return err;
  506. }
  507. }
  508. /*------------------------------------------------------------------------------
  509. ---------------------------------- connect() -----------------------------------
  510. ------------------------------------------------------------------------------*/
  511. /* int __fd, const struct sockaddr * __addr, socklen_t __len
  512. connect() intercept function */
  513. int connect(CONNECT_SIG)
  514. {
  515. dwr("\n\nconnect(%d):\n", __fd);
  516. print_addr(__addr);
  517. struct sockaddr_in *connaddr;
  518. connaddr = (struct sockaddr_in *) __addr;
  519. #ifdef CHECKS
  520. /* Check that this is a valid fd */
  521. if(fcntl(__fd, F_GETFD) < 0) {
  522. errno = EBADF;
  523. handle_error("connect", "EBADF", -1);
  524. return -1;
  525. }
  526. /* Check that it is a socket */
  527. int sock_type;
  528. socklen_t sock_type_len = sizeof(sock_type);
  529. if(getsockopt(__fd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) {
  530. errno = ENOTSOCK;
  531. handle_error("connect", "ENOTSOCK", -1);
  532. return -1;
  533. }
  534. /* Check family */
  535. if (connaddr->sin_family < 0 || connaddr->sin_family >= NPROTO){
  536. errno = EAFNOSUPPORT;
  537. handle_error("connect", "EAFNOSUPPORT", -1);
  538. return -1;
  539. }
  540. /* FIXME: Check that address is in user space, return EFAULT ? */
  541. #endif
  542. /* make sure we don't touch any standard outputs */
  543. if(__fd == STDIN_FILENO || __fd == STDOUT_FILENO || __fd == STDERR_FILENO){
  544. if (realconnect == NULL) {
  545. handle_error("connect", "Unresolved symbol [connect]", -1);
  546. exit(-1);
  547. }
  548. return(realconnect(__fd, __addr, __len));
  549. }
  550. if(__addr != NULL && (connaddr->sin_family == AF_LOCAL
  551. || connaddr->sin_family == PF_NETLINK
  552. || connaddr->sin_family == AF_NETLINK
  553. || connaddr->sin_family == AF_UNIX)) {
  554. int err = realconnect(__fd, __addr, __len);
  555. perror("connect():");
  556. //handle_error("connect", "Cannot connect to local socket", err);
  557. return err;
  558. }
  559. /* Assemble and send RPC */
  560. int err;
  561. char cmd[BUF_SZ];
  562. memset(cmd, '\0', BUF_SZ);
  563. struct connect_st rpc_st;
  564. rpc_st.__tid = syscall(SYS_gettid);
  565. rpc_st.__fd = __fd;
  566. memcpy(&rpc_st.__addr, __addr, sizeof(struct sockaddr));
  567. memcpy(&rpc_st.__len, &__len, sizeof(socklen_t));
  568. cmd[0] = RPC_CONNECT;
  569. memcpy(&cmd[1], &rpc_st, sizeof(struct connect_st));
  570. pthread_mutex_lock(&lock);
  571. send_command(fdret_sock, cmd);
  572. /*
  573. if(sock_type && O_NONBLOCK) {
  574. //pthread_mutex_unlock(&lock);
  575. //return EINPROGRESS;
  576. }
  577. */
  578. err = get_retval();
  579. pthread_mutex_unlock(&lock);
  580. //handle_error("connect", "", err);
  581. return err;
  582. }
  583. /*------------------------------------------------------------------------------
  584. ---------------------------------- select() ------------------------------------
  585. ------------------------------------------------------------------------------*/
  586. /* int n, fd_set *readfds, fd_set *writefds,
  587. fd_set *exceptfds, struct timeval *timeout */
  588. int select(SELECT_SIG)
  589. {
  590. //dwr("select():\n");
  591. return realselect(n, readfds, writefds, exceptfds, timeout);
  592. }
  593. /*------------------------------------------------------------------------------
  594. ------------------------------------ bind() ------------------------------------
  595. ------------------------------------------------------------------------------*/
  596. /* int sockfd, const struct sockaddr *addr, socklen_t addrlen
  597. bind() intercept function */
  598. int bind(BIND_SIG)
  599. {
  600. dwr("\n\nbind(%d):\n", sockfd);
  601. print_addr(addr);
  602. #ifdef CHECKS
  603. /* Check that this is a valid fd */
  604. if(fcntl(sockfd, F_GETFD) < 0) {
  605. errno = EBADF;
  606. handle_error("bind", "EBADF", -1);
  607. return -1;
  608. }
  609. /* Check that it is a socket */
  610. int opt = -1;
  611. socklen_t opt_len;
  612. if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &opt, &opt_len) < 0) {
  613. errno = ENOTSOCK;
  614. handle_error("bind", "ENOTSOCK", -1);
  615. return -1;
  616. }
  617. #endif
  618. int err;
  619. /* make sure we don't touch any standard outputs */
  620. if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO)
  621. return(realbind(sockfd, addr, addrlen));
  622. /* If local, just use normal syscall */
  623. struct sockaddr_in *connaddr;
  624. connaddr = (struct sockaddr_in *)addr;
  625. if(connaddr->sin_family == AF_LOCAL
  626. || connaddr->sin_family == AF_NETLINK
  627. || connaddr->sin_family == AF_UNIX) {
  628. int err = realbind(sockfd, addr, addrlen);
  629. dwr("realbind, err = %d\n", err);
  630. return err;
  631. }
  632. /* Assemble and send RPC */
  633. char cmd[BUF_SZ];
  634. struct bind_st rpc_st;
  635. rpc_st.sockfd = sockfd;
  636. rpc_st.__tid = syscall(SYS_gettid);
  637. memcpy(&rpc_st.addr, addr, sizeof(struct sockaddr));
  638. memcpy(&rpc_st.addrlen, &addrlen, sizeof(socklen_t));
  639. cmd[0]=RPC_BIND;
  640. memcpy(&cmd[1], &rpc_st, sizeof(struct bind_st));
  641. pthread_mutex_lock(&lock);
  642. send_command(fdret_sock, cmd);
  643. err = get_retval();
  644. pthread_mutex_unlock(&lock);
  645. errno = ERR_OK;
  646. handle_error("bind", "", err);
  647. return err;
  648. }
  649. /*------------------------------------------------------------------------------
  650. ----------------------------------- accept4() ----------------------------------
  651. ------------------------------------------------------------------------------*/
  652. /* int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags */
  653. int accept4(ACCEPT4_SIG)
  654. {
  655. dwr("\n\naccept4(%d):\n", sockfd);
  656. #ifdef CHECKS
  657. if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) {
  658. errno = EINVAL;
  659. return -1;
  660. }
  661. #endif
  662. int newfd = accept(sockfd, addr, addrlen);
  663. if(newfd > 0) {
  664. if(flags & SOCK_CLOEXEC)
  665. fcntl(newfd, F_SETFL, FD_CLOEXEC);
  666. if(flags & SOCK_NONBLOCK)
  667. fcntl(newfd, F_SETFL, O_NONBLOCK);
  668. }
  669. handle_error("accept4", "", newfd);
  670. return newfd;
  671. }
  672. /*------------------------------------------------------------------------------
  673. ----------------------------------- accept() -----------------------------------
  674. ------------------------------------------------------------------------------*/
  675. /* int sockfd struct sockaddr *addr, socklen_t *addrlen
  676. accept() intercept function */
  677. int accept(ACCEPT_SIG)
  678. {
  679. dwr("\n\naccept(%d):\n", sockfd);
  680. #ifdef CHECKS
  681. /* Check that this is a valid fd */
  682. if(fcntl(sockfd, F_GETFD) < 0) {
  683. return -1;
  684. errno = EBADF;
  685. dwr("EBADF\n");
  686. handle_error("accept", "EBADF", -1);
  687. return -1;
  688. }
  689. /* Check that it is a socket */
  690. int opt;
  691. socklen_t opt_len;
  692. if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &opt, &opt_len) < 0) {
  693. errno = ENOTSOCK;
  694. dwr("ENOTSOCK\n");
  695. handle_error("accept", "ENOTSOCK", -1);
  696. return -1;
  697. }
  698. /* Check that this socket supports accept() */
  699. if(!(opt && (SOCK_STREAM | SOCK_SEQPACKET))) {
  700. errno = EOPNOTSUPP;
  701. dwr("EOPNOTSUPP\n");
  702. handle_error("accept", "EOPNOTSUPP", -1);
  703. return -1;
  704. }
  705. /* Check that we haven't hit the soft-limit file descriptors allowed */
  706. struct rlimit rl;
  707. getrlimit(RLIMIT_NOFILE, &rl);
  708. if(sockfd >= rl.rlim_cur){
  709. errno = EMFILE;
  710. dwr("EMFILE\n");
  711. handle_error("accept", "EMFILE", -1);
  712. return -1;
  713. }
  714. /* Check address length */
  715. if(addrlen < 0) {
  716. errno = EINVAL;
  717. dwr("EINVAL\n");
  718. handle_error("accept", "EINVAL", -1);
  719. return -1;
  720. }
  721. #endif
  722. /* redirect calls for standard I/O descriptors to kernel */
  723. if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO){
  724. dwr("realaccept():\n");
  725. return(realaccept(sockfd, addr, addrlen));
  726. }
  727. if(addr)
  728. addr->sa_family = AF_INET;
  729. /* TODO: also get address info */
  730. char cmd[BUF_SZ];
  731. if(realaccept == NULL) {
  732. handle_error("accept", "Unresolved symbol [accept]", -1);
  733. return -1;
  734. }
  735. //if(opt & O_NONBLOCK)
  736. //fcntl(sockfd, F_SETFL, O_NONBLOCK);
  737. char rbuf[16], c[1];
  738. int new_conn_socket;
  739. int n = read(sockfd, c, sizeof(c)); // Read signal byte
  740. if(n > 0)
  741. {
  742. ssize_t size = sock_fd_read(fdret_sock, rbuf, sizeof(rbuf), &new_conn_socket);
  743. if(size > 0) {
  744. /* Send our local-fd number back to service so it can complete its mapping table */
  745. memset(cmd, '\0', BUF_SZ);
  746. cmd[0] = RPC_MAP;
  747. memcpy(&cmd[1], &new_conn_socket, sizeof(new_conn_socket));
  748. pthread_mutex_lock(&lock);
  749. int n_write = write(fdret_sock, cmd, BUF_SZ);
  750. if(n_write < 0) {
  751. errno = ECONNABORTED; // FIXME: Closest match, service unreachable
  752. handle_error("accept", "ECONNABORTED - Error sending perceived FD to service", -1);
  753. return -1;
  754. }
  755. pthread_mutex_unlock(&lock);
  756. errno = ERR_OK;
  757. dwr("*accept()=%d\n", new_conn_socket);
  758. handle_error("accept", "", new_conn_socket);
  759. return new_conn_socket; // OK
  760. }
  761. else {
  762. errno = ECONNABORTED; // FIXME: Closest match, service unreachable
  763. handle_error("accept", "ECONNABORTED - Error receiving new FD from service", -1);
  764. return -1;
  765. }
  766. }
  767. errno = EBADF;
  768. handle_error("accept", "EBADF - Error reading signal byte from service", -1);
  769. return -1;
  770. }
  771. /*------------------------------------------------------------------------------
  772. ------------------------------------- listen()----------------------------------
  773. ------------------------------------------------------------------------------*/
  774. /* int sockfd, int backlog
  775. listen() intercept function */
  776. int listen(LISTEN_SIG)
  777. {
  778. dwr("\n\nlisten(%d):\n", sockfd);
  779. int sock_type;
  780. socklen_t sock_type_len = sizeof(sock_type);
  781. #ifdef CHECKS
  782. /* Check that this is a valid fd */
  783. if(fcntl(sockfd, F_GETFD) < 0) {
  784. errno = EBADF;
  785. handle_error("listen", "EBADF", -1);
  786. return -1;
  787. }
  788. /* Check that it is a socket */
  789. if(getsockopt(sockfd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) {
  790. errno = ENOTSOCK;
  791. handle_error("listen", "ENOTSOCK", -1);
  792. return -1;
  793. }
  794. /* Check that this socket supports accept() */
  795. if(!(sock_type && (SOCK_STREAM | SOCK_SEQPACKET))) {
  796. errno = EOPNOTSUPP;
  797. handle_error("listen", "EOPNOTSUPP", -1);
  798. return -1;
  799. }
  800. #endif
  801. /* make sure we don't touch any standard outputs */
  802. if(sockfd == STDIN_FILENO || sockfd == STDOUT_FILENO || sockfd == STDERR_FILENO)
  803. return(reallisten(sockfd, backlog));
  804. if(is_mapped_to_service(sockfd) < 0) {
  805. // We now know this socket is not one of our socketpairs
  806. int err = reallisten(sockfd, backlog);
  807. dwr("reallisten()=%d\n", err);
  808. return err;
  809. }
  810. /* Assemble and send RPC */
  811. char cmd[BUF_SZ];
  812. memset(cmd, '\0', BUF_SZ);
  813. struct listen_st rpc_st;
  814. rpc_st.sockfd = sockfd;
  815. rpc_st.backlog = backlog;
  816. rpc_st.__tid = syscall(SYS_gettid);
  817. cmd[0] = RPC_LISTEN;
  818. memcpy(&cmd[1], &rpc_st, sizeof(struct listen_st));
  819. pthread_mutex_lock(&lock);
  820. send_command(fdret_sock, cmd);
  821. int err = get_retval();
  822. pthread_mutex_unlock(&lock);
  823. handle_error("listen", "", ERR_OK);
  824. return ERR_OK;
  825. }
  826. /*------------------------------------------------------------------------------
  827. -------------------------------------- clone()----------------------------------
  828. ------------------------------------------------------------------------------*/
  829. // int (*fn)(void *), void *child_stack, int flags, void *arg, ...
  830. /*
  831. int clone(CLONE_SIG)
  832. {
  833. dwr("clone()\n");
  834. return realclone(fn, child_stack, flags, arg);
  835. }
  836. */
  837. /*------------------------------------------------------------------------------
  838. -------------------------------------- poll()-----------------------------------
  839. ------------------------------------------------------------------------------*/
  840. // struct pollfd *fds, nfds_t nfds, int timeout
  841. /*
  842. int poll(POLL_SIG)
  843. {
  844. dwr("poll()\n");
  845. return realpoll(fds, nfds, timeout);
  846. //return ERESTART_RESTARTBLOCK;
  847. }
  848. */
  849. /*------------------------------------------------------------------------------
  850. -------------------------------------- close()-----------------------------------
  851. ------------------------------------------------------------------------------*/
  852. // int fd
  853. int close(CLOSE_SIG)
  854. {
  855. dwr("close(%d)\n", fd);
  856. if(fd == fdret_sock)
  857. return 0; // FIXME: Ignore request to shut down our rpc fd, this is *almost always* safe
  858. if(fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO){
  859. return realclose(fd);
  860. }
  861. }
  862. /*------------------------------------------------------------------------------
  863. -------------------------------------- dup2()-----------------------------------
  864. ------------------------------------------------------------------------------*/
  865. // int oldfd, int newfd
  866. int dup2(DUP2_SIG)
  867. {
  868. dwr("dup2(%d, %d)\n", oldfd, newfd);
  869. if(oldfd == fdret_sock) {
  870. dwr("client application attempted to dup2 RPC socket (%d). This is not allowed.\n", oldfd);
  871. errno = EBADF;
  872. return -1;
  873. }
  874. if(oldfd != STDIN_FILENO && oldfd != STDOUT_FILENO && oldfd != STDERR_FILENO) {
  875. return realdup2(oldfd, newfd);
  876. }
  877. }
  878. /*------------------------------------------------------------------------------
  879. -------------------------------------- dup3()-----------------------------------
  880. ------------------------------------------------------------------------------*/
  881. // int oldfd, int newfd, int flags
  882. int dup3(DUP3_SIG)
  883. {
  884. dwr("dup3(%d, %d, %d)\n", oldfd, newfd, flags);
  885. #ifdef DEBUG
  886. // Only do this check if we want to debug the intercept, otherwise, dont mess with
  887. // the client application's logging methods
  888. if(newfd == STDIN_FILENO || newfd == STDOUT_FILENO || newfd == STDERR_FILENO)
  889. return newfd; // FIXME: This is to prevent httpd from dup'ing over our stderr
  890. //and preventing us from debugging
  891. else
  892. #endif
  893. return realdup3(oldfd, newfd, flags);
  894. }
  895. /*------------------------------------------------------------------------------
  896. ------------------------------------ syscall()----------------------------------
  897. ------------------------------------------------------------------------------*/
  898. long syscall(SYSCALL_SIG)
  899. {
  900. dwr("syscall(%u, ...):\n", number);
  901. va_list ap;
  902. uintptr_t a,b,c,d,e,f;
  903. va_start(ap, number);
  904. a=va_arg(ap, uintptr_t);
  905. b=va_arg(ap, uintptr_t);
  906. c=va_arg(ap, uintptr_t);
  907. d=va_arg(ap, uintptr_t);
  908. e=va_arg(ap, uintptr_t);
  909. f=va_arg(ap, uintptr_t);
  910. va_end(ap);
  911. #if defined(__i386__)
  912. /* TODO: Implement for 32-bit systems: syscall(__NR_socketcall, 18, args);
  913. args[0] = (unsigned long) fd;
  914. args[1] = (unsigned long) addr;
  915. args[2] = (unsigned long) addrlen;
  916. args[3] = (unsigned long) flags;
  917. */
  918. #else
  919. if(number == __NR_accept4) {
  920. int sockfd = a;
  921. struct sockaddr * addr = (struct sockaddr*)b;
  922. socklen_t * addrlen = (socklen_t*)c;
  923. int flags = d;
  924. int old_errno = errno;
  925. int err = accept4(sockfd, addr, addrlen, flags);
  926. errno = old_errno;
  927. if(err == -EBADF) {
  928. //errno = EAGAIN;
  929. err = -EAGAIN;
  930. //exit(0);
  931. }
  932. return err;
  933. }
  934. #endif
  935. return realsyscall(number,a,b,c,d,e,f);
  936. }