From 23d70bde6c027a44d5d82a6120f3f8211edc3f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayd=C4=B1n=20Mercan?= Date: Thu, 29 May 2025 10:50:25 +0000 Subject: [PATCH 1/2] add attribute macro for counted_by Using C23 attributes for `counted_by` is broken with clang. `__has_attribute` is used since `__has_c_attribute` only works with C23 attributes, (`gnu::counted_by`/`clang::counted_by`) --- lib/isc/include/isc/attributes.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/isc/include/isc/attributes.h b/lib/isc/include/isc/attributes.h index eb1bb53e2e..96d57f9f49 100644 --- a/lib/isc/include/isc/attributes.h +++ b/lib/isc/include/isc/attributes.h @@ -14,12 +14,16 @@ #pragma once /*** - *** Clang Compatibility Macros + *** Attribute Compatibility Macros ***/ -#if !defined(__has_c_attribute) +#ifndef __has_c_attribute #define __has_c_attribute(x) 0 -#endif /* if !defined(__has_c_attribute) */ +#endif /* __has_c_attribute */ + +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif /* __has_attribute */ #if __has_c_attribute(noreturn) && __STDC_VERSION__ >= 202311L #define ISC_NORETURN [[noreturn]] @@ -102,3 +106,9 @@ #else #define ISC_ATTR_UNUSED __attribute__((__unused__)) #endif + +#if __has_attribute(__counted_by__) +#define ISC_ATTR_COUNTED_BY(x) __attribute__((__counted_by__(x))) +#else +#define ISC_ATTR_COUNTED_BY(x) +#endif From 408190fd3bf81a763f02d7008f2874ce61ca228b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ayd=C4=B1n=20Mercan?= Date: Thu, 29 May 2025 11:03:11 +0000 Subject: [PATCH 2/2] use proper flexible arrays in rrl The single-element array hack can trip newer sanitizers or fortification levels. --- lib/dns/include/dns/rrl.h | 9 ++++++--- lib/dns/rrl.c | 38 +++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/lib/dns/include/dns/rrl.h b/lib/dns/include/dns/rrl.h index aef47a7345..6c5be512fd 100644 --- a/lib/dns/include/dns/rrl.h +++ b/lib/dns/include/dns/rrl.h @@ -19,6 +19,9 @@ #include #include +#include + +#include #include #include @@ -157,7 +160,7 @@ struct dns_rrl_hash { isc_stdtime_t check_time; unsigned int gen : DNS_RRL_HASH_GEN_BITS; int length; - dns_rrl_bin_t bins[1]; + dns_rrl_bin_t bins[] ISC_ATTR_COUNTED_BY(length); }; /* @@ -166,8 +169,8 @@ struct dns_rrl_hash { typedef struct dns_rrl_block dns_rrl_block_t; struct dns_rrl_block { ISC_LINK(dns_rrl_block_t) link; - int size; - dns_rrl_entry_t entries[1]; + uint32_t count; + dns_rrl_entry_t entries[] ISC_ATTR_COUNTED_BY(count); }; /* diff --git a/lib/dns/rrl.c b/lib/dns/rrl.c index dc91711c0c..c936bc724d 100644 --- a/lib/dns/rrl.c +++ b/lib/dns/rrl.c @@ -205,7 +205,6 @@ set_age(dns_rrl_t *rrl, dns_rrl_entry_t *e, isc_stdtime_t now) { static isc_result_t expand_entries(dns_rrl_t *rrl, int newsize) { - unsigned int bsize; dns_rrl_block_t *b; dns_rrl_entry_t *e; double rate; @@ -237,10 +236,11 @@ expand_entries(dns_rrl_t *rrl, int newsize) { rrl->hash->length, rate); } - bsize = sizeof(dns_rrl_block_t) + - ISC_CHECKED_MUL((newsize - 1), sizeof(dns_rrl_entry_t)); - b = isc_mem_cget(rrl->mctx, 1, bsize); - b->size = bsize; + b = isc_mem_cget(rrl->mctx, 1, STRUCT_FLEX_SIZE(b, entries, newsize)); + *b = (dns_rrl_block_t){ + .link = ISC_LINK_INITIALIZER, + .count = newsize, + }; e = b->entries; for (i = 0; i < newsize; ++i, ++e) { @@ -274,16 +274,14 @@ free_old_hash(dns_rrl_t *rrl) { } isc_mem_put(rrl->mctx, old_hash, - sizeof(*old_hash) + - ISC_CHECKED_MUL((old_hash->length - 1), - sizeof(old_hash->bins[0]))); + STRUCT_FLEX_SIZE(old_hash, bins, old_hash->length)); rrl->old_hash = NULL; } static isc_result_t expand_rrl_hash(dns_rrl_t *rrl, isc_stdtime_t now) { dns_rrl_hash_t *hash; - int old_bins, new_bins, hsize; + int old_bins, new_bins; double rate; if (rrl->old_hash != NULL) { @@ -301,12 +299,13 @@ expand_rrl_hash(dns_rrl_t *rrl, isc_stdtime_t now) { } new_bins = hash_divisor(new_bins); - hsize = sizeof(dns_rrl_hash_t) + - ISC_CHECKED_MUL((new_bins - 1), sizeof(hash->bins[0])); - hash = isc_mem_cget(rrl->mctx, 1, hsize); - hash->length = new_bins; rrl->hash_gen ^= 1; - hash->gen = rrl->hash_gen; + hash = isc_mem_cget(rrl->mctx, 1, + STRUCT_FLEX_SIZE(hash, bins, new_bins)); + *hash = (dns_rrl_hash_t){ + .length = new_bins, + .gen = rrl->hash_gen, + }; if (isc_log_wouldlog(DNS_RRL_LOG_DROP) && old_bins != 0) { rate = rrl->probes; @@ -1283,21 +1282,18 @@ dns_rrl_view_destroy(dns_view_t *view) { ISC_LIST_FOREACH (rrl->blocks, b, link) { ISC_LIST_UNLINK(rrl->blocks, b, link); - isc_mem_put(rrl->mctx, b, b->size); + isc_mem_put(rrl->mctx, b, + STRUCT_FLEX_SIZE(b, entries, b->count)); } h = rrl->hash; if (h != NULL) { - isc_mem_put(rrl->mctx, h, - sizeof(*h) + ISC_CHECKED_MUL((h->length - 1), - sizeof(h->bins[0]))); + isc_mem_put(rrl->mctx, h, STRUCT_FLEX_SIZE(h, bins, h->length)); } h = rrl->old_hash; if (h != NULL) { - isc_mem_put(rrl->mctx, h, - sizeof(*h) + ISC_CHECKED_MUL((h->length - 1), - sizeof(h->bins[0]))); + isc_mem_put(rrl->mctx, h, STRUCT_FLEX_SIZE(h, bins, h->length)); } isc_mem_putanddetach(&rrl->mctx, rrl, sizeof(*rrl));