]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: add and use set_cloexec()
authorDavid Lamparter <equinox@opensourcerouting.org>
Tue, 8 Nov 2016 19:46:05 +0000 (20:46 +0100)
committerDavid Lamparter <equinox@opensourcerouting.org>
Wed, 9 Nov 2016 12:40:05 +0000 (13:40 +0100)
watchquagga is already leaking an open file descriptor on its pid file
on fork+exec() invocations; next up is adding vtysh support with even
more fds.  Mark things CLOEXEC before going there.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib/network.c
lib/network.h
lib/pid_output.c
lib/vty.c

index 5379ecb5a68d5102f745588d51ac2512969893bb..506e0191364d60bc9e3b3b627071f7d5b8e189aa 100644 (file)
@@ -94,6 +94,20 @@ set_nonblocking(int fd)
   return 0;
 }
 
+int
+set_cloexec(int fd)
+{
+  int flags;
+  flags = fcntl(fd, F_GETFD, 0);
+  if (flags == -1)
+    return -1;
+
+  flags |= FD_CLOEXEC;
+  if (fcntl(fd, F_SETFD, flags) == -1)
+    return -1;
+  return 0;
+}
+
 float
 htonf (float host)
 {
index 0fcb575d1cea7af6d2ef8d21dfa4f33e8d87bb01..a9126caf7f1a9cfb4474cdb8ab75198615058537 100644 (file)
@@ -33,6 +33,8 @@ extern int writen (int, const u_char *, int);
    -1 on error. */
 extern int set_nonblocking(int fd);
 
+extern int set_cloexec(int fd);
+
 /* Does the I/O error indicate that the operation should be retried later? */
 #define ERRNO_IO_RETRY(EN) \
        (((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))
index 5261babc6d7d59d339fb28f4b36f09cbee442c3a..de4c2fba991e873e1d269b6b1a07e3cd152f374c 100644 (file)
@@ -24,6 +24,7 @@
 #include <fcntl.h>
 #include <log.h>
 #include "version.h"
+#include "network.h"
 
 #define PIDFILE_MASK 0644
 #ifndef HAVE_FCNTL
@@ -84,6 +85,8 @@ pid_output (const char *path)
       umask(oldumask);
       memset (&lock, 0, sizeof(lock));
 
+      set_cloexec(fd);
+
       lock.l_type = F_WRLCK;
       lock.l_whence = SEEK_SET;
 
index 171aca173964838ca2aaf254b00e0525e5c1b68d..10ae99db07875a3b861e23f60293708a02763127 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -1841,6 +1841,7 @@ vty_accept (struct thread *thread)
       return -1;
     }
   set_nonblocking(vty_sock);
+  set_cloexec(vty_sock);
 
   sockunion2hostprefix (&su, &p);
 
@@ -1939,6 +1940,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
       sockopt_v6only (ainfo->ai_family, sock);
       sockopt_reuseaddr (sock);
       sockopt_reuseport (sock);
+      set_cloexec (sock);
 
       ret = bind (sock, ainfo->ai_addr, ainfo->ai_addrlen);
       if (ret < 0)
@@ -2006,6 +2008,7 @@ vty_serv_sock_family (const char* addr, unsigned short port, int family)
   /* This is server, so reuse address. */
   sockopt_reuseaddr (accept_sock);
   sockopt_reuseport (accept_sock);
+  set_cloexec (accept_sock);
 
   /* Bind socket to universal address and given port. */
   ret = sockunion_bind (accept_sock, &su, port, naddr);
@@ -2068,6 +2071,8 @@ vty_serv_un (const char *path)
   len = sizeof (serv.sun_family) + strlen (serv.sun_path);
 #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
 
+  set_cloexec (sock);
+
   ret = bind (sock, (struct sockaddr *) &serv, len);
   if (ret < 0)
     {
@@ -2135,7 +2140,8 @@ vtysh_accept (struct thread *thread)
       close (sock);
       return -1;
     }
-  
+  set_cloexec(sock);
+
 #ifdef VTYSH_DEBUG
   printf ("VTY shell accept\n");
 #endif /* VTYSH_DEBUG */