aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/daemon.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-06-22 09:58:14 +0000
committerChristian Grothoff <christian@grothoff.org>2012-06-22 09:58:14 +0000
commit6a99b74bb8fe7608f5dcfcec6b35d7648579c67f (patch)
treef0c1f9f6157a7126ef2f11b9f4072d2b10626041 /src/daemon/daemon.c
parentfaabde7649be638b3be42e83be0bf367741d38a1 (diff)
downloadlibmicrohttpd-6a99b74bb8fe7608f5dcfcec6b35d7648579c67f.tar.gz
libmicrohttpd-6a99b74bb8fe7608f5dcfcec6b35d7648579c67f.zip
-#2414: make listen and accepted sockets non-inheritable by default
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r--src/daemon/daemon.c95
1 files changed, 90 insertions, 5 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 451bb39a..6db7ec10 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -77,6 +77,11 @@
77#endif 77#endif
78#endif 78#endif
79 79
80#ifndef SOCK_CLOEXEC
81#define SOCK_CLOEXEC 0
82#endif
83
84
80/** 85/**
81 * Default implementation of the panic function 86 * Default implementation of the panic function
82 */ 87 */
@@ -961,7 +966,8 @@ MHD_add_connection (struct MHD_Daemon *daemon,
961 (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) ) 966 (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
962 { 967 {
963#if HAVE_MESSAGES 968#if HAVE_MESSAGES
964 FPRINTF(stderr, "Failed to make socket non-blocking: %s\n", 969 FPRINTF(stderr, "Failed to make socket %d non-blocking: %s\n",
970 connection->socket_fd,
965 STRERROR (errno)); 971 STRERROR (errno));
966#endif 972#endif
967 } 973 }
@@ -1108,10 +1114,23 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1108 struct sockaddr *addr = (struct sockaddr *) &addrstorage; 1114 struct sockaddr *addr = (struct sockaddr *) &addrstorage;
1109 socklen_t addrlen; 1115 socklen_t addrlen;
1110 int s; 1116 int s;
1117 int flags;
1118 int need_fcntl;
1111 1119
1112 addrlen = sizeof (addrstorage); 1120 addrlen = sizeof (addrstorage);
1113 memset (addr, 0, sizeof (addrstorage)); 1121 memset (addr, 0, sizeof (addrstorage));
1114 s = ACCEPT (daemon->socket_fd, addr, &addrlen); 1122#if HAVE_ACCEPT4
1123 s = accept4 (daemon->socket_fd, addr, &addrlen, SOCK_CLOEXEC);
1124 need_fcntl = MHD_NO;
1125#else
1126 s = -1;
1127 need_fcntl = MHD_YES;
1128#endif
1129 if (-1 == s)
1130 {
1131 s = ACCEPT (daemon->socket_fd, addr, &addrlen);
1132 need_fcntl = MHD_YES;
1133 }
1115 if ((s == -1) || (addrlen <= 0)) 1134 if ((s == -1) || (addrlen <= 0))
1116 { 1135 {
1117#if HAVE_MESSAGES 1136#if HAVE_MESSAGES
@@ -1127,6 +1146,20 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
1127 } 1146 }
1128 return MHD_NO; 1147 return MHD_NO;
1129 } 1148 }
1149 if (MHD_YES == need_fcntl)
1150 {
1151 /* make socket non-inheritable */
1152 flags = fcntl (s, F_GETFD);
1153 if ( ( (-1 == flags) ||
1154 ( (flags != (flags | FD_CLOEXEC)) &&
1155 (0 != fcntl (s, F_SETFD, flags | FD_CLOEXEC)) ) ) )
1156 {
1157#if HAVE_MESSAGES
1158 FPRINTF(stderr, "Failed to make socket non-inheritable: %s\n",
1159 STRERROR (errno));
1160#endif
1161 }
1162 }
1130#if HAVE_MESSAGES 1163#if HAVE_MESSAGES
1131#if DEBUG_CONNECT 1164#if DEBUG_CONNECT
1132 MHD_DLOG (daemon, "Accepted connection on socket %d\n", s); 1165 MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
@@ -1947,6 +1980,58 @@ parse_options_va (struct MHD_Daemon *daemon,
1947 1980
1948 1981
1949/** 1982/**
1983 * Create a listen socket, if possible with CLOEXEC flag set.
1984 *
1985 * @param domain socket domain (i.e. PF_INET)
1986 * @param type socket type (usually SOCK_STREAM)
1987 * @param protocol desired protocol, 0 for default
1988 */
1989static int
1990create_socket (int domain, int type, int protocol)
1991{
1992 static int sock_cloexec = SOCK_CLOEXEC;
1993 int ctype = SOCK_STREAM | sock_cloexec;
1994 int fd;
1995 int flags;
1996
1997 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
1998 * implementations do not set ai_socktype, e.g. RHL6.2. */
1999 fd = socket(domain, ctype, protocol);
2000 if ( (-1 == fd) && (EINVAL == errno) && (0 != sock_cloexec) )
2001 {
2002 sock_cloexec = 0;
2003 fd = socket(domain, type, protocol);
2004 }
2005 if (-1 == fd)
2006 return -1;
2007 if (0 != sock_cloexec)
2008 return fd; /* this is it */
2009 /* flag was not set during 'socket' call, let's try setting it manually */
2010 flags = fcntl (fd, F_GETFD);
2011 if (flags < 0)
2012 {
2013#if HAVE_MESSAGES
2014 FPRINTF(stderr, "Failed to get socket options to make socket non-inheritable: %s\n",
2015 STRERROR (errno));
2016#endif
2017 return fd; /* good luck */
2018 }
2019 if (flags == (flags | FD_CLOEXEC))
2020 return fd; /* already set */
2021 flags |= FD_CLOEXEC;
2022 if (0 != fcntl (fd, F_SETFD, flags))
2023 {
2024#if HAVE_MESSAGES
2025 FPRINTF(stderr, "Failed to make socket non-inheritable: %s\n",
2026 STRERROR (errno));
2027#endif
2028 return fd; /* good luck */
2029 }
2030 return fd;
2031}
2032
2033
2034/**
1950 * Start a webserver on the given port. 2035 * Start a webserver on the given port.
1951 * 2036 *
1952 * @param port port to bind to 2037 * @param port port to bind to
@@ -2148,7 +2233,7 @@ MHD_start_daemon_va (unsigned int options,
2148 { 2233 {
2149 if ((options & MHD_USE_IPv6) != 0) 2234 if ((options & MHD_USE_IPv6) != 0)
2150#if HAVE_INET6 2235#if HAVE_INET6
2151 socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0); 2236 socket_fd = create_socket (PF_INET6, SOCK_STREAM, 0);
2152#else 2237#else
2153 { 2238 {
2154#if HAVE_MESSAGES 2239#if HAVE_MESSAGES
@@ -2159,7 +2244,7 @@ MHD_start_daemon_va (unsigned int options,
2159 } 2244 }
2160#endif 2245#endif
2161 else 2246 else
2162 socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0); 2247 socket_fd = create_socket (PF_INET, SOCK_STREAM, 0);
2163 if (socket_fd == -1) 2248 if (socket_fd == -1)
2164 { 2249 {
2165#if HAVE_MESSAGES 2250#if HAVE_MESSAGES
@@ -2358,7 +2443,7 @@ MHD_start_daemon_va (unsigned int options,
2358 sk_flags = fcntl (socket_fd, F_GETFL); 2443 sk_flags = fcntl (socket_fd, F_GETFL);
2359 if (sk_flags < 0) 2444 if (sk_flags < 0)
2360 goto thread_failed; 2445 goto thread_failed;
2361 if (fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK) < 0) 2446 if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
2362 goto thread_failed; 2447 goto thread_failed;
2363#else 2448#else
2364 sk_flags = 1; 2449 sk_flags = 1;