summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOto Šťáva <oto.stava@nic.cz>2024-05-20 13:01:04 +0200
committerOto Šťáva <oto.stava@nic.cz>2024-05-20 13:01:04 +0200
commit8827536a27b27d011fb005f1898c4c74d0d972e1 (patch)
tree9762e19adbd9887415db0807864e27c5f3cdb940
parent.gitlab-ci: remove SonarCloud Scanner (diff)
parentdaemon/tls_ephemeral_credentials: fix possible race between read() and fstat() (diff)
downloadknot-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.yml1
-rw-r--r--contrib/dynarray.h112
-rw-r--r--contrib/dynarray.spdx10
-rw-r--r--daemon/tls_ephemeral_credentials.c2
-rw-r--r--modules/hints/hints.c2
-rw-r--r--utils/cache_gc/kr_cache_gc.c66
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);