From e3159409c0edb56f5dc00df41f9525f568eeeb8d Mon Sep 17 00:00:00 2001 From: Yves Rutschle Date: Thu, 25 Jul 2013 21:35:27 +0200 Subject: [PATCH] check fd < FD_SETSIZE --- ChangeLog | 4 ++++ sslh-select.c | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 048e132..653beaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,10 @@ vNEXT: See README for iptables magic and capability management. + Fixed bug in sslh-select: if number of opened file + descriptor became bigger than FD_SETSIZE, bad things + would happen. + Fixed bug in sslh-select: if socket dropped while defered_data was present, sslh-select would crash. diff --git a/sslh-select.c b/sslh-select.c index 3c12a64..14b3716 100644 --- a/sslh-select.c +++ b/sslh-select.c @@ -72,6 +72,16 @@ int tidy_connection(struct connection *cnx, fd_set *fds, fd_set *fds2) return 0; } +/* if fd becomes higher than FD_SETSIZE, things won't work so well with FD_SET + * and FD_CLR. Need to drop connections if we go above that limit */ +int fd_is_in_range(int fd) { + if (fd >= FD_SETSIZE) { + log_message(LOG_ERR, "too many open file descriptor to monitor them all -- dropping connection\n"); + return 0; + } + return 1; +} + /* Accepts a connection from the main socket and assigns it to an empty slot. * If no slots are available, allocate another few. If that fails, drop the * connexion */ @@ -83,6 +93,9 @@ int accept_new_connection(int listen_socket, struct connection *cnx[], int* cnx_ in_socket = accept(listen_socket, 0, 0); CHECK_RES_RETURN(in_socket, "accept"); + if (!fd_is_in_range(in_socket)) + return -1; + res = set_nonblock(in_socket); if (res == -1) return -1; @@ -123,7 +136,7 @@ int connect_queue(struct connection *cnx, struct addrinfo *addr, struct queue *q = &cnx->q[1]; q->fd = connect_addr(addr, cnx->q[0].fd, cnx_name); - if (q->fd != -1) { + if ((q->fd != -1) && fd_is_in_range(q->fd)) { log_connection(cnx); set_nonblock(q->fd); flush_defered(q);