diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c6fe60..4109e0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.7) +cmake_minimum_required(VERSION 3.10) project(HttpsDnsProxy C) include(CheckIncludeFile) @@ -110,7 +110,7 @@ if(USE_CLANG_TIDY) message(STATUS "clang-tidy not found.") else() message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") - set(DO_CLANG_TIDY "${CLANG_TIDY_EXE}" "-fix" "-fix-errors" "-checks=*,-cert-err34-c,-readability-identifier-length,-altera-unroll-loops,-bugprone-easily-swappable-parameters,-concurrency-mt-unsafe,-*magic-numbers,-hicpp-signed-bitwise,-readability-function-cognitive-complexity,-altera-id-dependent-backward-branch,-google-readability-todo,-misc-include-cleaner,-cast-align") + set(DO_CLANG_TIDY "${CLANG_TIDY_EXE}" "-fix" "-fix-errors" "-checks=*,-readability-identifier-length,-altera-unroll-loops,-bugprone-easily-swappable-parameters,-concurrency-mt-unsafe,-*magic-numbers,-hicpp-signed-bitwise,-readability-function-cognitive-complexity,-altera-id-dependent-backward-branch,-misc-include-cleaner,-llvmlibc-restrict-system-libc-headers,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling") endif() else() message(STATUS "Not using clang-tidy.") diff --git a/src/dns_poller.c b/src/dns_poller.c index 2ff30d8..8014766 100644 --- a/src/dns_poller.c +++ b/src/dns_poller.c @@ -1,5 +1,5 @@ -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include #include "dns_poller.h" #include "logging.h" @@ -38,7 +38,6 @@ static void sock_state_cb(void *data, int fd, int read, int write) { FLOG("c-ares needed more IO event handler, than the number of provided nameservers: %u", d->io_events_count); } DLOG("Reserved new io event: %p", io_event_ptr); - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_io_init(io_event_ptr, sock_cb, fd, (read ? EV_READ : 0) | (write ? EV_WRITE : 0)); ev_io_start(d->loop, io_event_ptr); @@ -119,7 +118,6 @@ static ev_tstamp get_timeout(dns_poller_t *d) static struct timeval max_tv = {.tv_sec = 5, .tv_usec = 0}; struct timeval tv; struct timeval *tvp = ares_timeout(d->ares, &max_tv, &tv); - // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) ev_tstamp after = (double)tvp->tv_sec + (double)tvp->tv_usec * 1e-6; return after > 0.1 ? after : 0.1; } @@ -147,7 +145,7 @@ static void timer_cb(struct ev_loop __attribute__((unused)) *loop, d->request_ongoing = 1; struct ares_addrinfo_hints hints; - memset(&hints, 0, sizeof(hints)); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + memset(&hints, 0, sizeof(hints)); hints.ai_flags = ARES_AI_CANONNAME; hints.ai_family = d->family; hints.ai_socktype = SOCK_STREAM; @@ -199,8 +197,6 @@ void dns_poller_init(dns_poller_t *d, struct ev_loop *loop, d->polling_interval = bootstrap_dns_polling_interval; d->request_ongoing = 0; d->cb_data = cb_data; - - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_timer_init(&d->timer, timer_cb, 0, 0); d->timer.data = d; ev_timer_start(d->loop, &d->timer); diff --git a/src/dns_server.c b/src/dns_server.c index 2fc8f19..a6c7765 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -1,9 +1,9 @@ -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include +#include #include -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include #include "dns_server.h" #include "logging.h" @@ -67,7 +67,7 @@ static void watcher_cb(struct ev_loop __attribute__((unused)) *loop, if (dns_req == NULL) { FLOG("Out of mem"); } - memcpy(dns_req, tmp_buf, (size_t)len); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + memcpy(dns_req, tmp_buf, (size_t)len); d->cb(d, 0, d->cb_data, (struct sockaddr*)&tmp_raddr, dns_req, (size_t)len); } @@ -80,8 +80,6 @@ void dns_server_init(dns_server_t *d, struct ev_loop *loop, d->addrlen = listen_addrinfo->ai_addrlen; d->cb = cb; d->cb_data = data; - - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_io_init(&d->watcher, watcher_cb, d->sock, EV_READ); d->watcher.data = d; ev_io_start(d->loop, &d->watcher); @@ -145,7 +143,7 @@ static void truncate_dns_response(char *buf, size_t *buflen, const uint16_t size // rough estimate to reach size limit size_t answers = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); - size_t answers_to_keep = (size_limit - DNS_HEADER_LENGTH) / (old_size / answers); + size_t answers_to_keep = ((size_limit - DNS_HEADER_LENGTH) * answers) / old_size; answers_to_keep = answers_to_keep > 0 ? answers_to_keep : 1; // try to keep 1 answer // remove answer records until fit size limit or running out of answers @@ -185,7 +183,7 @@ static void truncate_dns_response(char *buf, size_t *buflen, const uint16_t size ares_dns_record_destroy(dnsrec); if (new_resp != NULL && new_resp_len < old_size) { - memcpy(buf, new_resp, new_resp_len); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + memcpy(buf, new_resp, new_resp_len); *buflen = new_resp_len; buf[2] |= 0x02; // set truncation flag ILOG("%04hX: DNS response size truncated from %u to %u to keep %u limit", @@ -196,6 +194,10 @@ static void truncate_dns_response(char *buf, size_t *buflen, const uint16_t size void dns_server_respond(dns_server_t *d, struct sockaddr *raddr, const char *dns_req, const size_t dns_req_len, char *dns_resp, size_t dns_resp_len) { + if (dns_resp_len < DNS_HEADER_LENGTH) { + WLOG("Malformed response received, invalid length: %u", dns_resp_len); + return; + } if (dns_resp_len > DNS_SIZE_LIMIT) { const uint16_t udp_size = get_edns_udp_size(dns_req, dns_req_len); if (dns_resp_len > udp_size) { diff --git a/src/dns_server_tcp.c b/src/dns_server_tcp.c index 97d03e4..a533722 100644 --- a/src/dns_server_tcp.c +++ b/src/dns_server_tcp.c @@ -1,9 +1,9 @@ //NOLINTNEXTLINE(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) #define _GNU_SOURCE // needed for having accept4() -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include +#include #include "dns_server_tcp.h" #include "logging.h" @@ -104,10 +104,10 @@ static int get_dns_request(struct tcp_client_s *client, if (*dns_req == NULL) { FLOG_CLIENT("Out of mem"); } - memcpy(*dns_req, client->input_buffer + sizeof(uint16_t), *req_size); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + memcpy(*dns_req, client->input_buffer + sizeof(uint16_t), *req_size); // move down data of next request(s) if any client->input_buffer_used -= data_size; - memmove(client->input_buffer, client->input_buffer + data_size, client->input_buffer_used); // NOLINT(clang-diagnostic-format-nonliteral,clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + memmove(client->input_buffer, client->input_buffer + data_size, client->input_buffer_used); return 1; } @@ -150,7 +150,7 @@ static void read_cb(struct ev_loop __attribute__((unused)) *loop, FLOG_CLIENT("Out of mem"); } } - memcpy(client->input_buffer + client->input_buffer_used, buf, (size_t)len); // NOLINT(clang-diagnostic-format-nonliteral,clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + memcpy(client->input_buffer + client->input_buffer_used, buf, (size_t)len); client->input_buffer_used = needed_space; // Split requests @@ -208,13 +208,12 @@ static void accept_cb(struct ev_loop __attribute__((unused)) *loop, client->d = d; client->id = d->client_id; client->sock = client_sock; - memcpy(&client->raddr, &client_addr, client_addr_len); // NOLINT(clang-diagnostic-format-nonliteral,clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + memcpy(&client->raddr, &client_addr, client_addr_len); client->addr_len = client_addr_len; client->input_buffer = NULL; client->next = d->clients; d->clients = client; - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_io_init(&client->read_watcher, read_cb, client->sock, EV_READ); client->read_watcher.data = client; ev_io_start(d->loop, &client->read_watcher); @@ -294,7 +293,6 @@ dns_server_tcp_t * dns_server_tcp_create( d->client_limit = tcp_client_limit; d->clients = NULL; - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_io_init(&d->accept_watcher, accept_cb, d->sock, EV_READ); d->accept_watcher.data = d; ev_io_start(d->loop, &d->accept_watcher); diff --git a/src/https_client.c b/src/https_client.c index b26ac0f..371602b 100644 --- a/src/https_client.c +++ b/src/https_client.c @@ -1,13 +1,13 @@ -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include +#include +#include +#include #include -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include +#include +#include #include "https_client.h" #include "logging.h" @@ -69,7 +69,6 @@ static size_t write_buffer(void *buf, size_t size, size_t nmemb, void *userp) { return 0; } ctx->buf = new_buf; - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) memcpy(&(ctx->buf[ctx->buflen]), buf, write_size); ctx->buflen = new_size; // We always expect to receive valid non-null ASCII but just to be safe... @@ -153,21 +152,16 @@ static void https_log_data(int level, struct https_fetch_ctx *ctx, char str[width + 1]; size_t hex_off = 0; size_t str_off = 0; - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) memset(hex, 0, sizeof(hex)); - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) memset(str, 0, sizeof(str)); for (size_t c = 0; c < width; c++) { if (i+c < size) { - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) hex_off += (size_t)snprintf(hex + hex_off, sizeof(hex) - hex_off, "%02x ", (unsigned char)ptr[i+c]); - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) str_off += (size_t)snprintf(str + str_off, sizeof(str) - str_off, "%c", isprint(ptr[i+c]) ? ptr[i+c] : '.'); } else { - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) hex_off += (size_t)snprintf(hex + hex_off, sizeof(hex) - hex_off, " "); } } @@ -313,14 +307,14 @@ static void https_fetch_ctx_init(https_client_t *client, ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_POSTFIELDS, data); ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_WRITEFUNCTION, &write_buffer); ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_WRITEDATA, ctx); - ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_MAXAGE_CONN, client->opt->max_idle_time); - ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_PIPEWAIT, client->opt->use_http_version > 1); + ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_MAXAGE_CONN, (long)client->opt->max_idle_time); + ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_PIPEWAIT, (long)(client->opt->use_http_version > 1)); ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_USERAGENT, "https_dns_proxy/0.4"); - ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_FOLLOWLOCATION, 0); - ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_NOSIGNAL, 0); - ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_TIMEOUT, client->connections > 0 ? 5 : 10 /* seconds */); + ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_FOLLOWLOCATION, 0L); + ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_NOSIGNAL, 0L); + ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_TIMEOUT, client->connections > 0 ? 5L : 10L /* seconds */); // We know Google supports this, so force it. - ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); + ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_SSLVERSION, (long)CURL_SSLVERSION_TLSv1_2); ASSERT_CURL_EASY_SETOPT(ctx, CURLOPT_ERRORBUFFER, ctx->curl_errbuf); // zeroed by calloc if (client->opt->curl_proxy) { DLOG_REQ("Using curl proxy: %s", client->opt->curl_proxy); @@ -639,7 +633,6 @@ static int multi_sock_cb(CURL *curl, curl_socket_t sock, int what, return -1; } DLOG("Reserved new io event: %p", io_event_ptr); - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_io_init(io_event_ptr, sock_cb, sock, ((what & CURL_POLL_IN) ? EV_READ : 0) | ((what & CURL_POLL_OUT) ? EV_WRITE : 0)); @@ -652,7 +645,6 @@ static int multi_timer_cb(CURLM __attribute__((unused)) *multi, GET_PTR(https_client_t, c, userp); ev_timer_stop(c->loop, &c->timer); if (timeout_ms >= 0) { - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_timer_init(&c->timer, timer_cb, (double)timeout_ms / 1000.0, 0); ev_timer_start(c->loop, &c->timer); } @@ -681,7 +673,6 @@ static void reset_timer_cb(struct ev_loop __attribute__((unused)) *loop, void https_client_init(https_client_t *c, options_t *opt, stat_t *stat, struct ev_loop *loop) { - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) memset(c, 0, sizeof(*c)); c->loop = loop; c->fetches = NULL; diff --git a/src/logging.c b/src/logging.c index 944c96b..37434c5 100644 --- a/src/logging.c +++ b/src/logging.c @@ -1,9 +1,9 @@ #include #include #include -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include +#include #include "logging.h" #include "ring_buffer.h" @@ -56,7 +56,6 @@ void logging_events_init(struct ev_loop *loop) { /* don't start timer if we will never write messages that are not flushed */ if (loglevel < LOG_FLUSH_LEVEL) { DLOG("starting periodic log flush timer"); - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_timer_init(&logging_timer, logging_timer_cb, 0, 10); ev_timer_start(loop, &logging_timer); } @@ -114,8 +113,6 @@ void _log(const char *file, int line, int severity, const char *fmt, ...) { char buff[LOG_LINE_SIZE]; uint32_t buff_pos = 0; - - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) int chars = snprintf(buff, LOG_LINE_SIZE, "%s %8"PRIu64".%06"PRIu64" %s:%d ", SeverityStr[severity], (uint64_t)tv.tv_sec, (uint64_t)tv.tv_usec, file, line); if (chars < 0 || chars >= LOG_LINE_SIZE/2) { @@ -125,8 +122,7 @@ void _log(const char *file, int line, int severity, const char *fmt, ...) { va_list args; va_start(args, fmt); - // NOLINTNEXTLINE(clang-diagnostic-format-nonliteral,clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) - chars = vsnprintf(buff + buff_pos, LOG_LINE_SIZE - buff_pos, fmt, args); + chars = vsnprintf(buff + buff_pos, LOG_LINE_SIZE - buff_pos, fmt, args); // NOLINT(clang-diagnostic-format-nonliteral) va_end(args); if (chars < 0) { @@ -145,8 +141,6 @@ void _log(const char *file, int line, int severity, const char *fmt, ...) { if (severity < loglevel) { return; } - - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) (void)fprintf(logfile, "%s\n", buff); if (severity >= LOG_FLUSH_LEVEL) { diff --git a/src/logging.h b/src/logging.h index cd110d6..1352438 100644 --- a/src/logging.h +++ b/src/logging.h @@ -1,9 +1,9 @@ #ifndef _LOGGING_H_ #define _LOGGING_H_ -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include +#include #ifdef __cplusplus extern "C" { diff --git a/src/main.c b/src/main.c index c81d5a5..23ba463 100644 --- a/src/main.c +++ b/src/main.c @@ -1,16 +1,16 @@ // Simple UDP-to-HTTPS DNS Proxy // (C) 2016 Aaron Drew -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include +#include +#include +#include +#include +#include #if HAS_LIBSYSTEMD == 1 -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include #endif #include "dns_poller.h" @@ -62,7 +62,7 @@ static int hostname_from_url(const char* url_in, 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); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + strncpy(hostname, host, hostname_len-1); hostname[hostname_len-1] = '\0'; res = 1; // success } @@ -139,7 +139,7 @@ static void dns_server_cb(void *dns_server, uint8_t is_tcp, void *data, FLOG("%04hX: Out of mem", tx_id); } req->tx_id = tx_id; - memcpy(&req->raddr, tmp_remote_addr, app->addrlen); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + memcpy(&req->raddr, tmp_remote_addr, app->addrlen); req->dns_server = dns_server; req->is_tcp = is_tcp; req->dns_req = dns_req; // To free buffer after https request is complete. @@ -182,7 +182,7 @@ static int addr_list_reduced(const char* full_list, const char* list) { char current[50]; const char *comma = strchr(pos, ','); size_t ip_len = (size_t)(comma ? comma - pos : end - pos); - strncpy(current, pos, ip_len); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + strncpy(current, pos, ip_len); current[ip_len] = '\0'; const char *match_begin = strstr(full_list, current); @@ -202,13 +202,13 @@ static void dns_poll_cb(const char* hostname, void *data, const char* addr_list) { app_state_t *app = (app_state_t *)data; char buf[255 + (sizeof(":443:") - 1) + POLLER_ADDR_LIST_SIZE]; - memset(buf, 0, sizeof(buf)); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + memset(buf, 0, sizeof(buf)); if (strlen(hostname) > 254) { FLOG("Hostname too long."); } - int ip_start = snprintf(buf, sizeof(buf) - 1, "%s:443:", hostname); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + int ip_start = snprintf(buf, sizeof(buf) - 1, "%s:443:", hostname); if (ip_start < 0) { abort(); // must be impossible } - (void)snprintf(buf + ip_start, sizeof(buf) - 1 - (uint32_t)ip_start, "%s", addr_list); // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) + (void)snprintf(buf + ip_start, sizeof(buf) - 1 - (uint32_t)ip_start, "%s", addr_list); if (app->resolv == NULL) { systemd_notify_ready(); } @@ -251,7 +251,6 @@ static int proxy_supports_name_resolution(const char *proxy) static struct addrinfo * get_listen_address(const char *listen_addr) { struct addrinfo *ai = NULL; struct addrinfo hints; - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) memset(&hints, 0, sizeof(struct addrinfo)); /* prevent DNS lookups if leakage is our worry */ hints.ai_flags = AI_NUMERICHOST; @@ -398,17 +397,14 @@ int main(int argc, char *argv[]) { } ev_signal sigpipe; - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_signal_init(&sigpipe, sigpipe_cb, SIGPIPE); ev_signal_start(loop, &sigpipe); ev_signal sigint; - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_signal_init(&sigint, signal_shutdown_cb, SIGINT); ev_signal_start(loop, &sigint); ev_signal sigterm; - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_signal_init(&sigterm, signal_shutdown_cb, SIGTERM); ev_signal_start(loop, &sigterm); diff --git a/src/options.c b/src/options.c index 51f8193..fa003dc 100644 --- a/src/options.c +++ b/src/options.c @@ -1,11 +1,11 @@ -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include +#include +#include +#include +#include +#include +#include #include "logging.h" #include "options.h" @@ -47,6 +47,15 @@ void options_init(struct Options *opt) { opt->flight_recorder_size = 0; } +int parse_int(char * str) { + char * endptr = NULL; + unsigned long int value = strtoul(str, &endptr, 10); + if (*endptr != '\0' || value > INT32_MAX) { + return -1; + } + return (int)value; +} + enum OptionsParseResult options_parse_args(struct Options *opt, int argc, char **argv) { int c = 0; while ((c = getopt(argc, argv, "a:c:p:T:du:g:b:i:4r:e:t:l:vxqm:L:s:C:F:hV")) != -1) { @@ -55,13 +64,13 @@ enum OptionsParseResult options_parse_args(struct Options *opt, int argc, char * opt->listen_addr = optarg; break; case 'c': // DSCP codepoint - opt->dscp = atoi(optarg); + opt->dscp = parse_int(optarg); break; case 'p': // listen_port - opt->listen_port = atoi(optarg); + opt->listen_port = parse_int(optarg); break; case 'T': // tcp_client_limit - opt->tcp_client_limit = atoi(optarg); + opt->tcp_client_limit = parse_int(optarg); break; case 'd': // daemonize opt->daemonize = 1; @@ -76,7 +85,7 @@ enum OptionsParseResult options_parse_args(struct Options *opt, int argc, char * opt->bootstrap_dns = optarg; break; case 'i': // bootstrap dns servers polling interval - opt->bootstrap_dns_polling_interval = atoi(optarg); + opt->bootstrap_dns_polling_interval = parse_int(optarg); break; case '4': // ipv4 mode - don't use v6 addresses. opt->ipv4 = 1; @@ -106,19 +115,19 @@ enum OptionsParseResult options_parse_args(struct Options *opt, int argc, char * } break; case 'm': - opt->max_idle_time = atoi(optarg); + opt->max_idle_time = parse_int(optarg); break; case 'L': - opt->conn_loss_time = atoi(optarg); + opt->conn_loss_time = parse_int(optarg); break; case 's': // stats interval - opt->stats_interval = atoi(optarg); + opt->stats_interval = parse_int(optarg); break; case 'C': // CA info opt->ca_info = optarg; break; case 'F': // Flight recorder size - opt->flight_recorder_size = atoi(optarg); + opt->flight_recorder_size = parse_int(optarg); break; case 'h': return OPR_HELP; @@ -147,7 +156,7 @@ enum OptionsParseResult options_parse_args(struct Options *opt, int argc, char * opt->gid = g->gr_gid; } if (opt->dscp < 0 || opt->dscp >63) { - printf("DSCP code (%d) invalid:[0-63]\n", opt->dscp); + printf("DSCP code must be between 0 and 63.\n"); return OPR_OPTION_ERROR; } opt->dscp <<= 2; diff --git a/src/ring_buffer.c b/src/ring_buffer.c index 0de09ea..8286a4f 100644 --- a/src/ring_buffer.c +++ b/src/ring_buffer.c @@ -1,7 +1,7 @@ #include -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) -#include // NOLINT(llvmlibc-restrict-system-libc-headers) +#include +#include +#include #include "ring_buffer.h" @@ -60,7 +60,6 @@ void ring_buffer_dump(struct ring_buffer *rb, FILE * file) uint32_t current = rb->full ? rb->next : 0; do { - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) (void)fprintf(file, "%s\n", rb->storage[current]); if (++current == rb->size) { @@ -81,7 +80,6 @@ void ring_buffer_push_back(struct ring_buffer *rb, char* data, uint32_t size) free(rb->storage[rb->next]); } rb->storage[rb->next] = (char*)malloc(size + 1); - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) memcpy(rb->storage[rb->next], data, size); rb->storage[rb->next][size] = '\0'; diff --git a/src/stat.c b/src/stat.c index bddf758..f0f6b21 100644 --- a/src/stat.c +++ b/src/stat.c @@ -40,8 +40,6 @@ void stat_init(stat_t *s, struct ev_loop *loop, int stats_interval) { s->loop = loop; s->stats_interval = stats_interval; reset_counters(s); - - // NOLINTNEXTLINE(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling) ev_timer_init(&s->stats_timer, stat_timer_cb, s->stats_interval, s->stats_interval); s->stats_timer.data = s; @@ -71,12 +69,10 @@ void stat_request_end(stat_t *s, size_t resp_len, ev_tstamp latency, uint8_t is_ if (is_tcp) { s->tcp_responses_size += resp_len; s->tcp_responses++; - // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) s->tcp_query_times_sum += (uint64_t)(latency * 1000); } else { s->responses_size += resp_len; s->responses++; - // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) s->query_times_sum += (uint64_t)(latency * 1000); } }