use force_close() on server to avoid descriptor leaks

This commit is contained in:
Nikos Mavrogiannopoulos
2014-09-21 01:40:36 +02:00
parent a8b32ed8f0
commit f622f6696c
4 changed files with 34 additions and 23 deletions

View File

@@ -24,6 +24,8 @@
#include <sys/socket.h>
#include <ipc.pb-c.h>
#include <talloc.h>
#include <unistd.h>
#include <errno.h>
void _talloc_free2(void *ctx, void *ptr);
void *_talloc_size2(void *ctx, size_t size);
@@ -31,6 +33,15 @@ void *_talloc_size2(void *ctx, size_t size);
#define PROTOBUF_ALLOCATOR(name, pool) \
ProtobufCAllocator name = {.alloc = _talloc_size2, .free = _talloc_free2, .allocator_data = pool}
inline static
void force_close(int fd)
{
int ret;
do {
ret = close(fd);
} while(ret == -1 && errno != EBADF);
}
ssize_t force_write(int sockfd, const void *buf, size_t len);
ssize_t force_read(int sockfd, void *buf, size_t len);
ssize_t force_read_timeout(int sockfd, void *buf, size_t len, unsigned sec);

View File

@@ -89,7 +89,7 @@ void ctl_handler_deinit(main_server_st * s)
if (s->ctl_fd >= 0) {
/*mslog(s, NULL, LOG_DEBUG, "closing unix socket connection");*/
close(s->ctl_fd);
force_close(s->ctl_fd);
/*remove(OCSERV_UNIX_NAME); */
}
}
@@ -653,7 +653,7 @@ static void ctl_handle_commands(main_server_st * s)
cleanup:
talloc_free(pool);
if (cfd != -1)
close(cfd);
force_close(cfd);
}
int ctl_handler_set_fds(main_server_st * s, fd_set * rd_set, fd_set * wr_set)

View File

@@ -88,7 +88,7 @@ int set_tun_mtu(main_server_st * s, struct proc_st *proc, unsigned mtu)
ret = 0;
fail:
close(fd);
force_close(fd);
return ret;
}
@@ -129,7 +129,7 @@ int handle_script_exit(main_server_st *s, struct proc_st *proc, int code)
* it causes issues to client.
*/
if (proc->tun_lease.fd >= 0)
close(proc->tun_lease.fd);
force_close(proc->tun_lease.fd);
proc->tun_lease.fd = -1;
return ret;
@@ -189,7 +189,7 @@ int session_openclose(main_server_st * s, struct proc_st *proc, unsigned open)
s->secmod_addr_len);
if (ret < 0) {
e = errno;
close(sd);
force_close(sd);
mslog(s, proc, LOG_ERR,
"error connecting to sec-mod socket '%s': %s",
s->secmod_addr.sun_path, strerror(e));
@@ -205,7 +205,7 @@ int session_openclose(main_server_st * s, struct proc_st *proc, unsigned open)
&ireq, (pack_size_func)sec_auth_session_msg__get_packed_size,
(pack_func)sec_auth_session_msg__pack);
if (ret < 0) {
close(sd);
force_close(sd);
mslog(s, proc, LOG_ERR,
"error sending message to sec-mod socket '%s'",
s->secmod_addr.sun_path);
@@ -215,7 +215,7 @@ int session_openclose(main_server_st * s, struct proc_st *proc, unsigned open)
if (open) {
ret = recv_msg(proc, sd, SM_CMD_AUTH_SESSION_REPLY,
(void *)&msg, (unpack_func) sec_auth_session_reply_msg__unpack);
close(sd);
force_close(sd);
if (ret < 0) {
mslog(s, proc, LOG_ERR, "error receiving auth reply message");
return ret;
@@ -226,7 +226,7 @@ int session_openclose(main_server_st * s, struct proc_st *proc, unsigned open)
return -1;
}
} else {
close(sd);
force_close(sd);
}
return 0;
@@ -255,7 +255,7 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k)
/* close the intercomm fd */
if (proc->fd >= 0)
close(proc->fd);
force_close(proc->fd);
proc->fd = -1;
proc->pid = -1;

