Browse Source

[4074] Made sockets close-on-exec

Francis Dupont 9 years ago
parent
commit
aedb56ca1e

+ 10 - 1
src/lib/config/command_socket_factory.cc

@@ -85,8 +85,17 @@ private:
         // shut down properly.
         static_cast<void>(remove(file_name.c_str()));
 
+        // Set this socket to be closed-on-exec.
+        if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
+            const char* errmsg = strerror(errno);
+            ::close(fd);
+            isc_throw(SocketError, "Failed to set close-on-exec on unix socket\
+ "
+                      << fd << ": " << errmsg);
+        }
+
         // Set this socket to be non-blocking one.
-        if (fcntl(fd, F_SETFL, O_NONBLOCK) !=0 ) {
+        if (fcntl(fd, F_SETFL, O_NONBLOCK) != 0) {
             const char* errmsg = strerror(errno);
             ::close(fd);
             isc_throw(SocketError, "Failed to set non-block mode on unix socket "

+ 5 - 0
src/lib/dhcp/iface_mgr_linux.cc

@@ -42,6 +42,7 @@
 #include <boost/array.hpp>
 #include <boost/static_assert.hpp>
 
+#include <fcntl.h>
 #include <stdint.h>
 #include <net/if.h>
 #include <linux/rtnetlink.h>
@@ -135,6 +136,10 @@ void Netlink::rtnl_open_socket() {
         isc_throw(Unexpected, "Failed to create NETLINK socket.");
     }
 
+    if (fcntl(fd_, F_SETFD, FD_CLOEXEC) < 0) {
+        isc_throw(Unexpected, "Failed to set close-on-exec in NETLINK socket.");
+    }
+
     if (setsockopt(fd_, SOL_SOCKET, SO_SNDBUF, &SNDBUF_SIZE, sizeof(SNDBUF_SIZE)) < 0) {
         isc_throw(Unexpected, "Failed to set send buffer in NETLINK socket.");
     }

+ 9 - 1
src/lib/dhcp/pkt_filter.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -32,6 +32,14 @@ PktFilter::openFallbackSocket(const isc::asiolink::IOAddress& addr,
                   " address " << addr << ", port " << port
                   << ", reason: " << strerror(errno));
     }
+    // Set the close-on-exec flag.
+    if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
+        close(sock);
+        isc_throw(SocketConfigError, "Failed to set close-on-exec flag"
+                  << " on fallback socket for address " << addr
+                  << ", port " << port
+                  << ", reason: " << strerror(errno));
+    }
     // Bind the socket to a specified address and port.
     struct sockaddr_in addr4;
     memset(&addr4, 0, sizeof(addr4));

+ 8 - 0
src/lib/dhcp/pkt_filter_bpf.cc

@@ -266,6 +266,14 @@ PktFilterBPF::openSocket(Iface& iface,
         }
     }
 
+    // Set the close-on-exec flag.
+    if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
+        close(fallback);
+        close(sock);
+        isc_throw(SocketConfigError, "Failed to set close-on-exec flag"
+                  << " on BPF device with interface " << iface.getName());
+    }
+
     // The BPF device is now open. Now it needs to be configured.
 
     // Associate the device with the interface name.

+ 8 - 0
src/lib/dhcp/pkt_filter_inet.cc

@@ -18,6 +18,7 @@
 #include <dhcp/pkt_filter_inet.h>
 #include <errno.h>
 #include <cstring>
+#include <fcntl.h>
 
 using namespace isc::asiolink;
 
@@ -55,6 +56,13 @@ PktFilterInet::openSocket(Iface& iface,
         isc_throw(SocketConfigError, "Failed to create UDP6 socket.");
     }
 
+    // Set the close-on-exec flag.
+    if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
+        close(sock);
+        isc_throw(SocketConfigError, "Failed to set close-on-exec flag"
+                  << " on socket " << sock);
+    }
+
 #ifdef SO_BINDTODEVICE
     if (receive_bcast && iface.flag_broadcast_) {
         // Bind to device so as we receive traffic on a specific interface.

+ 8 - 0
src/lib/dhcp/pkt_filter_inet6.cc

@@ -19,6 +19,7 @@
 #include <dhcp/pkt_filter_inet6.h>
 #include <util/io/pktinfo_utilities.h>
 
+#include <fcntl.h>
 #include <netinet/in.h>
 
 using namespace isc::asiolink;
@@ -66,6 +67,13 @@ PktFilterInet6::openSocket(const Iface& iface,
         isc_throw(SocketConfigError, "Failed to create UDP6 socket.");
     }
 
+    // Set the close-on-exec flag.
+    if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
+        close(sock);
+        isc_throw(SocketConfigError, "Failed to set close-on-exec flag"
+                  << " on IPv6 socket.");
+    }
+
     // Set SO_REUSEADDR option.
     int flag = 1;
     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,

+ 9 - 0
src/lib/dhcp/pkt_filter_lpf.cc

@@ -19,6 +19,7 @@
 #include <dhcp/pkt_filter_lpf.h>
 #include <dhcp/protocol_util.h>
 #include <exceptions/exceptions.h>
+#include <fcntl.h>
 #include <linux/filter.h>
 #include <linux/if_ether.h>
 #include <linux/if_packet.h>
@@ -154,6 +155,14 @@ PktFilterLPF::openSocket(Iface& iface,
         isc_throw(SocketConfigError, "Failed to create raw LPF socket");
     }
 
+    // Set the close-on-exec flag.
+    if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
+        close(sock);
+        close(fallback);
+        isc_throw(SocketConfigError, "Failed to set close-on-exec flag"
+                  << " on the socket " << sock);
+    }
+
     // Create socket filter program. This program will only allow incoming UDP
     // traffic which arrives on the specific (DHCP) port). It will also filter
     // out all fragmented packets.

+ 12 - 0
src/lib/util/watch_socket.cc

@@ -42,6 +42,18 @@ WatchSocket::WatchSocket()
     source_ = fds[1];
     sink_ = fds[0];
 
+    if (fcntl(source_, F_SETFD, FD_CLOEXEC)) {
+        const char* errstr = strerror(errno);
+        isc_throw(WatchSocketError, "Cannot set source to close-on-exec: "
+                                     << errstr);
+    }
+
+    if (fcntl(sink_, F_SETFD, FD_CLOEXEC)) {
+        const char* errstr = strerror(errno);
+        isc_throw(WatchSocketError, "Cannot set sink to close-on-exec: "
+                                     << errstr);
+    }
+
     if (fcntl(sink_, F_SETFL, O_NONBLOCK)) {
         const char* errstr = strerror(errno);
         isc_throw(WatchSocketError, "Cannot set sink to non-blocking: "