From 87934b76a783a17577072a98e0e2eb7cadc1babd Mon Sep 17 00:00:00 2001 From: afanasyev Date: Mon, 9 Feb 2026 00:27:55 +0300 Subject: [PATCH] fix: critical bugs in DNS proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - main.c: fix NULL pointer dereference in https_resp_cb() — req was used before NULL check, and FLOG also dereferenced NULL req->tx_id - main.c: fix potential crash in get_host_from_uri() — strlen(host) was called before checking curl_url_get() return code, host could be NULL - dns_server_tcp.c: fix data corruption on EAGAIN — sent += len was executed with len == -1 when EAGAIN/EWOULDBLOCK occurred, causing negative offset; added continue to skip the addition - dns_server_tcp.c: fix format string mismatches in FLOG() calls — format had 2 specifiers but 4 arguments were passed (ipstr, port, strerror, errno); changed format to include all 4 arguments - dns_server_tcp.c: fix typo 'listaning' -> 'listening' - https_client.c: remove deprecated CURLPIPE_HTTP1 (since libcurl 7.62.0), keep only CURLPIPE_MULTIPLEX --- src/dns_server_tcp.c | 7 ++++--- src/https_client.c | 2 +- src/main.c | 20 +++++++++++--------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/dns_server_tcp.c b/src/dns_server_tcp.c index a533722..5696473 100644 --- a/src/dns_server_tcp.c +++ b/src/dns_server_tcp.c @@ -257,17 +257,17 @@ static int get_tcp_listen_sock(struct addrinfo *listen_addrinfo) { } if (listen(sock, LISTEN_BACKLOG) == -1) { - FLOG("Error listaning on %s:%d TCP: %s (%d)", ipstr, port, + FLOG("Error listening on %s:%d TCP: %s (%d)", ipstr, port, strerror(errno), errno); } int flags = fcntl(sock, F_GETFL, 0); if (flags == -1) { - FLOG("Error getting TCP socket flags: %s (%d)", ipstr, port, + FLOG("Error getting TCP socket flags on %s:%d: %s (%d)", ipstr, port, strerror(errno), errno); } if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) { - FLOG("Error setting TCP socket to non-blocking: %s (%d)", ipstr, port, + FLOG("Error setting TCP socket to non-blocking on %s:%d: %s (%d)", ipstr, port, strerror(errno), errno); } @@ -344,6 +344,7 @@ void dns_server_tcp_respond(dns_server_tcp_t *d, remove_client(client); return; } + continue; } sent += len; diff --git a/src/https_client.c b/src/https_client.c index fde2ae5..96da9e5 100644 --- a/src/https_client.c +++ b/src/https_client.c @@ -659,7 +659,7 @@ static void https_client_multi_init(https_client_t *c, struct curl_slist *header c->curlm = curl_multi_init(); // if fails, first setopt will fail c->header_list = header_list; - ASSERT_CURL_MULTI_SETOPT(c->curlm, CURLMOPT_PIPELINING, CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX); + ASSERT_CURL_MULTI_SETOPT(c->curlm, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX); ASSERT_CURL_MULTI_SETOPT(c->curlm, CURLMOPT_MAX_TOTAL_CONNECTIONS, HTTPS_CONNECTION_LIMIT); ASSERT_CURL_MULTI_SETOPT(c->curlm, CURLMOPT_MAX_HOST_CONNECTIONS, HTTPS_CONNECTION_LIMIT); ASSERT_CURL_MULTI_SETOPT(c->curlm, CURLMOPT_SOCKETDATA, c); diff --git a/src/main.c b/src/main.c index 23ba463..6ae0f7c 100644 --- a/src/main.c +++ b/src/main.c @@ -58,13 +58,15 @@ static int hostname_from_url(const char* url_in, if (rc == CURLUE_OK) { char *host = NULL; rc = curl_url_get(url, CURLUPART_HOST, &host, 0); - const size_t host_len = strlen(host); - if (rc == CURLUE_OK && host_len < hostname_len && - host[0] != '[' && host[host_len-1] != ']' && // skip IPv6 address - !is_ipv4_address(host)) { - strncpy(hostname, host, hostname_len-1); - hostname[hostname_len-1] = '\0'; - res = 1; // success + if (rc == CURLUE_OK && host != NULL) { + const size_t host_len = strlen(host); + if (host_len < hostname_len && + host[0] != '[' && host[host_len-1] != ']' && // skip IPv6 address + !is_ipv4_address(host)) { + strncpy(hostname, host, hostname_len-1); + hostname[hostname_len-1] = '\0'; + res = 1; // success + } } curl_free(host); } @@ -88,10 +90,10 @@ static void sigpipe_cb(struct ev_loop __attribute__((__unused__)) *loop, static void https_resp_cb(void *data, char *buf, size_t buflen) { request_t *req = (request_t *)data; - DLOG("Received response for id: %hX, len: %zu", req->tx_id, buflen); if (req == NULL) { - FLOG("%04hX: data NULL", req->tx_id); + FLOG("data NULL, buflen: %zu", buflen); } + DLOG("Received response for id: %hX, len: %zu", req->tx_id, buflen); if (buf != NULL) { // May be NULL for timeout, DNS failure, or something similar. if (buflen < DNS_HEADER_LENGTH) { WLOG("%04hX: Malformed response received, too short: %u", req->tx_id, buflen);