]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
create all sockets with SOCK_CLOEXEC
authorAlexandre Oliva <aoliva@redhat.com>
Mon, 3 Nov 2014 20:51:40 +0000 (18:51 -0200)
committerAlexandre Oliva <aoliva@redhat.com>
Fri, 7 Nov 2014 09:18:52 +0000 (07:18 -0200)
16 files changed:
include/socket-cloexec.h [new file with mode: 0644]
resolv/res_hconf.c
socket/opensock.c
sunrpc/clnt_tcp.c
sunrpc/clnt_unix.c
sunrpc/pm_getport.c
sunrpc/pmap_rmt.c
sunrpc/rtime.c
sunrpc/svc_tcp.c
sunrpc/svc_udp.c
sunrpc/svc_unix.c
sysdeps/gnu/ifaddrs.c
sysdeps/posix/getaddrinfo.c
sysdeps/unix/sysv/linux/check_native.c
sysdeps/unix/sysv/linux/check_pf.c
sysdeps/unix/sysv/linux/ifaddrs.c

diff --git a/include/socket-cloexec.h b/include/socket-cloexec.h
new file mode 100644 (file)
index 0000000..8ada604
--- /dev/null
@@ -0,0 +1,105 @@
+/* Copyright (C) 2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _SOCKET_CLOEXEC_H
+#define _SOCKET_CLOEXEC_H
+
+#include <stdbool.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+
+/* Like socket, but with SOCK_CLOEXEC set if available.  If it's not,
+   try to set the FD_CLOEXEC flag, and if that fails, close the socket
+   and fail unless __tolerant.  */
+static inline int
+__socket_cloexec (int __domain, int __type, int __protocol, bool __tolerant)
+{
+  int __ret;
+#ifdef SOCK_CLOEXEC
+# ifdef __ASSUME_SOCK_CLOEXEC
+  int  __have_sock_cloexec = 1;
+# endif /* __ASSUME_SOCK_CLOEXEC */
+  if (__have_sock_cloexec >= 0)
+    {
+      __ret = __socket (__domain, __type | SOCK_CLOEXEC, __protocol);
+      if (__have_sock_cloexec == 0)
+       __have_sock_cloexec = (__ret == -1 && errno == EINVAL ? -1 : 1);
+      if (__have_sock_cloexec > 0)
+       return __ret;
+    }
+#endif /* SOCK_CLOEXEC */
+  __ret = __socket (__domain, __type, __protocol);
+
+  if ((__ret >= 0 && __fcntl (__ret, F_SETFD, FD_CLOEXEC) < 0) && !__tolerant)
+    {
+      __close (__ret);
+      __ret = -1;
+    }
+
+  return __ret;
+}
+
+/* Like socket, but with SOCK_CLOEXEC and SOCK_NONBLOCK set if
+   SOCK_CLOEXEC is available.  SOCK_NONBLOCK is supported iff
+   SOCK_CLOEXEC is.
+
+   If SOCK_CLOEXEC is not supported, try to set the FD_CLOEXEC flag,
+   and if that fails, close the socket and fail unless __tolerant.
+
+   If SOCK_NONBLOCK is not supported, try to set the O_NONBLOCK flag,
+   and if that fails, close the socket and fail REGARDLESS of
+   __tolerant.  */
+static inline int
+__socket_cloexec_nonblock (int __domain, int __type, int __protocol,
+                          bool __tolerant)
+{
+  int __ret;
+#ifdef SOCK_NONBLOCK
+# ifdef __ASSUME_SOCK_CLOEXEC
+  int  __have_sock_cloexec = 1;
+# endif /* __ASSUME_SOCK_CLOEXEC */
+  if (__have_sock_cloexec >= 0)
+    {
+      __ret = __socket (__domain, __type | SOCK_CLOEXEC | SOCK_NONBLOCK,
+                       __protocol);
+      if (__have_sock_cloexec == 0)
+       __have_sock_cloexec = (__ret == -1 && errno == EINVAL ? -1 : 1);
+      if (__have_sock_cloexec > 0)
+       return __ret;
+    }
+#endif /* SOCK_NONBLOCK */
+  __ret = __socket (__domain, __type, __protocol);
+  if (__ret >= 0)
+    {
+      int __fl = __fcntl (__ret, F_GETFL);
+      if (__fl == -1
+         || __fcntl (__ret, F_SETFL, __fl | O_NONBLOCK) < 0
+         || (__fcntl (__ret, F_SETFD, FD_CLOEXEC) < 0 && !__tolerant))
+       {
+         __close (__ret);
+         __ret = -1;
+       }
+    }
+  return __ret;
+}
+
+#pragma poison __socket
+#pragma poison socket
+
+#endif /* _SOCKET_CLOEXEC_H */
index b4c86227f8ad461083d4f93135413ce87959d954..1df336c699c97b1faa31b6d804864cd71f4eec49 100644 (file)
@@ -41,6 +41,7 @@
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <netinet/in.h>
+#include <socket-cloexec.h>
 #include <bits/libc-lock.h>
 #include "ifreq.h"
 #include "res_hconf.h"
