[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] [tor/master 1/9] Initial work to set CLOEXEC on all possible fds
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Sat, 20 Nov 2010 00:58:33 -0500
Subject: Initial work to set CLOEXEC on all possible fds
Commit: 5a66de7015d32e723f13171b622a8dabcef05126
Still to go: some pipes, all stdio files.
---
configure.in | 1 +
src/common/compat.c | 41 +++++++++++++++++++++++++++++++++++++----
src/common/compat.h | 3 +++
src/common/util.c | 6 +++---
src/or/connection_edge.c | 4 ++--
src/or/eventdns.c | 2 +-
6 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/configure.in b/configure.in
index e156533..6ca5531 100644
--- a/configure.in
+++ b/configure.in
@@ -250,6 +250,7 @@ dnl Check for functions before libevent, since libevent-1.2 apparently
dnl exports strlcpy without defining it in a header.
AC_CHECK_FUNCS(
+ accept4 \
flock \
ftime \
getaddrinfo \
diff --git a/src/common/compat.c b/src/common/compat.c
index b7f4f17..e3a76e8 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -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);
diff --git a/src/common/compat.h b/src/common/compat.h
index 2471e6b..9eaf77a 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -340,6 +340,9 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
((tvp)->tv_sec cmp (uvp)->tv_sec))
/* ===== File compatibility */
+
+int tor_open_cloexec(const char *path, int flags, unsigned mode);
+
int replace_file(const char *from, const char *to);
int touch_file(const char *fname);
diff --git a/src/common/util.c b/src/common/util.c
index 16e7370..efa0335 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1814,7 +1814,7 @@ start_writing_to_file(const char *fname, int open_flags, int mode,
if (open_flags & O_BINARY)
new_file->binary = 1;
- new_file->fd = open(open_name, open_flags, mode);
+ new_file->fd = tor_open_cloexec(open_name, open_flags, mode);
if (new_file->fd < 0) {
log_warn(LD_FS, "Couldn't open \"%s\" (%s) for writing: %s",
open_name, fname, strerror(errno));
@@ -2035,7 +2035,7 @@ read_file_to_str(const char *filename, int flags, struct stat *stat_out)
tor_assert(filename);
- fd = open(filename,O_RDONLY|(bin?O_BINARY:O_TEXT),0);
+ fd = tor_open_cloexec(filename,O_RDONLY|(bin?O_BINARY:O_TEXT),0);
if (fd<0) {
int severity = LOG_WARN;
int save_errno = errno;
@@ -2735,7 +2735,7 @@ finish_daemon(const char *desired_cwd)
exit(1);
}
- nullfd = open("/dev/null", O_RDWR);
+ nullfd = tor_open_cloexec("/dev/null", O_RDWR, 0);
if (nullfd < 0) {
log_err(LD_GENERAL,"/dev/null can't be opened. Exiting.");
exit(1);
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index c0329b9..4e988bd 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -1752,10 +1752,10 @@ get_pf_socket(void)
#ifdef OPENBSD
/* only works on OpenBSD */
- pf = open("/dev/pf", O_RDONLY);
+ pf = tor_open_cloexec("/dev/pf", O_RDONLY, 0);
#else
/* works on NetBSD and FreeBSD */
- pf = open("/dev/pf", O_RDWR);
+ pf = tor_open_cloexec("/dev/pf", O_RDWR, 0);
#endif
if (pf < 0) {
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index b929303..0665cf5 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -3035,7 +3035,7 @@ evdns_resolv_conf_parse(int flags, const char *const filename) {
log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
- fd = open(filename, O_RDONLY);
+ fd = tor_open_cloexec(filename, O_RDONLY, 0);
if (fd < 0) {
evdns_resolv_set_defaults(flags);
return 1;
--
1.7.1