From f622f6696c3b3a5fc8ffc39c4d5db2322c78c7c2 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Sun, 21 Sep 2014 01:40:36 +0200 Subject: [PATCH] use force_close() on server to avoid descriptor leaks --- src/common.h | 11 +++++++++++ src/main-ctl-unix.c | 4 ++-- src/main-misc.c | 14 +++++++------- src/main.c | 28 ++++++++++++++-------------- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/common.h b/src/common.h index 494bec96..e17e9089 100644 --- a/src/common.h +++ b/src/common.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include 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); diff --git a/src/main-ctl-unix.c b/src/main-ctl-unix.c index ae117576..7e684c46 100644 --- a/src/main-ctl-unix.c +++ b/src/main-ctl-unix.c @@ -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) diff --git a/src/main-misc.c b/src/main-misc.c index 03ee3fb9..b5cfa4c6 100644 --- a/src/main-misc.c +++ b/src/main-misc.c @@ -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; diff --git a/src/main.c b/src/main.c index 84699dc9..d7b589bf 100644 --- a/src/main.c +++ b/src/main.c @@ -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(<mp->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);