diff --git a/configure b/configure index 641657b12..2b4149c0c 100755 --- a/configure +++ b/configure @@ -4462,11 +4462,6 @@ $as_echo "no" >&6; } fi -# ommit -O2 for clang because of optimizer failures (in expi-incep in -# the signature serial timestamp checks.) -if $CC --version 2>&1 | grep "clang" >/dev/null; then - : -else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -O2" >&5 @@ -4500,7 +4495,6 @@ fi default_cflags=yes fi -fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' diff --git a/configure.ac b/configure.ac index 4517b1c20..07ef4a40f 100644 --- a/configure.ac +++ b/configure.ac @@ -249,15 +249,9 @@ AC_LANG_C default_cflags=no if test "x$CFLAGS" = "x" ; then ACX_CHECK_COMPILER_FLAG(g, [CFLAGS="$CFLAGS -g"]) -# ommit -O2 for clang because of optimizer failures (in expi-incep in -# the signature serial timestamp checks.) -if $CC --version 2>&1 | grep "clang" >/dev/null; then - : -else ACX_CHECK_COMPILER_FLAG(O2, [CFLAGS="$CFLAGS -O2"]) default_cflags=yes fi -fi AC_PROG_CC ACX_DEPFLAG ACX_DETERMINE_EXT_FLAGS_UNBOUND diff --git a/doc/Changelog b/doc/Changelog index 9036882eb..16f3cacdb 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -3,6 +3,8 @@ away, without a repeat query picking the DS from cache. The correct reply should have been an answer, the reply is fixed by the scrubber to have the answer in the answer section. + - Remove clang optimizer disable, + Fix that expiration date checks don't fail with clang -O2. 15 December 2017: Wouter - Fix timestamp failure because of clang optimizer failure, by diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c index 82ef6a85c..b73daf3e5 100644 --- a/validator/val_sigcrypt.c +++ b/validator/val_sigcrypt.c @@ -1204,14 +1204,47 @@ sigdate_error(const char* str, int32_t expi, int32_t incep, int32_t now) (unsigned)incep, (unsigned)now); } +/** RFC 1918 comparison, uses unsigned integers, and tries to avoid + * compiler optimization (eg. by avoiding a-b<0 comparisons), + * this routine matches compare_serial(), for SOA serial number checks */ +static int +compare_1918(uint32_t a, uint32_t b) +{ + /* for 32 bit values */ + const uint32_t cutoff = ((uint32_t) 1 << (32 - 1)); + + if (a == b) { + return 0; + } else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) { + return -1; + } else { + return 1; + } +} + +/** if we know that b is larger than a, return the difference between them, + * that is the distance between them. in RFC1918 arith */ +static uint32_t +subtract_1918(uint32_t a, uint32_t b) +{ + /* for 32 bit values */ + const uint32_t cutoff = ((uint32_t) 1 << (32 - 1)); + + if(a == b) + return 0; + if(a < b && b - a < cutoff) { + return b-a; + } + return a-b; +} + /** check rrsig dates */ static int check_dates(struct val_env* ve, uint32_t unow, uint8_t* expi_p, uint8_t* incep_p, char** reason) { /* read out the dates */ - int32_t expi, incep, now; - int32_t incepminexpi; + uint32_t expi, incep, now; memmove(&expi, expi_p, sizeof(expi)); memmove(&incep, incep_p, sizeof(incep)); expi = ntohl(expi); @@ -1225,22 +1258,21 @@ check_dates(struct val_env* ve, uint32_t unow, } now = ve->date_override; verbose(VERB_ALGO, "date override option %d", (int)now); - } else now = (int32_t)unow; + } else now = unow; /* check them */ - incepminexpi = incep-expi; - if(incepminexpi > 0) { + if(compare_1918(incep, expi) > 0) { sigdate_error("verify: inception after expiration, " "signature bad", expi, incep, now); *reason = "signature inception after expiration"; return 0; } - if(incep - now > 0) { + if(compare_1918(incep, now) > 0) { /* within skew ? (calc here to avoid calculation normally) */ - int32_t skew = (expi-incep)/10; - if(skew < ve->skew_min) skew = ve->skew_min; - if(skew > ve->skew_max) skew = ve->skew_max; - if(incep - now > skew) { + uint32_t skew = subtract_1918(incep, expi)/10; + if(skew < (uint32_t)ve->skew_min) skew = ve->skew_min; + if(skew > (uint32_t)ve->skew_max) skew = ve->skew_max; + if(subtract_1918(now, incep) > skew) { sigdate_error("verify: signature bad, current time is" " before inception date", expi, incep, now); *reason = "signature before inception date"; @@ -1249,11 +1281,11 @@ check_dates(struct val_env* ve, uint32_t unow, sigdate_error("verify warning suspicious signature inception " " or bad local clock", expi, incep, now); } - if(now - expi > 0) { - int32_t skew = (expi-incep)/10; - if(skew < ve->skew_min) skew = ve->skew_min; - if(skew > ve->skew_max) skew = ve->skew_max; - if(now - expi > skew) { + if(compare_1918(now, expi) > 0) { + uint32_t skew = subtract_1918(incep, expi)/10; + if(skew < (uint32_t)ve->skew_min) skew = ve->skew_min; + if(skew > (uint32_t)ve->skew_max) skew = ve->skew_max; + if(subtract_1918(expi, now) > skew) { sigdate_error("verify: signature expired", expi, incep, now); *reason = "signature expired";