From: Francis Dupont Date: Thu, 1 Oct 2015 20:51:20 +0000 (+0200) Subject: [4074] Made sockets close-on-exec X-Git-Tag: trac3874_base~29^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aedb56ca1e573729024fa335a69210c75ab951db;p=thirdparty%2Fkea.git [4074] Made sockets close-on-exec --- diff --git a/src/lib/config/command_socket_factory.cc b/src/lib/config/command_socket_factory.cc index aa3cbe520e..768658ed37 100644 --- a/src/lib/config/command_socket_factory.cc +++ b/src/lib/config/command_socket_factory.cc @@ -85,8 +85,17 @@ private: // shut down properly. static_cast(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 " diff --git a/src/lib/dhcp/iface_mgr_linux.cc b/src/lib/dhcp/iface_mgr_linux.cc index 4409a25578..1c20809935 100644 --- a/src/lib/dhcp/iface_mgr_linux.cc +++ b/src/lib/dhcp/iface_mgr_linux.cc @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -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."); } diff --git a/src/lib/dhcp/pkt_filter.cc b/src/lib/dhcp/pkt_filter.cc index 154e6b547b..0451c386f8 100644 --- a/src/lib/dhcp/pkt_filter.cc +++ b/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)); diff --git a/src/lib/dhcp/pkt_filter_bpf.cc b/src/lib/dhcp/pkt_filter_bpf.cc index 84c202339d..cbcb335ff1 100644 --- a/src/lib/dhcp/pkt_filter_bpf.cc +++ b/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. diff --git a/src/lib/dhcp/pkt_filter_inet.cc b/src/lib/dhcp/pkt_filter_inet.cc index 7cc3612acc..d3b038b4c4 100644 --- a/src/lib/dhcp/pkt_filter_inet.cc +++ b/src/lib/dhcp/pkt_filter_inet.cc @@ -18,6 +18,7 @@ #include #include #include +#include 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. diff --git a/src/lib/dhcp/pkt_filter_inet6.cc b/src/lib/dhcp/pkt_filter_inet6.cc index 29161bf9a1..6fa56a6f1c 100644 --- a/src/lib/dhcp/pkt_filter_inet6.cc +++ b/src/lib/dhcp/pkt_filter_inet6.cc @@ -19,6 +19,7 @@ #include #include +#include #include 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, diff --git a/src/lib/dhcp/pkt_filter_lpf.cc b/src/lib/dhcp/pkt_filter_lpf.cc index 2959125e34..840631f514 100644 --- a/src/lib/dhcp/pkt_filter_lpf.cc +++ b/src/lib/dhcp/pkt_filter_lpf.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -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. diff --git a/src/lib/util/watch_socket.cc b/src/lib/util/watch_socket.cc index 6ac0128e60..b0e382605f 100644 --- a/src/lib/util/watch_socket.cc +++ b/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: "