From 8f9e6acda8c899ddef44bb5559a08b79287a5155 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sun, 17 Oct 2021 12:47:06 +0100 Subject: [PATCH] [Minor] Fix some issues in the contrib libraries Found by: coverity scan --- contrib/librdns/curve.c | 1 + contrib/librdns/packet.c | 7 +++++-- contrib/librdns/parse.c | 8 ++++++++ contrib/librdns/resolver.c | 10 +++------- contrib/librdns/util.c | 3 ++- contrib/libucl/ucl_parser.c | 4 ++++ contrib/libucl/ucl_util.c | 38 ++++++++++++++++++++++++++----------- 7 files changed, 50 insertions(+), 21 deletions(-) diff --git a/contrib/librdns/curve.c b/contrib/librdns/curve.c index c6479c31e..19ec2508c 100644 --- a/contrib/librdns/curve.c +++ b/contrib/librdns/curve.c @@ -715,6 +715,7 @@ rdns_curve_send (struct rdns_request *req, void *plugin_data, boxed_len = req->pos + crypto_box_ZEROBYTES; m = malloc (boxed_len); if (m == NULL) { + free(creq); return -1; } diff --git a/contrib/librdns/packet.c b/contrib/librdns/packet.c index 99536668c..5c822ffef 100644 --- a/contrib/librdns/packet.c +++ b/contrib/librdns/packet.c @@ -92,7 +92,7 @@ rdns_format_dns_name (struct rdns_resolver *resolver, const char *in, char *o; int labels = 0; size_t label_len, olen, remain; - uint32_t *uclabel; + uint32_t *uclabel = NULL; size_t punylabel_len, uclabel_len; char tmp_label[DNS_D_MAXLABEL]; bool need_encode = false; @@ -163,6 +163,7 @@ rdns_format_dns_name (struct rdns_resolver *resolver, const char *in, } free (uclabel); + uclabel = NULL; if (dot) { p = dot + 1; @@ -230,9 +231,11 @@ rdns_format_dns_name (struct rdns_resolver *resolver, const char *in, return true; - err: +err: free (*out); *out = NULL; + free (uclabel); + return false; } diff --git a/contrib/librdns/parse.c b/contrib/librdns/parse.c index 18bb6a694..1a9c01838 100644 --- a/contrib/librdns/parse.c +++ b/contrib/librdns/parse.c @@ -351,6 +351,10 @@ rdns_parse_rr (struct rdns_resolver *resolver, case DNS_T_TXT: case DNS_T_SPF: if (datalen <= *remain) { + if (datalen > UINT16_MAX / 2) { + rdns_info ("too large datalen; domain %s", rep->requested_name); + return -1; + } elt->content.txt.data = malloc(datalen + 1); if (elt->content.txt.data == NULL) { rdns_err ("failed to allocate %d bytes for TXT record; domain %s", @@ -413,6 +417,10 @@ rdns_parse_rr (struct rdns_resolver *resolver, rdns_info ("stripped dns reply while reading TLSA record; domain %s", rep->requested_name); return -1; } + if (datalen > UINT16_MAX / 2) { + rdns_info ("too large datalen; domain %s", rep->requested_name); + return -1; + } GET8 (elt->content.tlsa.usage); GET8 (elt->content.tlsa.selector); GET8 (elt->content.tlsa.match_type); diff --git a/contrib/librdns/resolver.c b/contrib/librdns/resolver.c index 6e3792f7e..2c402077c 100644 --- a/contrib/librdns/resolver.c +++ b/contrib/librdns/resolver.c @@ -150,13 +150,7 @@ rdns_make_reply (struct rdns_request *req, enum dns_rcode rcode) rep->code = rcode; req->reply = rep; rep->authenticated = false; - - if (req) { - rep->requested_name = req->requested_names[0].name; - } - else { - rep->requested_name = NULL; - } + rep->requested_name = req->requested_names[0].name; } return rep; @@ -1133,4 +1127,6 @@ void rdns_resolver_set_fake_reply (struct rdns_resolver *resolver, HASH_ADD (hh, resolver->fake_elts, key, sizeof (*srch) + len, fake_rep); } + + free (srch); } diff --git a/contrib/librdns/util.c b/contrib/librdns/util.c index 920e94b99..be31c8f14 100644 --- a/contrib/librdns/util.c +++ b/contrib/librdns/util.c @@ -207,7 +207,7 @@ rdns_make_client_socket (const char *credits, hints.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV; snprintf (portbuf, sizeof (portbuf), "%d", (int)port); - if ((r = getaddrinfo (credits, portbuf, &hints, &res)) == 0) { + if (getaddrinfo (credits, portbuf, &hints, &res) == 0) { r = rdns_make_inet_socket (type, res, psockaddr, psocklen); if (r != -1 && psockaddr) { @@ -217,6 +217,7 @@ rdns_make_client_socket (const char *credits, if (cpy == NULL) { close (r); + freeaddrinfo (res); return -1; } diff --git a/contrib/libucl/ucl_parser.c b/contrib/libucl/ucl_parser.c index 5b5681863..1d285f27d 100644 --- a/contrib/libucl/ucl_parser.c +++ b/contrib/libucl/ucl_parser.c @@ -685,6 +685,8 @@ ucl_parser_add_container (ucl_object_t *obj, struct ucl_parser *parser, ucl_object_unref (obj); } + UCL_FREE(sizeof (struct ucl_stack), st); + return NULL; } @@ -2888,7 +2890,9 @@ ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data, if (!special_handler->handler (parser, data, len, &ndata, &nlen, special_handler->user_data)) { + UCL_FREE(sizeof (struct ucl_chunk), chunk); ucl_create_err (&parser->err, "call for external handler failed"); + return false; } diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c index 830aaa14c..e97e3ab9b 100644 --- a/contrib/libucl/ucl_util.c +++ b/contrib/libucl/ucl_util.c @@ -887,44 +887,49 @@ ucl_fetch_file (const unsigned char *filename, unsigned char **buf, size_t *bufl { int fd; struct stat st; + if ((fd = open (filename, O_RDONLY)) == -1) { + ucl_create_err (err, "cannot open file %s: %s", + filename, strerror (errno)); + return false; + } - if (stat (filename, &st) == -1) { + if (fstat (fd, &st) == -1) { if (must_exist || errno == EPERM) { ucl_create_err (err, "cannot stat file %s: %s", filename, strerror (errno)); } + close (fd); + return false; } if (!S_ISREG (st.st_mode)) { if (must_exist) { ucl_create_err (err, "file %s is not a regular file", filename); } + close (fd); return false; } + if (st.st_size == 0) { /* Do not map empty files */ *buf = NULL; *buflen = 0; } else { - if ((fd = open (filename, O_RDONLY)) == -1) { - ucl_create_err (err, "cannot open file %s: %s", - filename, strerror (errno)); - return false; - } - if ((*buf = ucl_mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { - close (fd); - ucl_create_err (err, "cannot mmap file %s: %s", - filename, strerror (errno)); + if ((*buf = ucl_mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { + close(fd); + ucl_create_err(err, "cannot mmap file %s: %s", + filename, strerror(errno)); *buf = NULL; return false; } *buflen = st.st_size; - close (fd); } + close (fd); + return true; } @@ -1136,6 +1141,10 @@ ucl_include_file_single (const unsigned char *data, size_t len, /* We need to check signature first */ snprintf (filebuf, sizeof (filebuf), "%s.sig", realbuf); if (!ucl_fetch_file (filebuf, &sigbuf, &siglen, &parser->err, true)) { + if (buf) { + ucl_munmap (buf, buflen); + } + return false; } if (!ucl_sig_check (buf, buflen, sigbuf, siglen, parser)) { @@ -1145,8 +1154,13 @@ ucl_include_file_single (const unsigned char *data, size_t len, if (sigbuf) { ucl_munmap (sigbuf, siglen); } + if (buf) { + ucl_munmap (buf, buflen); + } + return false; } + if (sigbuf) { ucl_munmap (sigbuf, siglen); } @@ -1255,6 +1269,8 @@ ucl_include_file_single (const unsigned char *data, size_t len, ucl_munmap (buf, buflen); } + ucl_object_unref (new_obj); + return false; } nest_obj->prev = nest_obj; -- 2.39.5