Set FD_CLOEXEC flag on all sockets.
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 17 Feb 2012 15:13:38 +0000 (16:13 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Fri, 17 Feb 2012 15:13:38 +0000 (16:13 +0100)
Scripts called by tinc would inherit its open filedescriptors. This could
be a problem if other long-running daemons are started from those scripts,
if those daemons would not close all filedescriptors before going into the
background.

Problem found and solution suggested by Nick Hibma.

THANKS
src/bsd/device.c
src/linux/device.c
src/net_socket.c
src/raw_socket_device.c
src/solaris/device.c
src/uml_device.c
src/vde_device.c

diff --git a/THANKS b/THANKS
index 4a6eae2..f26f268 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -31,6 +31,7 @@ We would like to thank the following people for their contributions to tinc:
 * Menno Smits
 * Michael Tokarev
 * Miles Nordin
+* Nick Hibma
 * Nick Patavalis
 * Paul Littlefield
 * Robert van der Meulen
index f1d3f9f..45c2d5f 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.c -- Interaction BSD tun/tap device
     Copyright (C) 2001-2005 Ivo Timmermans,
-                  2001-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2001-2012 Guus Sliepen <guus@tinc-vpn.org>
                   2009      Grzegorz Dymarek <gregd72002@googlemail.com>
 
     This program is free software; you can redistribute it and/or modify
@@ -106,6 +106,10 @@ static bool setup_device(void) {
                return false;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(device_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
        switch(device_type) {
                default:
                        device_type = DEVICE_TYPE_TUN;
index c06e7b9..f50ff11 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.c -- Interaction with Linux ethertap and tun/tap device
     Copyright (C) 2001-2005 Ivo Timmermans,
-                  2001-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2001-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -72,6 +72,10 @@ static bool setup_device(void) {
                return false;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(device_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
 #ifdef HAVE_LINUX_IF_TUN_H
        /* Ok now check if this is an old ethertap or a new tun/tap thingie */
 
index a45bc20..d8bb007 100644 (file)
@@ -1,7 +1,7 @@
 /*
     net_socket.c -- Handle various kinds of sockets.
     Copyright (C) 1998-2005 Ivo Timmermans,
-                  2000-2010 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
                   2006      Scott Lamb <slamb@slamb.org>
                   2009      Florian Forster <octo@verplant.org>
 
@@ -180,6 +180,10 @@ int setup_listen_socket(const sockaddr_t *sa) {
                return -1;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(nfd, F_SETFD, FD_CLOEXEC);
+#endif
+
        /* Optimize TCP settings */
 
        option = 1;
@@ -238,6 +242,10 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
                return -1;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(nfd, F_SETFD, FD_CLOEXEC);
+#endif
+
 #ifdef O_NONBLOCK
        {
                int flags = fcntl(nfd, F_GETFL);
@@ -410,6 +418,10 @@ begin:
 
        c->socket = socket(c->address.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
 
+#ifdef FD_CLOEXEC
+       fcntl(c->socket, F_SETFD, FD_CLOEXEC);
+#endif
+
        if(c->socket == -1) {
                ifdebug(CONNECTIONS) logger(LOG_ERR, "Creating socket for %s failed: %s", c->hostname, sockstrerror(sockerrno));
                goto begin;
index 90ccedf..e2692ec 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.c -- raw socket
     Copyright (C) 2002-2005 Ivo Timmermans,
-                  2002-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2002-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -53,6 +53,10 @@ static bool setup_device(void) {
                return false;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(device_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
        if(ioctl(device_fd, SIOCGIFINDEX, &ifr)) {
index 579cece..969b514 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.c -- Interaction with Solaris tun device
     Copyright (C) 2001-2005 Ivo Timmermans,
-                  2001-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2001-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -55,6 +55,10 @@ static bool setup_device(void) {
                return false;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(device_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
        ppa = 0;
 
        ptr = device;
@@ -67,6 +71,10 @@ static bool setup_device(void) {
                return false;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(ip_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
        /* Assign a new PPA and get its unit number. */
        if((ppa = ioctl(device_fd, TUNNEWPPA, ppa)) < 0) {
                logger(LOG_ERR, "Can't assign new interface: %s", strerror(errno));
@@ -79,6 +87,10 @@ static bool setup_device(void) {
                return false;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(if_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
        if(ioctl(if_fd, I_PUSH, "ip") < 0) {
                logger(LOG_ERR, "Can't push IP module: %s", strerror(errno));
                return false;
index 26bcb01..a0b87f9 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.c -- UML network socket
     Copyright (C) 2002-2005 Ivo Timmermans,
-                  2002-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2002-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -77,6 +77,10 @@ static bool setup_device(void) {
                return false;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(write_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
        setsockopt(write_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
 
        if(fcntl(write_fd, F_SETFL, O_NONBLOCK) < 0) {
@@ -91,6 +95,10 @@ static bool setup_device(void) {
                return false;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(data_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
        setsockopt(data_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
 
        if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0) {
@@ -118,6 +126,10 @@ static bool setup_device(void) {
                return false;
        }
 
+#ifdef FD_CLOEXEC
+       fcntl(device_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
        setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
 
        if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) {
@@ -181,6 +193,10 @@ static bool read_packet(vpn_packet_t *packet) {
                                return false;
                        }
 
+#ifdef FD_CLOEXEC
+                       fcntl(request_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
                        if(fcntl(listen_fd, F_SETFL, O_NONBLOCK) < 0) {
                                logger(LOG_ERR, "System call `%s' failed: %s", "fcntl", strerror(errno));
                                running = false;
index 8f601e7..258945e 100644 (file)
@@ -1,6 +1,6 @@
 /*
     device.c -- VDE plug
-    Copyright (C) 2011 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -74,6 +74,10 @@ static bool setup_device(void) {
 
        device_fd = plug.vde_datafd(conn);
 
+#ifdef FD_CLOEXEC
+       fcntl(device_fd, F_SETFD, FD_CLOEXEC);
+#endif
+
        logger(LOG_INFO, "%s is a %s", device, device_info);
 
        if(routing_mode == RMODE_ROUTER)