2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 10:10:06 +00:00

Simplify add/sub/mul overflow checks

Use C23 stdckdint.h when available and define ckd_{mul,add,sub} shims to
__builtin_{mul,add,sub}_overflow().  Require the __builtin functions
unconditionally.
This commit is contained in:
Ondřej Surý 2025-08-05 08:19:20 +02:00
parent 0f57a4d6f5
commit 808340e1a3
No known key found for this signature in database
GPG Key ID: 2820F37E873DEA41
5 changed files with 42 additions and 59 deletions

View File

@ -319,7 +319,7 @@ keymgr_prepublication_time(dns_dnsseckey_t *key, dns_kasp_t *kasp,
return 0;
}
if (ISC_OVERFLOW_ADD(active, klifetime, &retire)) {
if (ckd_add(&retire, active, klifetime)) {
log_key_overflow(key->key, "retire");
retire = UINT32_MAX;
}
@ -424,7 +424,7 @@ keymgr_key_update_lifetime(dns_dnsseckey_t *key, dns_kasp_t *kasp,
uint32_t a = now;
uint32_t inactive;
(void)dst_key_gettime(key->key, DST_TIME_ACTIVATE, &a);
if (ISC_OVERFLOW_ADD(a, lifetime, &inactive)) {
if (ckd_add(&inactive, a, lifetime)) {
log_key_overflow(key->key, "inactive");
inactive = UINT32_MAX;
}
@ -1904,7 +1904,7 @@ keymgr_key_rollover(dns_kasp_key_t *kaspkey, dns_dnsseckey_t *active_key,
if (lifetime > 0) {
uint32_t inactive;
if (ISC_OVERFLOW_ADD(active, lifetime, &inactive)) {
if (ckd_add(&inactive, active, lifetime)) {
log_key_overflow(new_key->key, "inactive");
inactive = UINT32_MAX;
}

View File

@ -173,7 +173,7 @@ makeslab(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region,
*/
nalloc = nitems;
RUNTIME_CHECK(!ISC_OVERFLOW_MUL(nalloc, sizeof(rdata[0]), &rdatasize));
RUNTIME_CHECK(!ckd_mul(&rdatasize, nalloc, sizeof(rdata[0])));
rdata = isc_mem_get(mctx, rdatasize);
/*

View File

@ -17,63 +17,45 @@
#include <isc/util.h>
/*
* It is awkward to support signed numbers as well, so keep it simple
* (with a safety check).
*/
#define ISC_OVERFLOW_IS_UNSIGNED(a) \
({ \
STATIC_ASSERT((typeof(a))-1 > 0, \
"overflow checks require unsigned types"); \
(a); \
#if HAVE_STDCKDINT_H
#include <stdckdint.h>
#else /* HAVE_STDCKDINT_H */
#define ckd_mul(cp, a, b) __builtin_mul_overflow(a, b, cp)
#define ckd_add(cp, a, b) __builtin_add_overflow(a, b, cp)
#define ckd_sub(cp, a, b) __builtin_sub_overflow(a, b, cp)
#endif /* HAVE_STDCKDINT_H */
#define ISC_CHECKED_MUL(a, b) \
({ \
typeof(a) _c; \
bool _overflow = ckd_mul(&_c, a, b); \
INSIST(!_overflow); \
_c; \
})
#define ISC_OVERFLOW_UINT_MAX(a) ISC_OVERFLOW_IS_UNSIGNED((typeof(a))-1)
#define ISC_OVERFLOW_UINT_MIN(a) ISC_OVERFLOW_IS_UNSIGNED(0)
/*
* Return true on overflow, e.g.
*
* bool overflow = ISC_OVERFLOW_MUL(count, sizeof(array[0]), &bytes);
* INSIST(!overflow);
*/
#define ISC_OVERFLOW_MUL(a, b, cp) __builtin_mul_overflow(a, b, cp)
#define ISC_OVERFLOW_ADD(a, b, cp) __builtin_add_overflow(a, b, cp)
#define ISC_OVERFLOW_SUB(a, b, cp) __builtin_sub_overflow(a, b, cp)
#define ISC_CHECKED_MUL(a, b) \
({ \
typeof(a) _c; \
bool _overflow = ISC_OVERFLOW_MUL(a, b, &_c); \
INSIST(!_overflow); \
_c; \
#define ISC_CHECKED_ADD(a, b) \
({ \
typeof(a) _c; \
bool _overflow = ckd_add(&_c, a, b); \
INSIST(!_overflow); \
_c; \
})
#define ISC_CHECKED_ADD(a, b) \
({ \
typeof(a) _c; \
bool _overflow = ISC_OVERFLOW_ADD(a, b, &_c); \
INSIST(!_overflow); \
_c; \
#define ISC_CHECKED_SUB(a, b) \
({ \
typeof(a) _c; \
bool _overflow = ckd_sub(&_c, a, b); \
INSIST(!_overflow); \
_c; \
})
#define ISC_CHECKED_SUB(a, b) \
({ \
typeof(a) _c; \
bool _overflow = ISC_OVERFLOW_SUB(a, b, cp); \
INSIST(!_overflow); \
_c; \
})
#define ISC_CHECKED_MUL_ADD(a, b, c) \
({ \
size_t _d; \
bool _overflow = ISC_OVERFLOW_MUL(a, b, &_d) || \
ISC_OVERFLOW_ADD(_d, c, &_d); \
INSIST(!_overflow); \
_d; \
#define ISC_CHECKED_MUL_ADD(a, b, c) \
({ \
size_t _d; \
bool _overflow = ckd_mul(&_d, a, b) || ckd_add(&_d, _d, c); \
INSIST(!_overflow); \
_d; \
})

View File

@ -190,7 +190,7 @@ isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result) {
REQUIRE(t->nanoseconds < NS_PER_SEC && i->nanoseconds < NS_PER_SEC);
/* Seconds */
if (ISC_OVERFLOW_ADD(t->seconds, i->seconds, &result->seconds)) {
if (ckd_add(&result->seconds, t->seconds, i->seconds)) {
return ISC_R_RANGE;
}
@ -214,7 +214,7 @@ isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
REQUIRE(t->nanoseconds < NS_PER_SEC && i->nanoseconds < NS_PER_SEC);
/* Seconds */
if (ISC_OVERFLOW_SUB(t->seconds, i->seconds, &result->seconds)) {
if (ckd_sub(&result->seconds, t->seconds, i->seconds)) {
return ISC_R_RANGE;
}

View File

@ -525,6 +525,7 @@ foreach h : [
'net/if6.h',
'net/route.h',
'regex.h',
'stdckdint.h',
'sys/mman.h',
'sys/select.h',
'sys/sockio.h',