From 3fadbfb580aff36e6a6bda1cd766ec38b456dae4 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 4 Jun 2014 17:40:36 +0900 Subject: [PATCH] Do not let sockets be inherited by sub-processes Set FD_CLOEXEC flag on tunnel and UDP file descriptors. Fixes ticket #99, "should not allow UDP socket to be inherited by ifconfig" --- CHANGELOG | 1 + src/common.c | 18 ++++++++++++++++++ src/common.h | 2 ++ src/tun.c | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index ad85947..5f8287a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -23,6 +23,7 @@ master: - A number of minor patches from Frank Denis, Gregor Herrmann and Barak A. Pearlmutter. - Testcase compilation fixes for OS X and FreeBSD + - Do not let sockets be inherited by sub-processes, fixes #99. 2010-02-06: 0.6.0-rc1 "Hotspotify" - Fixed tunnel not working on Windows. diff --git a/src/common.c b/src/common.c index cfdcb56..6373a30 100644 --- a/src/common.c +++ b/src/common.c @@ -189,6 +189,8 @@ open_dns(struct sockaddr_storage *sockaddr, size_t sockaddr_len) #ifndef WINDOWS32 /* To get destination address from each UDP datagram, see iodined.c:read_dns() */ setsockopt(fd, IPPROTO_IP, DSTADDR_SOCKOPT, (const void*) &flag, sizeof(flag)); + + fd_set_close_on_exec(fd); #endif #ifdef IP_OPT_DONT_FRAG @@ -461,3 +463,19 @@ int recent_seqno(int ourseqno, int gotseqno) } return 0; } + +/* Set FD_CLOEXEC flag on file descriptor. + * This stops it from being inherited by system() calls. + */ +void +fd_set_close_on_exec(int fd) +{ + int flags; + + flags = fcntl(fd, F_GETFD); + if (flags == -1) + err(4, "Failed to get fd flags"); + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) + err(4, "Failed to set fd flags"); +} diff --git a/src/common.h b/src/common.h index 8df77f8..7b91942 100644 --- a/src/common.h +++ b/src/common.h @@ -136,4 +136,6 @@ void warnx(const char *fmt, ...); int recent_seqno(int , int); +void fd_set_close_on_exec(int fd); + #endif diff --git a/src/tun.c b/src/tun.c index db37974..0af1d81 100644 --- a/src/tun.c +++ b/src/tun.c @@ -98,6 +98,7 @@ open_tun(const char *tun_device) if (ioctl(tun_fd, TUNSETIFF, (void *) &ifreq) != -1) { fprintf(stderr, "Opened %s\n", ifreq.ifr_name); + fd_set_close_on_exec(tun_fd); return tun_fd; } @@ -112,6 +113,7 @@ open_tun(const char *tun_device) if (ioctl(tun_fd, TUNSETIFF, (void *) &ifreq) != -1) { fprintf(stderr, "Opened %s\n", ifreq.ifr_name); snprintf(if_name, sizeof(if_name), "dns%d", i); + fd_set_close_on_exec(tun_fd); return tun_fd; } @@ -147,6 +149,7 @@ open_tun(const char *tun_device) } fprintf(stderr, "Opened %s\n", tun_name); + fd_set_close_on_exec(tun_fd); return tun_fd; } else { for (i = 0; i < TUN_MAX_TRY; i++) { @@ -155,6 +158,7 @@ open_tun(const char *tun_device) if ((tun_fd = open(tun_name, O_RDWR)) >= 0) { fprintf(stderr, "Opened %s\n", tun_name); snprintf(if_name, sizeof(if_name), "tun%d", i); + fd_set_close_on_exec(tun_fd); return tun_fd; }