|
@@ -101,6 +101,23 @@
|
|
|
#include "strlcat.c"
|
|
|
#endif
|
|
|
|
|
|
+/** As open(path, flags, mode), but return an fd with the close-on-exec mode
|
|
|
+ * set. */
|
|
|
+int
|
|
|
+tor_open_cloexec(const char *path, int flags, unsigned mode)
|
|
|
+{
|
|
|
+#ifdef O_CLOEXEC
|
|
|
+ return open(path, flags|O_CLOEXEC, mode);
|
|
|
+#else
|
|
|
+ int fd = open(path, flags, mode);
|
|
|
+#ifdef FD_CLOEXEC
|
|
|
+ if (fd >= 0)
|
|
|
+ fcntl(s, F_SETFD, FD_CLOEXEC);
|
|
|
+#endif
|
|
|
+ return fd;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
#ifdef HAVE_SYS_MMAN_H
|
|
|
/** Try to create a memory mapping for <b>filename</b> and return it. On
|
|
|
* failure, return NULL. Sets errno properly, using ERANGE to mean
|
|
@@ -116,7 +133,7 @@ tor_mmap_file(const char *filename)
|
|
|
|
|
|
tor_assert(filename);
|
|
|
|
|
|
- fd = open(filename, O_RDONLY, 0);
|
|
|
+ fd = tor_open_cloexec(filename, O_RDONLY, 0);
|
|
|
if (fd<0) {
|
|
|
int save_errno = errno;
|
|
|
int severity = (errno == ENOENT) ? LOG_INFO : LOG_WARN;
|
|
@@ -685,7 +702,7 @@ tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
|
|
|
*locked_out = 0;
|
|
|
|
|
|
log_info(LD_FS, "Locking \"%s\"", filename);
|
|
|
- fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
|
|
|
+ fd = tor_open_cloexec(filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
|
|
|
if (fd < 0) {
|
|
|
log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
|
|
|
strerror(errno));
|
|
@@ -904,8 +921,15 @@ mark_socket_open(int s)
|
|
|
int
|
|
|
tor_open_socket(int domain, int type, int protocol)
|
|
|
{
|
|
|
- int s = socket(domain, type, protocol);
|
|
|
+ int s;
|
|
|
+#ifdef SOCK_CLOEXEC
|
|
|
+ type |= SOCK_CLOEXEC;
|
|
|
+#endif
|
|
|
+ s = socket(domain, type, protocol);
|
|
|
if (s >= 0) {
|
|
|
+#ifdef FD_CLOEXEC
|
|
|
+ fcntl(s, F_SETFD, FD_CLOEXEC);
|
|
|
+#endif
|
|
|
socket_accounting_lock();
|
|
|
++n_sockets_open;
|
|
|
mark_socket_open(s);
|
|
@@ -918,8 +942,17 @@ tor_open_socket(int domain, int type, int protocol)
|
|
|
int
|
|
|
tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len)
|
|
|
{
|
|
|
- int s = accept(sockfd, addr, len);
|
|
|
+ int s;
|
|
|
+#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC)
|
|
|
+#define LINUX_CLOEXEC_ACCEPT
|
|
|
+ s = accept4(sockfd, addr, len, SOCK_CLOEXEC);
|
|
|
+#else
|
|
|
+ s = accept(sockfd, addr, len);
|
|
|
+#endif
|
|
|
if (s >= 0) {
|
|
|
+#if !defined(LINUX_CLOEXEC_ACCEPT) && defined(FD_CLOEXEC)
|
|
|
+ fcntl(s, F_SETFD, FD_CLOEXEC);
|
|
|
+#endif
|
|
|
socket_accounting_lock();
|
|
|
++n_sockets_open;
|
|
|
mark_socket_open(s);
|