mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-03 00:53:32 +01:00
Merge remote branch 'sjmurdoch/cloexec'
This commit is contained in:
commit
9908404f01
@ -250,6 +250,7 @@ dnl Check for functions before libevent, since libevent-1.2 apparently
|
|||||||
dnl exports strlcpy without defining it in a header.
|
dnl exports strlcpy without defining it in a header.
|
||||||
|
|
||||||
AC_CHECK_FUNCS(
|
AC_CHECK_FUNCS(
|
||||||
|
accept4 \
|
||||||
flock \
|
flock \
|
||||||
ftime \
|
ftime \
|
||||||
getaddrinfo \
|
getaddrinfo \
|
||||||
|
@ -101,6 +101,35 @@
|
|||||||
#include "strlcat.c"
|
#include "strlcat.c"
|
||||||
#endif
|
#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
|
#ifdef HAVE_SYS_MMAN_H
|
||||||
/** Try to create a memory mapping for <b>filename</b> and return it. On
|
/** Try to create a memory mapping for <b>filename</b> and return it. On
|
||||||
* failure, return NULL. Sets errno properly, using ERANGE to mean
|
* failure, return NULL. Sets errno properly, using ERANGE to mean
|
||||||
@ -116,7 +145,7 @@ tor_mmap_file(const char *filename)
|
|||||||
|
|
||||||
tor_assert(filename);
|
tor_assert(filename);
|
||||||
|
|
||||||
fd = open(filename, O_RDONLY, 0);
|
fd = tor_open_cloexec(filename, O_RDONLY, 0);
|
||||||
if (fd<0) {
|
if (fd<0) {
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
int severity = (errno == ENOENT) ? LOG_INFO : LOG_WARN;
|
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;
|
*locked_out = 0;
|
||||||
|
|
||||||
log_info(LD_FS, "Locking \"%s\"", filename);
|
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) {
|
if (fd < 0) {
|
||||||
log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
|
log_warn(LD_FS,"Couldn't open \"%s\" for locking: %s", filename,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@ -904,8 +933,16 @@ mark_socket_open(int s)
|
|||||||
int
|
int
|
||||||
tor_open_socket(int domain, int type, int protocol)
|
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 (s >= 0) {
|
||||||
|
#if !defined(LINUX_CLOEXEC_OPEN_SOCKET) && defined(FD_CLOEXEC)
|
||||||
|
fcntl(s, F_SETFD, FD_CLOEXEC);
|
||||||
|
#endif
|
||||||
socket_accounting_lock();
|
socket_accounting_lock();
|
||||||
++n_sockets_open;
|
++n_sockets_open;
|
||||||
mark_socket_open(s);
|
mark_socket_open(s);
|
||||||
@ -918,8 +955,17 @@ tor_open_socket(int domain, int type, int protocol)
|
|||||||
int
|
int
|
||||||
tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len)
|
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 (s >= 0) {
|
||||||
|
#if !defined(LINUX_CLOEXEC_ACCEPT) && defined(FD_CLOEXEC)
|
||||||
|
fcntl(s, F_SETFD, FD_CLOEXEC);
|
||||||
|
#endif
|
||||||
socket_accounting_lock();
|
socket_accounting_lock();
|
||||||
++n_sockets_open;
|
++n_sockets_open;
|
||||||
mark_socket_open(s);
|
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)
|
//don't use win32 socketpairs (they are always bad)
|
||||||
#if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS)
|
#if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS)
|
||||||
int r;
|
int r;
|
||||||
|
#ifdef SOCK_CLOEXEC
|
||||||
|
type |= SOCK_CLOEXEC;
|
||||||
|
#endif
|
||||||
r = socketpair(family, type, protocol, fd);
|
r = socketpair(family, type, protocol, fd);
|
||||||
if (r == 0) {
|
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();
|
socket_accounting_lock();
|
||||||
if (fd[0] >= 0) {
|
if (fd[0] >= 0) {
|
||||||
++n_sockets_open;
|
++n_sockets_open;
|
||||||
|
@ -51,6 +51,8 @@
|
|||||||
#include <netinet6/in6.h>
|
#include <netinet6/in6.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined (WINCE)
|
#if defined (WINCE)
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <io.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))
|
((tvp)->tv_sec cmp (uvp)->tv_sec))
|
||||||
|
|
||||||
/* ===== File compatibility */
|
/* ===== 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 replace_file(const char *from, const char *to);
|
||||||
int touch_file(const char *fname);
|
int touch_file(const char *fname);
|
||||||
|
|
||||||
|
@ -686,7 +686,7 @@ add_file_log(const log_severity_list_t *severity, const char *filename)
|
|||||||
int fd;
|
int fd;
|
||||||
logfile_t *lf;
|
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)
|
if (fd<0)
|
||||||
return -1;
|
return -1;
|
||||||
if (tor_fd_seekend(fd)<0)
|
if (tor_fd_seekend(fd)<0)
|
||||||
|
@ -1814,7 +1814,7 @@ start_writing_to_file(const char *fname, int open_flags, int mode,
|
|||||||
if (open_flags & O_BINARY)
|
if (open_flags & O_BINARY)
|
||||||
new_file->binary = 1;
|
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) {
|
if (new_file->fd < 0) {
|
||||||
log_warn(LD_FS, "Couldn't open \"%s\" (%s) for writing: %s",
|
log_warn(LD_FS, "Couldn't open \"%s\" (%s) for writing: %s",
|
||||||
open_name, fname, strerror(errno));
|
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);
|
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) {
|
if (fd<0) {
|
||||||
int severity = LOG_WARN;
|
int severity = LOG_WARN;
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
@ -2735,7 +2735,7 @@ finish_daemon(const char *desired_cwd)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
nullfd = open("/dev/null", O_RDWR);
|
nullfd = tor_open_cloexec("/dev/null", O_RDWR, 0);
|
||||||
if (nullfd < 0) {
|
if (nullfd < 0) {
|
||||||
log_err(LD_GENERAL,"/dev/null can't be opened. Exiting.");
|
log_err(LD_GENERAL,"/dev/null can't be opened. Exiting.");
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -2986,7 +2986,7 @@ tor_spawn_background(const char *const filename, int *stdout_read,
|
|||||||
child_state = CHILD_STATE_REDIRECT;
|
child_state = CHILD_STATE_REDIRECT;
|
||||||
|
|
||||||
/* Link stdin to /dev/null */
|
/* Link stdin to /dev/null */
|
||||||
fd = open("/dev/null", O_RDONLY);
|
fd = open("/dev/null", O_RDONLY); /* NOT cloexec, obviously. */
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
dup2(STDIN_FILENO, fd);
|
dup2(STDIN_FILENO, fd);
|
||||||
else
|
else
|
||||||
@ -2994,12 +2994,19 @@ tor_spawn_background(const char *const filename, int *stdout_read,
|
|||||||
|
|
||||||
child_state = CHILD_STATE_CLOSEFD;
|
child_state = CHILD_STATE_CLOSEFD;
|
||||||
|
|
||||||
/* Close all other fds, including the read end of the pipe */
|
close(stderr_pipe[0]);
|
||||||
/* XXX: use closefrom if available, or better still set FD_CLOEXEC
|
close(stderr_pipe[1]);
|
||||||
on all of Tor's open files */
|
close(stdout_pipe[0]);
|
||||||
for (fd = STDERR_FILENO + 1; fd < max_fd; fd++)
|
close(stdout_pipe[1]);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
/* Close all other fds, including the read end of the pipe */
|
||||||
|
/* 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;
|
child_state = CHILD_STATE_EXEC;
|
||||||
|
|
||||||
/* Call the requested program. We need the cast because
|
/* Call the requested program. We need the cast because
|
||||||
|
@ -1752,10 +1752,10 @@ get_pf_socket(void)
|
|||||||
|
|
||||||
#ifdef OPENBSD
|
#ifdef OPENBSD
|
||||||
/* only works on OpenBSD */
|
/* only works on OpenBSD */
|
||||||
pf = open("/dev/pf", O_RDONLY);
|
pf = tor_open_cloexec("/dev/pf", O_RDONLY, 0);
|
||||||
#else
|
#else
|
||||||
/* works on NetBSD and FreeBSD */
|
/* works on NetBSD and FreeBSD */
|
||||||
pf = open("/dev/pf", O_RDWR);
|
pf = tor_open_cloexec("/dev/pf", O_RDWR, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (pf < 0) {
|
if (pf < 0) {
|
||||||
|
@ -2446,7 +2446,7 @@ dirserv_read_measured_bandwidths(const char *from_file,
|
|||||||
smartlist_t *routerstatuses)
|
smartlist_t *routerstatuses)
|
||||||
{
|
{
|
||||||
char line[256];
|
char line[256];
|
||||||
FILE *fp = fopen(from_file, "r");
|
FILE *fp = tor_fopen_cloexec(from_file, "r");
|
||||||
int applied_lines = 0;
|
int applied_lines = 0;
|
||||||
time_t file_time;
|
time_t file_time;
|
||||||
int ok;
|
int ok;
|
||||||
|
@ -2286,7 +2286,7 @@ _evdns_nameserver_add_impl(const struct sockaddr *address,
|
|||||||
|
|
||||||
evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
|
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; }
|
if (ns->socket < 0) { err = 1; goto out1; }
|
||||||
#ifdef WIN32
|
#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);
|
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) {
|
if (fd < 0) {
|
||||||
evdns_resolv_set_defaults(flags);
|
evdns_resolv_set_defaults(flags);
|
||||||
return 1;
|
return 1;
|
||||||
@ -3455,7 +3455,7 @@ main(int c, char **v) {
|
|||||||
if (servertest) {
|
if (servertest) {
|
||||||
int sock;
|
int sock;
|
||||||
struct sockaddr_in my_addr;
|
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);
|
fcntl(sock, F_SETFL, O_NONBLOCK);
|
||||||
my_addr.sin_family = AF_INET;
|
my_addr.sin_family = AF_INET;
|
||||||
my_addr.sin_port = htons(10053);
|
my_addr.sin_port = htons(10053);
|
||||||
|
@ -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;
|
int severity = options_need_geoip_info(options, &msg) ? LOG_WARN : LOG_INFO;
|
||||||
crypto_digest_env_t *geoip_digest_env = NULL;
|
crypto_digest_env_t *geoip_digest_env = NULL;
|
||||||
clear_geoip_db();
|
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",
|
log_fn(severity, LD_GENERAL, "Failed to open GEOIP file %s. %s",
|
||||||
filename, msg);
|
filename, msg);
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user