diff options
author | Oto Šťáva <oto.stava@nic.cz> | 2024-05-20 13:01:04 +0200 |
---|---|---|
committer | Oto Šťáva <oto.stava@nic.cz> | 2024-05-20 13:01:04 +0200 |
commit | 8827536a27b27d011fb005f1898c4c74d0d972e1 (patch) | |
tree | 9762e19adbd9887415db0807864e27c5f3cdb940 | |
parent | .gitlab-ci: remove SonarCloud Scanner (diff) | |
parent | daemon/tls_ephemeral_credentials: fix possible race between read() and fstat() (diff) | |
download | knot-resolver-8827536a27b27d011fb005f1898c4c74d0d972e1.tar.xz knot-resolver-8827536a27b27d011fb005f1898c4c74d0d972e1.zip |
Merge branch 'coverity' into 'master-5'
Coverity fixes
See merge request knot/knot-resolver!1543
-rw-r--r-- | .gitlab-ci.yml | 1 | ||||
-rw-r--r-- | contrib/dynarray.h | 112 | ||||
-rw-r--r-- | contrib/dynarray.spdx | 10 | ||||
-rw-r--r-- | daemon/tls_ephemeral_credentials.c | 2 | ||||
-rw-r--r-- | modules/hints/hints.c | 2 | ||||
-rw-r--r-- | utils/cache_gc/kr_cache_gc.c | 66 |
6 files changed, 32 insertions, 161 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1c3eb427..61e0c929 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -285,6 +285,7 @@ lint:coverity: --form token=$COVERITY_SCAN_TOKEN --form email="knot-resolver@labs.nic.cz" --form file=@cov-int.tar.gz --form version="`git describe --tags`" --form description="`git describe --tags` / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID" + --fail-with-body .kres-gen: &kres-gen <<: *sanity diff --git a/contrib/dynarray.h b/contrib/dynarray.h deleted file mode 100644 index 7cbb686b..00000000 --- a/contrib/dynarray.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -/*! - * \brief Simple write-once allocation-optimal dynamic array. - * - * Include it into your .c file - * - * prefix - identifier prefix, e.g. ptr -> struct ptr_dynarray, ptr_dynarray_add(), ... - * ntype - data type to be stored. Let it be a number, pointer or small struct - * initial_capacity - how many data items will be allocated on stack and copied with assignment - * - * prefix_dynarray_add() - add a data item - * prefix_dynarray_fix() - call EVERYTIME the array is copied from some already invalid stack - * prefix_dynarray_free() - call EVERYTIME you dismiss all copies of the array - * - */ - -#include <stdlib.h> -#include <assert.h> - -#pragma once - -#define DYNARRAY_VISIBILITY_STATIC static -#define DYNARRAY_VISIBILITY_PUBLIC -#define DYNARRAY_VISIBILITY_LIBRARY __public__ - -#define dynarray_declare(prefix, ntype, visibility, initial_capacity) \ - typedef struct prefix ## _dynarray { \ - ssize_t capacity; \ - ssize_t size; \ - ntype *(*arr)(struct prefix ## _dynarray *dynarray); \ - ntype init[initial_capacity]; \ - ntype *_arr; \ - } prefix ## _dynarray_t; \ - \ - visibility ntype *prefix ## _dynarray_arr(prefix ## _dynarray_t *dynarray); \ - visibility void prefix ## _dynarray_add(prefix ## _dynarray_t *dynarray, \ - ntype const *to_add); \ - visibility void prefix ## _dynarray_free(prefix ## _dynarray_t *dynarray); - -#define dynarray_foreach(prefix, ntype, ptr, array) \ - for (ntype *ptr = prefix ## _dynarray_arr(&(array)); \ - ptr < prefix ## _dynarray_arr(&(array)) + (array).size; ptr++) - -#define dynarray_define(prefix, ntype, visibility) \ - \ - static void prefix ## _dynarray_free__(struct prefix ## _dynarray *dynarray) \ - { \ - if (dynarray->capacity > sizeof(dynarray->init) / sizeof(*dynarray->init)) { \ - free(dynarray->_arr); \ - } \ - } \ - \ - __attribute__((unused)) \ - visibility ntype *prefix ## _dynarray_arr(struct prefix ## _dynarray *dynarray) \ - { \ - assert(dynarray->size <= dynarray->capacity); \ - return (dynarray->capacity <= sizeof(dynarray->init) / sizeof(*dynarray->init) ? \ - dynarray->init : dynarray->_arr); \ - } \ - \ - static ntype *prefix ## _dynarray_arr_init__(struct prefix ## _dynarray *dynarray) \ - { \ - assert(dynarray->capacity == sizeof(dynarray->init) / sizeof(*dynarray->init)); \ - return dynarray->init; \ - } \ - \ - static ntype *prefix ## _dynarray_arr_arr__(struct prefix ## _dynarray *dynarray) \ - { \ - assert(dynarray->capacity > sizeof(dynarray->init) / sizeof(*dynarray->init)); \ - return dynarray->_arr; \ - } \ - \ - __attribute__((unused)) \ - visibility void prefix ## _dynarray_add(struct prefix ## _dynarray *dynarray, \ - ntype const *to_add) \ - { \ - if (dynarray->capacity < 0) { \ - return; \ - } \ - if (dynarray->capacity == 0) { \ - dynarray->capacity = sizeof(dynarray->init) / sizeof(*dynarray->init); \ - dynarray->arr = prefix ## _dynarray_arr_init__; \ - } \ - if (dynarray->size >= dynarray->capacity) { \ - ssize_t new_capacity = dynarray->capacity * 2 + 1; \ - ntype *new_arr = calloc(new_capacity, sizeof(ntype)); \ - if (new_arr == NULL) { \ - prefix ## _dynarray_free__(dynarray); \ - dynarray->capacity = dynarray->size = -1; \ - return; \ - } \ - if (dynarray->capacity > 0) { \ - memcpy(new_arr, prefix ## _dynarray_arr(dynarray), \ - dynarray->capacity * sizeof(ntype)); \ - } \ - prefix ## _dynarray_free__(dynarray); \ - dynarray->_arr = new_arr; \ - dynarray->capacity = new_capacity; \ - dynarray->arr = prefix ## _dynarray_arr_arr__; \ - } \ - prefix ## _dynarray_arr(dynarray)[dynarray->size++] = *to_add; \ - } \ - \ - __attribute__((unused)) \ - visibility void prefix ## _dynarray_free(struct prefix ## _dynarray *dynarray) \ - { \ - prefix ## _dynarray_free__(dynarray); \ - memset(dynarray, 0, sizeof(*dynarray)); \ - } diff --git a/contrib/dynarray.spdx b/contrib/dynarray.spdx deleted file mode 100644 index 02911c9c..00000000 --- a/contrib/dynarray.spdx +++ /dev/null @@ -1,10 +0,0 @@ -SPDXVersion: SPDX-2.1 -DataLicense: CC0-1.0 -SPDXID: SPDXRef-DOCUMENT -DocumentName: knotdns-dynarray -DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-ce6423dd-ac6a-4e78-90c3-5cbdef1e252c - -PackageName: knotdns-dynarray -PackageDownloadLocation: git+https://gitlab.nic.cz/knot/knot-dns.git@48c8b4f38cf5f7bf505c79b56adf7580688f6d3d#src/contrib/dynarray.h -PackageOriginator: Organization: Knot DNS contributors -PackageLicenseDeclared: GPL-3.0-or-later diff --git a/daemon/tls_ephemeral_credentials.c b/daemon/tls_ephemeral_credentials.c index 0d9ec6db..2b928faa 100644 --- a/daemon/tls_ephemeral_credentials.c +++ b/daemon/tls_ephemeral_credentials.c @@ -91,7 +91,7 @@ static gnutls_x509_privkey_t get_ephemeral_privkey (void) } data.size = stat.st_size; bytes_read = read(datafd, data.data, stat.st_size); - if (bytes_read != stat.st_size) { + if (bytes_read < 0 || bytes_read != stat.st_size) { kr_log_error(TLS, "unable to read ephemeral private key\n"); goto bad_data; } diff --git a/modules/hints/hints.c b/modules/hints/hints.c index af05ee24..2195ca3a 100644 --- a/modules/hints/hints.c +++ b/modules/hints/hints.c @@ -282,7 +282,7 @@ static int del_pair(struct hints_data *data, const char *name, const char *addr) return kr_error(EINVAL); } size_t key_len = knot_dname_size(key); - if (kr_fails_assert(key_len <= INT_MAX)) + if (kr_fails_assert(key_len <= KNOT_DNAME_MAXLEN)) return kr_error(EINVAL); if (addr) { diff --git a/utils/cache_gc/kr_cache_gc.c b/utils/cache_gc/kr_cache_gc.c index 62465f51..4097c802 100644 --- a/utils/cache_gc/kr_cache_gc.c +++ b/utils/cache_gc/kr_cache_gc.c @@ -8,20 +8,12 @@ // libknot includes #include <libknot/libknot.h> -// dynarray is inside libknot since 3.1, but it's differently named -#ifdef knot_dynarray_declare - #define dynarray_declare knot_dynarray_declare - #define dynarray_define knot_dynarray_define - #define dynarray_foreach knot_dynarray_foreach -#else - #include <contrib/dynarray.h> -#endif - // resolver includes #include <lib/cache/api.h> #include <lib/cache/impl.h> #include <lib/defines.h> #include "lib/cache/cdb_lmdb.h" +#include "lib/generic/array.h" #include "lib/utils.h" #include "kr_cache_gc.h" @@ -43,41 +35,40 @@ static knot_db_val_t *dbval_copy(const knot_db_val_t * from) } // section: rrtype list +typedef array_t(uint16_t) rrtype_array_t; -dynarray_declare(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC, 64) - dynarray_define(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC) -static void rrtypelist_add(rrtype_dynarray_t * arr, uint16_t add_type) +static void rrtypelist_add(rrtype_array_t *arr, uint16_t add_type) { bool already_present = false; - dynarray_foreach(rrtype, uint16_t, i, *arr) { - if (*i == add_type) { + for (size_t i = 0; i < arr->len; i++) { + if (arr->at[i] == add_type) { already_present = true; break; } } if (!already_present) { - rrtype_dynarray_add(arr, &add_type); + kr_require(array_push(*arr, add_type) >= 0); } } -static void rrtypelist_print(rrtype_dynarray_t * arr) +static void rrtypelist_print(rrtype_array_t *arr) { char type_s[32] = { 0 }; - dynarray_foreach(rrtype, uint16_t, i, *arr) { - knot_rrtype_to_string(*i, type_s, sizeof(type_s)); + for (size_t i = 0; i < arr->len; i++) { + knot_rrtype_to_string(arr->at[i], type_s, sizeof(type_s)); printf(" %s", type_s); } printf("\n"); } -dynarray_declare(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC, 256) - dynarray_define(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC) -static void entry_dynarray_deep_free(entry_dynarray_t * d) +typedef array_t(knot_db_val_t *) entry_array_t; + +static void entry_array_deep_free(entry_array_t *d) { - dynarray_foreach(entry, knot_db_val_t *, i, *d) { - free(*i); + for (size_t i = 0; i < d->len; i++) { + free(d->at[i]); } - entry_dynarray_free(d); + array_clear(*d); } typedef struct { @@ -98,7 +89,7 @@ int cb_compute_categories(const knot_db_val_t * key, gc_record_info_t * info, typedef struct { category_t limit_category; - entry_dynarray_t to_delete; + entry_array_t to_delete; size_t cfg_temp_keys_space; size_t used_space; size_t oversize_records; @@ -117,7 +108,7 @@ int cb_delete_categories(const knot_db_val_t * key, gc_record_info_t * info, ctx->oversize_records++; free(todelete); } else { - entry_dynarray_add(&ctx->to_delete, &todelete); + kr_require(array_push(ctx->to_delete, todelete) >= 0); ctx->used_space = used; } } @@ -229,13 +220,13 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state) to_del.limit_category = limit_category; ret = kr_gc_cache_iter(db, cfg, cb_delete_categories, &to_del); if (ret != KNOT_EOK) { - entry_dynarray_deep_free(&to_del.to_delete); + entry_array_deep_free(&to_del.to_delete); kr_cache_gc_free_state(state); return ret; } printf ("%zu records to be deleted using %.2lf MBytes of temporary memory, %zu records skipped due to memory limit.\n", - to_del.to_delete.size, ((double)to_del.used_space / 1048576.0), + to_del.to_delete.len, ((double)to_del.used_space / 1048576.0), to_del.oversize_records); //// 4. execute the planned deletions. @@ -245,23 +236,24 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state) kr_timer_start(&timer_delete); kr_timer_start(&timer_rw_txn); - rrtype_dynarray_t deleted_rrtypes = { 0 }; + rrtype_array_t deleted_rrtypes = { 0 }; ret = api->txn_begin(db, &txn, 0); if (ret != KNOT_EOK) { printf("Error starting R/W DB transaction (%s).\n", knot_strerror(ret)); - entry_dynarray_deep_free(&to_del.to_delete); + entry_array_deep_free(&to_del.to_delete); kr_cache_gc_free_state(state); return ret; } - dynarray_foreach(entry, knot_db_val_t *, i, to_del.to_delete) { - ret = api->del(&txn, *i); + for (size_t i = 0; i < to_del.to_delete.len; i++) { + knot_db_val_t *val = to_del.to_delete.at[i]; + ret = api->del(&txn, val); switch (ret) { case KNOT_EOK: deleted_records++; - const int entry_type = kr_gc_key_consistent(**i); + const int entry_type = kr_gc_key_consistent(*val); if (entry_type >= 0) // some "inconsistent" entries are OK rrtypelist_add(&deleted_rrtypes, entry_type); break; @@ -270,8 +262,8 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state) if (VERBOSE_STATUS) { // kresd normally only inserts (or overwrites), // so it's generally suspicious when a key goes missing. - printf("Record already gone (key len %zu): ", (*i)->len); - debug_printbin((*i)->data, (*i)->len); + printf("Record already gone (key len %zu): ", val->len); + debug_printbin(val->data, val->len); printf("\n"); } break; @@ -319,8 +311,8 @@ finish: printf("It took %.0lf msecs, %zu transactions (%s)\n\n", kr_timer_elapsed(&timer_delete) * 1000, rw_txn_count, knot_strerror(ret)); - rrtype_dynarray_free(&deleted_rrtypes); - entry_dynarray_deep_free(&to_del.to_delete); + array_clear(deleted_rrtypes); + entry_array_deep_free(&to_del.to_delete); // OK, let's close it in this case. kr_cache_gc_free_state(state); |