View File

@@ -188,14 +188,14 @@ int _listen_ports(void *pool, struct cfg_st* config,
if (bind(s, ptr->ai_addr, ptr->ai_addrlen) < 0) {
perror("bind() failed");
close(s);
force_close(s);
continue;
}
if (ptr->ai_socktype == SOCK_STREAM) {
if (listen(s, 10) < 0) {
perror("listen() failed");
close(s);
force_close(s);
return -1;
}
}
@@ -368,7 +368,7 @@ int reopen_udp_port(struct listener_st *l)
{
int s, y, e;
close(l->fd);
force_close(l->fd);
l->fd = -1;
s = socket(l->family, l->socktype, l->protocol);
@@ -404,7 +404,7 @@ int s, y, e;
if (bind(s, (void*)&l->addr, l->addr_len) < 0) {
e = errno;
syslog(LOG_ERR, "bind() failed: %s", strerror(e));
close(s);
force_close(s);
return -1;
}
@@ -558,7 +558,7 @@ void clear_lists(main_server_st *s)
struct script_wait_st *script_tmp = NULL, *script_pos;
list_for_each_safe(&s->listen_list.head, ltmp, lpos, list) {
close(ltmp->fd);
force_close(ltmp->fd);
list_del(&ltmp->list);
talloc_free(ltmp);
s->listen_list.total--;
@@ -566,9 +566,9 @@ void clear_lists(main_server_st *s)
list_for_each_safe(&s->proc_list.head, ctmp, cpos, list) {
if (ctmp->fd >= 0)
close(ctmp->fd);
force_close(ctmp->fd);
if (ctmp->tun_lease.fd >= 0)
close(ctmp->tun_lease.fd);
force_close(ctmp->tun_lease.fd);
if (ctmp->cookie_ptr)
ctmp->cookie_ptr->proc = NULL;
list_del(&ctmp->list);
@@ -1051,13 +1051,13 @@ int main(int argc, char** argv)
set_cloexec_flag (fd, 1);
if (s->config->max_clients > 0 && s->active_clients >= s->config->max_clients) {
close(fd);
force_close(fd);
mslog(s, NULL, LOG_INFO, "Reached maximum client limit (active: %u)", s->active_clients);
break;
}
if (check_tcp_wrapper(fd) < 0) {
close(fd);
force_close(fd);
mslog(s, NULL, LOG_INFO, "TCP wrappers rejected the connection (see /etc/hosts->[allow|deny])");
break;
}
@@ -1066,7 +1066,7 @@ int main(int argc, char** argv)
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, cmd_fd);
if (ret < 0) {
mslog(s, NULL, LOG_ERR, "Error creating command socket");
close(fd);
force_close(fd);
break;
}
@@ -1076,7 +1076,7 @@ int main(int argc, char** argv)
* sensitive data before running the worker
*/
sigprocmask(SIG_SETMASK, &sig_default_set, NULL);
close(cmd_fd[0]);
force_close(cmd_fd[0]);
clear_lists(s);
/* clear the cookie key */
@@ -1115,7 +1115,7 @@ int main(int argc, char** argv)
exit(0);
} else if (pid == -1) {
fork_failed:
close(cmd_fd[0]);
force_close(cmd_fd[0]);
} else { /* parent */
/* add_proc */
ctmp = new_proc(s, pid, cmd_fd[0],
@@ -1127,8 +1127,8 @@ fork_failed:
}
}
close(cmd_fd[1]);
close(fd);
force_close(cmd_fd[1]);
force_close(fd);
if (s->config->rate_limit_ms > 0)
ms_sleep(s->config->rate_limit_ms);