diff options
author | Nick Mathewson <nickm@torproject.org> | 2010-12-01 11:42:34 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2010-12-01 11:42:34 -0500 |
commit | 9908404f0189aad3917960ba63661079e546f150 (patch) | |
tree | 58e8d682c2945a55071580b053f24d3999bd641c /src | |
parent | fa1a4196225bcdc787342ee6f60c4f6ccdfe1879 (diff) | |
parent | a961521a86c439ab2ba1073daa6392a069903db1 (diff) | |
download | tor-9908404f0189aad3917960ba63661079e546f150.tar.gz tor-9908404f0189aad3917960ba63661079e546f150.zip |
Merge remote branch 'sjmurdoch/cloexec'
Diffstat (limited to 'src')
-rw-r--r-- | src/common/compat.c | 63 | ||||
-rw-r--r-- | src/common/compat.h | 5 | ||||
-rw-r--r-- | src/common/log.c | 2 | ||||
-rw-r--r-- | src/common/util.c | 21 | ||||
-rw-r--r-- | src/or/connection_edge.c | 4 | ||||
-rw-r--r-- | src/or/dirserv.c | 2 | ||||
-rw-r--r-- | src/or/eventdns.c | 6 | ||||
-rw-r--r-- | src/or/geoip.c | 2 |
8 files changed, 86 insertions, 19 deletions
diff --git a/src/common/compat.c b/src/common/compat.c index 0ebad62de3..d442294e83 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -101,6 +101,35 @@ #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(fd, F_SETFD, FD_CLOEXEC); +#endif + return fd; +#endif +} + +/** DOCDOC */ +FILE * +tor_fopen_cloexec(const char *path, const char *mode) +{ + FILE *result = fopen(path, mode); +#ifdef FD_CLOEXEC + if (result != NULL) + fcntl(fileno(result), F_SETFD, FD_CLOEXEC); +#endif + return result; +} + #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 +145,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 +714,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 +933,16 @@ 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 +#define LINUX_CLOEXEC_OPEN_SOCKET + type |= SOCK_CLOEXEC; +#endif + s = socket(domain, type, protocol); if (s >= 0) { +#if !defined(LINUX_CLOEXEC_OPEN_SOCKET) && defined(FD_CLOEXEC) + fcntl(s, F_SETFD, FD_CLOEXEC); +#endif socket_accounting_lock(); ++n_sockets_open; mark_socket_open(s); @@ -918,8 +955,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); @@ -975,8 +1021,17 @@ tor_socketpair(int family, int type, int protocol, int fd[2]) //don't use win32 socketpairs (they are always bad) #if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS) int r; +#ifdef SOCK_CLOEXEC + type |= SOCK_CLOEXEC; +#endif r = socketpair(family, type, protocol, fd); if (r == 0) { +#if !defined(SOCK_CLOEXEC) && defined(FD_CLOEXEC) + if (fd[0] >= 0) + fcntl(fd[0], F_SETFD, FD_CLOEXEC); + if (fd[1] >= 0) + fcntl(fd[1], F_SETFD, FD_CLOEXEC); +#endif socket_accounting_lock(); if (fd[0] >= 0) { ++n_sockets_open; diff --git a/src/common/compat.h b/src/common/compat.h index 38e0f99ba9..590da949c0 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -51,6 +51,8 @@ #include <netinet6/in6.h> #endif +#include <stdio.h> + #if defined (WINCE) #include <fcntl.h> #include <io.h> @@ -340,6 +342,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); +FILE *tor_fopen_cloexec(const char *path, const char *mode); + int replace_file(const char *from, const char *to); int touch_file(const char *fname); diff --git a/src/common/log.c b/src/common/log.c index e507275830..6f86406c2c 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -686,7 +686,7 @@ add_file_log(const log_severity_list_t *severity, const char *filename) int fd; logfile_t *lf; - fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0644); + fd = tor_open_cloexec(filename, O_WRONLY|O_CREAT|O_APPEND, 0644); if (fd<0) return -1; if (tor_fd_seekend(fd)<0) diff --git a/src/common/util.c b/src/common/util.c index 16e7370239..421da3560c 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); @@ -2986,7 +2986,7 @@ tor_spawn_background(const char *const filename, int *stdout_read, child_state = CHILD_STATE_REDIRECT; /* Link stdin to /dev/null */ - fd = open("/dev/null", O_RDONLY); + fd = open("/dev/null", O_RDONLY); /* NOT cloexec, obviously. */ if (fd != -1) dup2(STDIN_FILENO, fd); else @@ -2994,11 +2994,18 @@ tor_spawn_background(const char *const filename, int *stdout_read, child_state = CHILD_STATE_CLOSEFD; + close(stderr_pipe[0]); + close(stderr_pipe[1]); + close(stdout_pipe[0]); + close(stdout_pipe[1]); + close(fd); + /* Close all other fds, including the read end of the pipe */ - /* XXX: use closefrom if available, or better still set FD_CLOEXEC - on all of Tor's open files */ - for (fd = STDERR_FILENO + 1; fd < max_fd; fd++) + /* XXX: We should now be doing enough FD_CLOEXEC setting to make + * this needless. */ + for (fd = STDERR_FILENO + 1; fd < max_fd; fd++) { close(fd); + } child_state = CHILD_STATE_EXEC; 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/dirserv.c b/src/or/dirserv.c index a394bf62e2..edba9fbd8a 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -2446,7 +2446,7 @@ dirserv_read_measured_bandwidths(const char *from_file, smartlist_t *routerstatuses) { char line[256]; - FILE *fp = fopen(from_file, "r"); + FILE *fp = tor_fopen_cloexec(from_file, "r"); int applied_lines = 0; time_t file_time; int ok; diff --git a/src/or/eventdns.c b/src/or/eventdns.c index b929303fd5..4c6f60e89d 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -2286,7 +2286,7 @@ _evdns_nameserver_add_impl(const struct sockaddr *address, evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns); - ns->socket = socket(PF_INET, SOCK_DGRAM, 0); + ns->socket = tor_open_socket(PF_INET, SOCK_DGRAM, 0); if (ns->socket < 0) { err = 1; goto out1; } #ifdef WIN32 { @@ -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; @@ -3455,7 +3455,7 @@ main(int c, char **v) { if (servertest) { int sock; struct sockaddr_in my_addr; - sock = socket(PF_INET, SOCK_DGRAM, 0); + sock = tor_open_socket(PF_INET, SOCK_DGRAM, 0); fcntl(sock, F_SETFL, O_NONBLOCK); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(10053); diff --git a/src/or/geoip.c b/src/or/geoip.c index ae0776a571..84681821b0 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -206,7 +206,7 @@ geoip_load_file(const char *filename, or_options_t *options) int severity = options_need_geoip_info(options, &msg) ? LOG_WARN : LOG_INFO; crypto_digest_env_t *geoip_digest_env = NULL; clear_geoip_db(); - if (!(f = fopen(filename, "r"))) { + if (!(f = tor_fopen_cloexec(filename, "r"))) { log_fn(severity, LD_GENERAL, "Failed to open GEOIP file %s. %s", filename, msg); return -1; |