diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/compat.c | 41 | ||||
-rw-r--r-- | src/common/compat.h | 3 | ||||
-rw-r--r-- | src/common/util.c | 6 | ||||
-rw-r--r-- | src/or/connection_edge.c | 4 | ||||
-rw-r--r-- | src/or/eventdns.c | 2 |
5 files changed, 46 insertions, 10 deletions
diff --git a/src/common/compat.c b/src/common/compat.c index b7f4f17cae..e3a76e8dfa 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 2471e6b830..9eaf77a1d7 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 16e7370239..efa0335012 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 c0329b9d7a..4e988bd04c 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 b929303fd5..0665cf53ec 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; |