diff options
| author | David Lamparter <equinox@opensourcerouting.org> | 2016-11-08 20:46:05 +0100 |
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2016-11-09 13:40:05 +0100 |
| commit | 2da59394ec858ae5aecf2b26ab8d9fefdae17bb8 (patch) | |
| tree | 720795e72480f81c7f1cbabe1445bbd4ba8acc1c /lib | |
| parent | 73ea75daa522a43ad0be9bff1f26a98bc2e105b0 (diff) | |
lib: add and use set_cloexec()
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>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/network.c | 14 | ||||
| -rw-r--r-- | lib/network.h | 2 | ||||
| -rw-r--r-- | lib/pid_output.c | 3 | ||||
| -rw-r--r-- | lib/vty.c | 8 |
4 files changed, 26 insertions, 1 deletions
diff --git a/lib/network.c b/lib/network.c index 5379ecb5a6..506e019136 100644 --- a/lib/network.c +++ b/lib/network.c @@ -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) { diff --git a/lib/network.h b/lib/network.h index 0fcb575d1c..a9126caf7f 100644 --- a/lib/network.h +++ b/lib/network.h @@ -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)) diff --git a/lib/pid_output.c b/lib/pid_output.c index 5261babc6d..de4c2fba99 100644 --- a/lib/pid_output.c +++ b/lib/pid_output.c @@ -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; @@ -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 */ |