@@ -410,7 +411,7 @@ _res_hconf_reorder_addrs (struct hostent *hp)
       /* Initialize interface table.  */
 
       /* The SIOCGIFNETMASK ioctl will only work on an AF_INET socket.  */
-      sd = __socket (AF_INET, SOCK_DGRAM, 0);
+      sd = __socket_cloexec (AF_INET, SOCK_DGRAM, 0, true);
       if (sd < 0)
        return;
 
index 8dd89060fa95fe77484473cf8a31e83b59d0096b..d23a9624ea7f9a87e2a41bf031ad961de3ba5820 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <stdio.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <bits/libc-lock.h>
 
 /* Return a socket of any type.  The socket can be used in subsequent
@@ -32,7 +33,7 @@ __opensock (void)
 
   if (sock_af != -1)
     {
-      fd = __socket (sock_af, SOCK_DGRAM, 0);
+      fd = __socket_cloexec (sock_af, SOCK_DGRAM, 0, true);
       if (fd != -1)
         return fd;
     }
@@ -40,28 +41,28 @@ __opensock (void)
   __libc_lock_lock (lock);
 
   if (sock_af != -1)
-    fd = __socket (sock_af, SOCK_DGRAM, 0);
+    fd = __socket_cloexec (sock_af, SOCK_DGRAM, 0, true);
 
   if (fd == -1)
     {
 #ifdef AF_INET
-      fd = __socket (sock_af = AF_INET, SOCK_DGRAM, 0);
+      fd = __socket_cloexec (sock_af = AF_INET, SOCK_DGRAM, 0, true);
 #endif
 #ifdef AF_INET6
       if (fd < 0)
-       fd = __socket (sock_af = AF_INET6, SOCK_DGRAM, 0);
+       fd = __socket_cloexec (sock_af = AF_INET6, SOCK_DGRAM, 0, true);
 #endif
 #ifdef AF_IPX
       if (fd < 0)
-       fd = __socket (sock_af = AF_IPX, SOCK_DGRAM, 0);
+       fd = __socket_cloexec (sock_af = AF_IPX, SOCK_DGRAM, 0, true);
 #endif
 #ifdef AF_AX25
       if (fd < 0)
-       fd = __socket (sock_af = AF_AX25, SOCK_DGRAM, 0);
+       fd = __socket_cloexec (sock_af = AF_AX25, SOCK_DGRAM, 0, true);
 #endif
 #ifdef AF_APPLETALK
       if (fd < 0)
-       fd = __socket (sock_af = AF_APPLETALK, SOCK_DGRAM, 0);
+       fd = __socket_cloexec (sock_af = AF_APPLETALK, SOCK_DGRAM, 0, true);
 #endif
     }
 
index f4ba0efe165a7fa82366f47116155febbe76bdc0..2dd07cfa343f415b61550d58eca3e535d1571d76 100644 (file)
@@ -52,6 +52,7 @@
 #include <rpc/rpc.h>
 #include <sys/poll.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <rpc/pmap_clnt.h>
 #include <wchar.h>
 
@@ -146,7 +147,7 @@ clnttcp_create (struct sockaddr_in *raddr, u_long prog, u_long vers,
    */
   if (*sockp < 0)
     {
-      *sockp = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+      *sockp = __socket_cloexec (AF_INET, SOCK_STREAM, IPPROTO_TCP, true);
       (void) bindresvport (*sockp, (struct sockaddr_in *) 0);
       if ((*sockp < 0)
          || (__connect (*sockp, (struct sockaddr *) raddr,
index aff6fa50df7cf1f6826df0251562fd48321fcdf9..419a58a76f474a22877778c8a723837169954c95 100644 (file)
@@ -53,6 +53,7 @@
 #include <sys/uio.h>
 #include <sys/poll.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <rpc/pmap_clnt.h>
 #include <wchar.h>
 
@@ -132,7 +133,7 @@ clntunix_create (struct sockaddr_un *raddr, u_long prog, u_long vers,
    */
   if (*sockp < 0)
     {
-      *sockp = __socket (AF_UNIX, SOCK_STREAM, 0);
+      *sockp = __socket_cloexec (AF_UNIX, SOCK_STREAM, 0, true);
       len = strlen (raddr->sun_path) + sizeof (raddr->sun_family) + 1;
       if (*sockp < 0
          || __connect (*sockp, (struct sockaddr *) raddr, len) < 0)
index d9df0cc35b9cc5f9cb8e0ded5889e41cee59cbca..31f8dccfffbe27da521f3ce317b4f86b6189a262 100644 (file)
@@ -38,6 +38,7 @@
 #include <rpc/pmap_prot.h>
 #include <rpc/pmap_clnt.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 
 /*
  * Create a socket that is locally bound to a non-reserve port. For
@@ -48,7 +49,7 @@ int
 internal_function
 __get_socket (struct sockaddr_in *saddr)
 {
-  int so = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  int so = __socket_cloexec (AF_INET, SOCK_STREAM, IPPROTO_TCP, true);
   if (so < 0)
     return -1;
 
index fd8de85589e32c8e71352cb6f3630b157cf39e65..389eb9e1be076e7bf466a1693ac024ce88d4504b 100644 (file)
@@ -42,6 +42,7 @@
 #include <rpc/pmap_rmt.h>
 #include <sys/poll.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <stdio.h>
 #include <errno.h>
 #undef  _POSIX_SOURCE          /* Ultrix <sys/param.h> needs --roland@gnu */
@@ -238,7 +239,7 @@ clnt_broadcast (prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
    * initialization: create a socket, a broadcast address, and
    * preserialize the arguments into a send buffer.
    */
-  if ((sock = __socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+  if ((sock = __socket_cloexec (AF_INET, SOCK_DGRAM, IPPROTO_UDP, true)) < 0)
     {
       perror (_("Cannot create socket for broadcast rpc"));
       stat = RPC_CANTSEND;
index 79d55d1415a8ddebe25a6326236a313d9e52fe3f..48f4681547e63bee1b538306a31612681207a18c 100644 (file)
@@ -45,6 +45,7 @@
 #include <sys/types.h>
 #include <sys/poll.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <sys/time.h>
 #include <rpc/auth_des.h>
 #include <errno.h>
@@ -84,7 +85,7 @@ rtime (struct sockaddr_in *addrp, struct rpc_timeval *timep,
   else
     type = SOCK_DGRAM;
 
-  s = __socket (AF_INET, type, 0);
+  s = __socket_cloexec (AF_INET, type, 0, true);
   if (s < 0)
     return (-1);
 
index 92886f08690e08054e847340f66e5435340d49bc..eaf6297f5af0b33635cadd47ce24f58ea31ebd89 100644 (file)
@@ -58,6 +58,7 @@
 #include <libintl.h>
 #include <rpc/rpc.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <sys/poll.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -159,7 +160,8 @@ svctcp_create (int sock, u_int sendsize, u_int recvsize)
 
   if (sock == RPC_ANYSOCK)
     {
-      if ((sock = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+      if ((sock = __socket_cloexec (AF_INET, SOCK_STREAM, IPPROTO_TCP,
+                                   true)) < 0)
        {
          perror (_("svc_tcp.c - tcp socket creation problem"));
          return (SVCXPRT *) NULL;
index 411234a207782ad42cebb610cafd8369ad2650c2..f7a6da1e5da35b1a5f2f73f14e8d6ed3122e1bad 100644 (file)
@@ -55,6 +55,7 @@
 #include <string.h>
 #include <rpc/rpc.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <errno.h>
 #include <libintl.h>
 
@@ -132,7 +133,8 @@ svcudp_bufcreate (sock, sendsz, recvsz)
 
   if (sock == RPC_ANYSOCK)
     {
-      if ((sock = __socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+      if ((sock = __socket_cloexec (AF_INET, SOCK_DGRAM, IPPROTO_UDP,
+                                   true)) < 0)
        {
          perror (_("svcudp_create: socket creation problem"));
          return (SVCXPRT *) NULL;
index 6d93c5f6e500a721556837f121b43a240c0d9ce6..0d7466d892f46de65abdb35462f605e9236e8c90 100644 (file)
@@ -58,6 +58,7 @@
 #include <rpc/rpc.h>
 #include <rpc/svc.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <sys/uio.h>
 #include <sys/poll.h>
 #include <errno.h>
@@ -157,7 +158,7 @@ svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
 
   if (sock == RPC_ANYSOCK)
     {
-      if ((sock = __socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
+      if ((sock = __socket_cloexec (AF_UNIX, SOCK_STREAM, 0, true)) < 0)
        {
          perror (_("svc_unix.c - AF_UNIX socket creation problem"));
          return (SVCXPRT *) NULL;
index 1b8775f013aeffd7bc7f04349cd2914e1bd84d8a..70db461b044544f85af0f480999e85cc816ba9a5 100644 (file)
@@ -19,6 +19,7 @@
 #include <ifaddrs.h>
 #include <net/if.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -37,7 +38,7 @@ getifaddrs (struct ifaddrs **ifap)
   /* This implementation handles only IPv4 interfaces.
      The various ioctls below will only work on an AF_INET socket.
      Some different mechanism entirely must be used for IPv6.  */
-  int fd = __socket (AF_INET, SOCK_DGRAM, 0);
+  int fd = __socket_cloexec (AF_INET, SOCK_DGRAM, 0, true);
   struct ifreq *ifreqs;
   int nifs;
 
index 8f392b9678c1da2947196af2bd21964c6b4fdafe..3cbd0334dda8dc68129fc20df80785a0117a5184 100644 (file)
@@ -52,6 +52,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <net/if.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/un.h>
@@ -2512,7 +2513,7 @@ getaddrinfo (const char *name, const char *service,
                  close_retry:
                    close_not_cancel_no_status (fd);
                  af = q->ai_family;
-                 fd = __socket (af, SOCK_DGRAM, IPPROTO_IP);
+                 fd = __socket_cloexec (af, SOCK_DGRAM, IPPROTO_IP, true);
                }
              else
                {
index 68adeb8771d5126cc80b7f3c8bb4b2d455c75ab4..4a2e143ac5c1cf76663206b8ed3ff1982e677296 100644 (file)
@@ -28,6 +28,8 @@
 #include <net/if.h>
 #include <net/if_arp.h>
 #include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <socket-cloexec.h>
 
 #include <asm/types.h>
 #include <linux/netlink.h>
@@ -40,7 +42,7 @@ void
 __check_native (uint32_t a1_index, int *a1_native,
                uint32_t a2_index, int *a2_native)
 {
-  int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  int fd = __socket_cloexec (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, true);
 
   struct sockaddr_nl nladdr;
   memset (&nladdr, '\0', sizeof (nladdr));
index 976f249e209d7f8f9e6eaaf0b5db69409620c809..a098068a26d43fe6f003a31b9b8f8f36f68c0fef 100644 (file)
@@ -26,6 +26,7 @@
 #include <unistd.h>
 #include <stdint.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 
 #include <asm/types.h>
 #include <linux/netlink.h>
@@ -353,7 +354,7 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
     }
   else
     {
-      int fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+      int fd = __socket_cloexec (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, true);
 
       if (__glibc_likely (fd >= 0))
        {
index a47b2edcad437b96c74952367dd7bb611b424b17..aed494ef4eac7a8564d86f96eca4329966b4b2e1 100644 (file)
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
+#include <socket-cloexec.h>
 #include <sysdep.h>
 #include <time.h>
 #include <unistd.h>
@@ -251,7 +252,7 @@ __netlink_open (struct netlink_handle *h)
 {
   struct sockaddr_nl nladdr;
 
-  h->fd = __socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+  h->fd = __socket_cloexec (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, true);
   if (h->fd < 0)
     goto out;