From 2d7d6581b4ac7d3cfaff415c1abf1dbc4027b479 Mon Sep 17 00:00:00 2001 From: Neil Cook Date: Mon, 31 Jul 2017 22:48:09 +0100 Subject: [PATCH 1/2] Ensure netreq->fd is set to -1 after close()/closesocket() If netreq->fd is not set to -1, then multiple functions close the same socket. This causes major issues in multithread code where the socket must not be closed multiple times as it may be owned by a different thread. --- src/stub.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/stub.c b/src/stub.c index c6f25c79..2bff7ae9 100644 --- a/src/stub.c +++ b/src/stub.c @@ -588,6 +588,7 @@ _getdns_cancel_stub_request(getdns_network_req *netreq) #else close(netreq->fd); #endif + netreq->fd = -1; } } @@ -606,6 +607,7 @@ stub_timeout_cb(void *userarg) #else close(netreq->fd); #endif + netreq->fd = -1; netreq->upstream->udp_timeouts++; if (netreq->upstream->udp_timeouts % 100 == 0) _getdns_upstream_log(netreq->upstream, GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG, @@ -1413,6 +1415,7 @@ stub_udp_read_cb(void *userarg) #else close(netreq->fd); #endif + netreq->fd = -1; stub_next_upstream(netreq); } netreq->debug_end_time = _getdns_get_time_as_uintt64(); @@ -1435,8 +1438,8 @@ stub_udp_read_cb(void *userarg) closesocket(netreq->fd); #else close(netreq->fd); - netreq->fd = -1; #endif + netreq->fd = -1; while (GLDNS_TC_WIRE(netreq->response)) { DEBUG_STUB("%s %-35s: MSG: %p TC bit set in response \n", STUB_DEBUG_READ, __FUNC__, (void*)netreq); @@ -1533,6 +1536,7 @@ stub_udp_write_cb(void *userarg) #else close(netreq->fd); #endif + netreq->fd = -1; stub_next_upstream(netreq); } netreq->debug_end_time = _getdns_get_time_as_uintt64(); From 1555c432f5e637ef16b95e1ab7dd5e7adfaff13b Mon Sep 17 00:00:00 2001 From: Neil Cook Date: Mon, 31 Jul 2017 22:51:24 +0100 Subject: [PATCH 2/2] Fix array bounds bug in upstream_select --- src/stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stub.c b/src/stub.c index 2bff7ae9..b8ac6710 100644 --- a/src/stub.c +++ b/src/stub.c @@ -1962,7 +1962,7 @@ upstream_select(getdns_network_req *netreq) return &upstreams->upstreams[i]; } i+=GETDNS_UPSTREAM_TRANSPORTS; - if (i > upstreams->count) + if (i >= upstreams->count) i = 0; } while (i != upstreams->current_udp);