mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Check return values from fcntl and setsockopt
(Based on a patch from flupzor; bug #8206)
This commit is contained in:
parent
eb9420082d
commit
63b67577d6
6
changes/bug6206
Normal file
6
changes/bug6206
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
o Minor bugfixes:
|
||||||
|
- Always check the return values of functions fcntl() and
|
||||||
|
setsockopt(). We don't believe these are ever actually failing in
|
||||||
|
practice, but better safe than sorry. Also, checking these return
|
||||||
|
values should please some analysis tools (like Coverity). Patch
|
||||||
|
from 'flupzor'. Fix for bug 8206; bugfix on all versions of Tor.
|
@ -137,8 +137,13 @@ tor_open_cloexec(const char *path, int flags, unsigned mode)
|
|||||||
|
|
||||||
fd = open(path, flags, mode);
|
fd = open(path, flags, mode);
|
||||||
#ifdef FD_CLOEXEC
|
#ifdef FD_CLOEXEC
|
||||||
if (fd >= 0)
|
if (fd >= 0) {
|
||||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
|
||||||
|
log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -150,8 +155,13 @@ tor_fopen_cloexec(const char *path, const char *mode)
|
|||||||
{
|
{
|
||||||
FILE *result = fopen(path, mode);
|
FILE *result = fopen(path, mode);
|
||||||
#ifdef FD_CLOEXEC
|
#ifdef FD_CLOEXEC
|
||||||
if (result != NULL)
|
if (result != NULL) {
|
||||||
fcntl(fileno(result), F_SETFD, FD_CLOEXEC);
|
if (fcntl(fileno(result), F_SETFD, FD_CLOEXEC) == -1) {
|
||||||
|
log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno));
|
||||||
|
fclose(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1024,7 +1034,15 @@ tor_open_socket(int domain, int type, int protocol)
|
|||||||
return s;
|
return s;
|
||||||
|
|
||||||
#if defined(FD_CLOEXEC)
|
#if defined(FD_CLOEXEC)
|
||||||
fcntl(s, F_SETFD, FD_CLOEXEC);
|
if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
|
||||||
|
log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno));
|
||||||
|
#if defined(_WIN32)
|
||||||
|
closesocket(s);
|
||||||
|
#else
|
||||||
|
close(s);
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
goto socket_ok; /* So that socket_ok will not be unused. */
|
goto socket_ok; /* So that socket_ok will not be unused. */
|
||||||
@ -1059,7 +1077,11 @@ tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len)
|
|||||||
return s;
|
return s;
|
||||||
|
|
||||||
#if defined(FD_CLOEXEC)
|
#if defined(FD_CLOEXEC)
|
||||||
fcntl(s, F_SETFD, FD_CLOEXEC);
|
if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
|
||||||
|
log_warn(LD_NET, "Couldn't set FD_CLOEXEC: %s", strerror(errno));
|
||||||
|
close(s);
|
||||||
|
return TOR_INVALID_SOCKET;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
goto socket_ok; /* So that socket_ok will not be unused. */
|
goto socket_ok; /* So that socket_ok will not be unused. */
|
||||||
@ -1083,17 +1105,31 @@ get_n_open_sockets(void)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Turn <b>socket</b> into a nonblocking socket.
|
/** Turn <b>socket</b> into a nonblocking socket. Return 0 on success, -1
|
||||||
|
* on failure.
|
||||||
*/
|
*/
|
||||||
void
|
int
|
||||||
set_socket_nonblocking(tor_socket_t socket)
|
set_socket_nonblocking(tor_socket_t socket)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
unsigned long nonblocking = 1;
|
unsigned long nonblocking = 1;
|
||||||
ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
|
ioctlsocket(socket, FIONBIO, (unsigned long*) &nonblocking);
|
||||||
#else
|
#else
|
||||||
fcntl(socket, F_SETFL, O_NONBLOCK);
|
int flags;
|
||||||
|
|
||||||
|
flags = fcntl(socket, F_GETFL, 0);
|
||||||
|
if (flags == -1) {
|
||||||
|
log_warn(LD_NET, "Couldn't get file status flags: %s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
flags |= O_NONBLOCK;
|
||||||
|
if (fcntl(socket, F_SETFL, flags) == -1) {
|
||||||
|
log_warn(LD_NET, "Couldn't set file status flags: %s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -518,7 +518,7 @@ int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2));
|
|||||||
const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
|
const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
|
||||||
int tor_inet_pton(int af, const char *src, void *dst);
|
int tor_inet_pton(int af, const char *src, void *dst);
|
||||||
int tor_lookup_hostname(const char *name, uint32_t *addr) ATTR_NONNULL((1,2));
|
int tor_lookup_hostname(const char *name, uint32_t *addr) ATTR_NONNULL((1,2));
|
||||||
void set_socket_nonblocking(tor_socket_t socket);
|
int set_socket_nonblocking(tor_socket_t socket);
|
||||||
int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]);
|
int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]);
|
||||||
int network_init(void);
|
int network_init(void);
|
||||||
|
|
||||||
|
@ -2275,6 +2275,7 @@ _evdns_nameserver_add_impl(const struct sockaddr *address,
|
|||||||
|
|
||||||
const struct nameserver *server = server_head, *const started_at = server_head;
|
const struct nameserver *server = server_head, *const started_at = server_head;
|
||||||
struct nameserver *ns;
|
struct nameserver *ns;
|
||||||
|
int flags;
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if (server) {
|
if (server) {
|
||||||
@ -2306,7 +2307,12 @@ _evdns_nameserver_add_impl(const struct sockaddr *address,
|
|||||||
ioctlsocket(ns->socket, FIONBIO, &nonblocking);
|
ioctlsocket(ns->socket, FIONBIO, &nonblocking);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
fcntl(ns->socket, F_SETFL, O_NONBLOCK);
|
if (fcntl(ns->socket, F_SETFL, O_NONBLOCK) == -1) {
|
||||||
|
evdns_log(EVDNS_LOG_WARN, "Error %s (%d) while settings file status flags.",
|
||||||
|
tor_socket_strerror(errno), errno);
|
||||||
|
err = 2;
|
||||||
|
goto out2;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (global_bind_addr_is_set &&
|
if (global_bind_addr_is_set &&
|
||||||
|
@ -918,8 +918,11 @@ make_socket_reuseable(tor_socket_t sock)
|
|||||||
* right after somebody else has let it go. But REUSEADDR on win32
|
* right after somebody else has let it go. But REUSEADDR on win32
|
||||||
* means you can bind to the port _even when somebody else
|
* means you can bind to the port _even when somebody else
|
||||||
* already has it bound_. So, don't do that on Win32. */
|
* already has it bound_. So, don't do that on Win32. */
|
||||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
|
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
|
||||||
(socklen_t)sizeof(one));
|
(socklen_t)sizeof(one)) == -1) {
|
||||||
|
log_warn(LD_NET, "Error setting SO_REUSEADDR flag: %s",
|
||||||
|
tor_socket_strerror(errno));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1102,7 +1105,10 @@ connection_listener_new(const struct sockaddr *listensockaddr,
|
|||||||
tor_assert(0);
|
tor_assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_socket_nonblocking(s);
|
if (set_socket_nonblocking(s) == -1) {
|
||||||
|
tor_close_socket(s);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
lis_conn = listener_connection_new(type, listensockaddr->sa_family);
|
lis_conn = listener_connection_new(type, listensockaddr->sa_family);
|
||||||
conn = TO_CONN(lis_conn);
|
conn = TO_CONN(lis_conn);
|
||||||
@ -1265,7 +1271,10 @@ connection_handle_listener_read(connection_t *conn, int new_type)
|
|||||||
(int)news,(int)conn->s);
|
(int)news,(int)conn->s);
|
||||||
|
|
||||||
make_socket_reuseable(news);
|
make_socket_reuseable(news);
|
||||||
set_socket_nonblocking(news);
|
if (set_socket_nonblocking(news) == -1) {
|
||||||
|
tor_close_socket(news);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (options->ConstrainedSockets)
|
if (options->ConstrainedSockets)
|
||||||
set_constrained_socket_buffers(news, (int)options->ConstrainedSockSize);
|
set_constrained_socket_buffers(news, (int)options->ConstrainedSockSize);
|
||||||
@ -1494,7 +1503,11 @@ connection_connect(connection_t *conn, const char *address,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_socket_nonblocking(s);
|
if (set_socket_nonblocking(s) == -1) {
|
||||||
|
*socket_error = tor_socket_errno(s);
|
||||||
|
tor_close_socket(s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (options->ConstrainedSockets)
|
if (options->ConstrainedSockets)
|
||||||
set_constrained_socket_buffers(s, (int)options->ConstrainedSockSize);
|
set_constrained_socket_buffers(s, (int)options->ConstrainedSockSize);
|
||||||
|
@ -535,13 +535,16 @@ spawn_cpuworker(void)
|
|||||||
|
|
||||||
conn = connection_new(CONN_TYPE_CPUWORKER, AF_UNIX);
|
conn = connection_new(CONN_TYPE_CPUWORKER, AF_UNIX);
|
||||||
|
|
||||||
set_socket_nonblocking(fd);
|
|
||||||
|
|
||||||
/* set up conn so it's got all the data we need to remember */
|
/* set up conn so it's got all the data we need to remember */
|
||||||
conn->s = fd;
|
conn->s = fd;
|
||||||
conn->address = tor_strdup("localhost");
|
conn->address = tor_strdup("localhost");
|
||||||
tor_addr_make_unspec(&conn->addr);
|
tor_addr_make_unspec(&conn->addr);
|
||||||
|
|
||||||
|
if (set_socket_nonblocking(fd) == -1) {
|
||||||
|
connection_free(conn); /* this closes fd */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (connection_add(conn) < 0) { /* no space, forget it */
|
if (connection_add(conn) < 0) { /* no space, forget it */
|
||||||
log_warn(LD_NET,"connection_add for cpuworker failed. Giving up.");
|
log_warn(LD_NET,"connection_add for cpuworker failed. Giving up.");
|
||||||
connection_free(conn); /* this closes fd */
|
connection_free(conn); /* this closes fd */
|
||||||
|
Loading…
Reference in New Issue
Block a user