[Lldb-commits] [lldb] r222004 - Apply SOCK_CLOEXEC flag to socket API functions in order to avoid handle leakage to a forked child process.
Oleksiy Vyalov
ovyalov at google.com
Fri Nov 14 08:25:18 PST 2014
Author: ovyalov
Date: Fri Nov 14 10:25:18 2014
New Revision: 222004
URL: http://llvm.org/viewvc/llvm-project?rev=222004&view=rev
Log:
Apply SOCK_CLOEXEC flag to socket API functions in order to avoid handle leakage to a forked child process.
http://reviews.llvm.org/D6204
Modified:
lldb/trunk/include/lldb/Host/Socket.h
lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
lldb/trunk/source/Host/common/Socket.cpp
lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
Modified: lldb/trunk/include/lldb/Host/Socket.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Socket.h?rev=222004&r1=222003&r2=222004&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Socket.h (original)
+++ lldb/trunk/include/lldb/Host/Socket.h Fri Nov 14 10:25:18 2014
@@ -56,16 +56,16 @@ public:
// Initialize a Tcp Socket object in listening mode. listen and accept are implemented
// separately because the caller may wish to manipulate or query the socket after it is
// initialized, but before entering a blocking accept.
- static Error TcpListen(llvm::StringRef host_and_port, Socket *&socket, Predicate<uint16_t>* predicate);
- static Error TcpConnect(llvm::StringRef host_and_port, Socket *&socket);
- static Error UdpConnect(llvm::StringRef host_and_port, Socket *&send_socket, Socket *&recv_socket);
- static Error UnixDomainConnect(llvm::StringRef host_and_port, Socket *&socket);
- static Error UnixDomainAccept(llvm::StringRef host_and_port, Socket *&socket);
+ static Error TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket, Predicate<uint16_t>* predicate);
+ static Error TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket);
+ static Error UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket);
+ static Error UnixDomainConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket);
+ static Error UnixDomainAccept(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket);
// Blocks on a listening socket until a connection is received. This method assumes that
// |this->m_socket| is a listening socket, created via either TcpListen() or via the native
// constructor that takes a NativeSocket, which itself was created via a call to |listen()|
- Error BlockingAccept(llvm::StringRef host_and_port, Socket *&socket);
+ Error BlockingAccept(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket);
int GetOption (int level, int option_name, int &option_value);
int SetOption (int level, int option_name, int option_value);
Modified: lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h?rev=222004&r1=222003&r2=222004&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h (original)
+++ lldb/trunk/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h Fri Nov 14 10:25:18 2014
@@ -34,7 +34,7 @@ class SocketAddress;
class ConnectionFileDescriptor : public Connection
{
public:
- ConnectionFileDescriptor();
+ ConnectionFileDescriptor(bool child_processes_inherit = false);
ConnectionFileDescriptor(int fd, bool owns_fd);
@@ -67,6 +67,9 @@ class ConnectionFileDescriptor : public
uint16_t GetListeningPort(uint32_t timeout_sec);
+ bool GetChildProcessesInherit() const;
+ void SetChildProcessesInherit(bool child_processes_inherit);
+
protected:
void OpenCommandPipe();
@@ -94,6 +97,7 @@ class ConnectionFileDescriptor : public
std::atomic<bool> m_shutting_down; // This marks that we are shutting down so if we get woken up from
// BytesAvailable to disconnect, we won't try to read again.
bool m_waiting_for_accept;
+ bool m_child_processes_inherit;
private:
DISALLOW_COPY_AND_ASSIGN(ConnectionFileDescriptor);
Modified: lldb/trunk/source/Host/common/Socket.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Socket.cpp?rev=222004&r1=222003&r2=222004&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Socket.cpp (original)
+++ lldb/trunk/source/Host/common/Socket.cpp Fri Nov 14 10:25:18 2014
@@ -55,6 +55,33 @@ const NativeSocket Socket::kInvalidSocke
#endif
#endif // #ifdef __ANDROID__
+namespace {
+
+NativeSocket CreateSocket(const int domain, const int type, const int protocol, bool child_processes_inherit)
+{
+ auto socketType = type;
+#ifdef SOCK_CLOEXEC
+ if (!child_processes_inherit) {
+ socketType |= SOCK_CLOEXEC;
+ }
+#endif
+ return ::socket (domain, socketType, protocol);
+}
+
+NativeSocket Accept(NativeSocket sockfd, struct sockaddr *addr, socklen_t *addrlen, bool child_processes_inherit)
+{
+#ifdef SOCK_CLOEXEC
+ int flags = 0;
+ if (!child_processes_inherit) {
+ flags |= SOCK_CLOEXEC;
+ }
+ return ::accept4 (sockfd, addr, addrlen, flags);
+#else
+ return ::accept (sockfd, addr, addrlen);
+#endif
+}
+}
+
Socket::Socket(NativeSocket socket, SocketProtocol protocol, bool should_close)
: IOObject(eFDTypeSocket, should_close)
, m_protocol(protocol)
@@ -68,7 +95,7 @@ Socket::~Socket()
Close();
}
-Error Socket::TcpConnect(llvm::StringRef host_and_port, Socket *&socket)
+Error Socket::TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket)
{
// Store the result in a unique_ptr in case we error out, the memory will get correctly freed.
std::unique_ptr<Socket> final_socket;
@@ -86,7 +113,7 @@ Error Socket::TcpConnect(llvm::StringRef
return error;
// Create the socket
- sock = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ sock = CreateSocket (AF_INET, SOCK_STREAM, IPPROTO_TCP, child_processes_inherit);
if (sock == kInvalidSocketValue)
{
// TODO: On Windows, use WSAGetLastError().
@@ -140,7 +167,7 @@ Error Socket::TcpConnect(llvm::StringRef
return error;
}
-Error Socket::TcpListen(llvm::StringRef host_and_port, Socket *&socket, Predicate<uint16_t>* predicate)
+Error Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket, Predicate<uint16_t>* predicate)
{
std::unique_ptr<Socket> listen_socket;
NativeSocket listen_sock = kInvalidSocketValue;
@@ -149,7 +176,7 @@ Error Socket::TcpListen(llvm::StringRef
const sa_family_t family = AF_INET;
const int socktype = SOCK_STREAM;
const int protocol = IPPROTO_TCP;
- listen_sock = ::socket (family, socktype, protocol);
+ listen_sock = ::CreateSocket (family, socktype, protocol, child_processes_inherit);
if (listen_sock == kInvalidSocketValue)
{
error.SetErrorToErrno();
@@ -211,7 +238,7 @@ Error Socket::TcpListen(llvm::StringRef
return error;
}
-Error Socket::BlockingAccept(llvm::StringRef host_and_port, Socket *&socket)
+Error Socket::BlockingAccept(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket)
{
Error error;
std::string host_str;
@@ -250,7 +277,10 @@ Error Socket::BlockingAccept(llvm::Strin
#endif
socklen_t accept_addr_len = sizeof accept_addr;
- int sock = ::accept (this->GetNativeSocket(), (struct sockaddr *)&accept_addr, &accept_addr_len);
+ int sock = Accept (this->GetNativeSocket(),
+ (struct sockaddr *)&accept_addr,
+ &accept_addr_len,
+ child_processes_inherit);
if (sock == kInvalidSocketValue)
{
@@ -295,7 +325,7 @@ Error Socket::BlockingAccept(llvm::Strin
}
-Error Socket::UdpConnect(llvm::StringRef host_and_port, Socket *&send_socket, Socket *&recv_socket)
+Error Socket::UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket)
{
std::unique_ptr<Socket> final_send_socket;
std::unique_ptr<Socket> final_recv_socket;
@@ -315,7 +345,7 @@ Error Socket::UdpConnect(llvm::StringRef
// Setup the receiving end of the UDP connection on this localhost
// on port zero. After we bind to port zero we can read the port.
- final_recv_fd = ::socket (AF_INET, SOCK_DGRAM, 0);
+ final_recv_fd = ::CreateSocket (AF_INET, SOCK_DGRAM, 0, child_processes_inherit);
if (final_recv_fd == kInvalidSocketValue)
{
// Socket creation failed...
@@ -366,9 +396,10 @@ Error Socket::UdpConnect(llvm::StringRef
service_info_ptr != NULL;
service_info_ptr = service_info_ptr->ai_next)
{
- final_send_fd = ::socket (service_info_ptr->ai_family,
- service_info_ptr->ai_socktype,
- service_info_ptr->ai_protocol);
+ final_send_fd = ::CreateSocket (service_info_ptr->ai_family,
+ service_info_ptr->ai_socktype,
+ service_info_ptr->ai_protocol,
+ child_processes_inherit);
if (final_send_fd != kInvalidSocketValue)
{
@@ -395,7 +426,7 @@ Error Socket::UdpConnect(llvm::StringRef
return error;
}
-Error Socket::UnixDomainConnect(llvm::StringRef name, Socket *&socket)
+Error Socket::UnixDomainConnect(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
{
Error error;
#ifndef LLDB_DISABLE_POSIX
@@ -403,7 +434,7 @@ Error Socket::UnixDomainConnect(llvm::St
// Open the socket that was passed in as an option
struct sockaddr_un saddr_un;
- int fd = ::socket (AF_UNIX, SOCK_STREAM, 0);
+ int fd = ::CreateSocket (AF_UNIX, SOCK_STREAM, 0, child_processes_inherit);
if (fd == kInvalidSocketValue)
{
error.SetErrorToErrno();
@@ -432,7 +463,7 @@ Error Socket::UnixDomainConnect(llvm::St
return error;
}
-Error Socket::UnixDomainAccept(llvm::StringRef name, Socket *&socket)
+Error Socket::UnixDomainAccept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
{
Error error;
#ifndef LLDB_DISABLE_POSIX
@@ -442,7 +473,7 @@ Error Socket::UnixDomainAccept(llvm::Str
NativeSocket listen_fd = kInvalidSocketValue;
NativeSocket socket_fd = kInvalidSocketValue;
- listen_fd = ::socket (AF_UNIX, SOCK_STREAM, 0);
+ listen_fd = ::CreateSocket (AF_UNIX, SOCK_STREAM, 0, child_processes_inherit);
if (listen_fd == kInvalidSocketValue)
{
error.SetErrorToErrno();
@@ -464,7 +495,7 @@ Error Socket::UnixDomainAccept(llvm::Str
{
if (::listen (listen_fd, 5) == 0)
{
- socket_fd = ::accept (listen_fd, NULL, 0);
+ socket_fd = Accept (listen_fd, NULL, 0, child_processes_inherit);
if (socket_fd > 0)
{
final_socket.reset(new Socket(socket_fd, ProtocolUnixDomain, true));
Modified: lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp?rev=222004&r1=222003&r2=222004&view=diff
==============================================================================
--- lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp (original)
+++ lldb/trunk/source/Host/posix/ConnectionFileDescriptorPosix.cpp Fri Nov 14 10:25:18 2014
@@ -49,12 +49,13 @@
using namespace lldb;
using namespace lldb_private;
-ConnectionFileDescriptor::ConnectionFileDescriptor()
+ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit)
: Connection()
, m_pipe()
, m_mutex(Mutex::eMutexTypeRecursive)
, m_shutting_down(false)
, m_waiting_for_accept(false)
+ , m_child_processes_inherit(child_processes_inherit)
{
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
if (log)
@@ -67,6 +68,7 @@ ConnectionFileDescriptor::ConnectionFile
, m_mutex(Mutex::eMutexTypeRecursive)
, m_shutting_down(false)
, m_waiting_for_accept(false)
+ , m_child_processes_inherit(false)
{
m_write_sp.reset(new File(fd, owns_fd));
m_read_sp.reset(new File(fd, false));
@@ -690,7 +692,7 @@ ConnectionStatus
ConnectionFileDescriptor::NamedSocketAccept(const char *socket_name, Error *error_ptr)
{
Socket *socket = nullptr;
- Error error = Socket::UnixDomainAccept(socket_name, socket);
+ Error error = Socket::UnixDomainAccept(socket_name, m_child_processes_inherit, socket);
if (error_ptr)
*error_ptr = error;
m_write_sp.reset(socket);
@@ -702,7 +704,7 @@ ConnectionStatus
ConnectionFileDescriptor::NamedSocketConnect(const char *socket_name, Error *error_ptr)
{
Socket *socket = nullptr;
- Error error = Socket::UnixDomainConnect(socket_name, socket);
+ Error error = Socket::UnixDomainConnect(socket_name, m_child_processes_inherit, socket);
if (error_ptr)
*error_ptr = error;
m_write_sp.reset(socket);
@@ -717,7 +719,7 @@ ConnectionFileDescriptor::SocketListen(c
Socket *socket = nullptr;
m_waiting_for_accept = true;
- Error error = Socket::TcpListen(s, socket, &m_port_predicate);
+ Error error = Socket::TcpListen(s, m_child_processes_inherit, socket, &m_port_predicate);
if (error_ptr)
*error_ptr = error;
if (error.Fail())
@@ -727,7 +729,7 @@ ConnectionFileDescriptor::SocketListen(c
listening_socket_up.reset(socket);
socket = nullptr;
- error = listening_socket_up->BlockingAccept(s, socket);
+ error = listening_socket_up->BlockingAccept(s, m_child_processes_inherit, socket);
listening_socket_up.reset();
if (error_ptr)
*error_ptr = error;
@@ -743,7 +745,7 @@ ConnectionStatus
ConnectionFileDescriptor::ConnectTCP(const char *s, Error *error_ptr)
{
Socket *socket = nullptr;
- Error error = Socket::TcpConnect(s, socket);
+ Error error = Socket::TcpConnect(s, m_child_processes_inherit, socket);
if (error_ptr)
*error_ptr = error;
m_write_sp.reset(socket);
@@ -756,7 +758,7 @@ ConnectionFileDescriptor::ConnectUDP(con
{
Socket *send_socket = nullptr;
Socket *recv_socket = nullptr;
- Error error = Socket::UdpConnect(s, send_socket, recv_socket);
+ Error error = Socket::UdpConnect(s, m_child_processes_inherit, send_socket, recv_socket);
if (error_ptr)
*error_ptr = error;
m_write_sp.reset(send_socket);
@@ -778,3 +780,15 @@ ConnectionFileDescriptor::GetListeningPo
}
return bound_port;
}
+
+bool
+ConnectionFileDescriptor::GetChildProcessesInherit() const
+{
+ return m_child_processes_inherit;
+}
+
+void
+ConnectionFileDescriptor::SetChildProcessesInherit(bool child_processes_inherit)
+{
+ m_child_processes_inherit = child_processes_inherit;
+}
More information about the lldb-commits
mailing list