diff options
-rw-r--r-- | changes/bug13290-avoid-div-zero-circuitstatus-pareto | 5 | ||||
-rw-r--r-- | src/or/circuitstats.c | 16 |
2 files changed, 20 insertions, 1 deletions
diff --git a/changes/bug13290-avoid-div-zero-circuitstatus-pareto b/changes/bug13290-avoid-div-zero-circuitstatus-pareto new file mode 100644 index 0000000000..42b121f9dd --- /dev/null +++ b/changes/bug13290-avoid-div-zero-circuitstatus-pareto @@ -0,0 +1,5 @@ + o Minor bugfixes: + - In circuit_build_times_calculate_timeout() in circuitstats.c, avoid + dividing by zero in the pareto calculations. This traps under + clang -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error. + Fixes bug 13290. diff --git a/src/or/circuitstats.c b/src/or/circuitstats.c index c24259c22c..5336e4046e 100644 --- a/src/or/circuitstats.c +++ b/src/or/circuitstats.c @@ -1085,7 +1085,21 @@ circuit_build_times_calculate_timeout(circuit_build_times_t *cbt, tor_assert(1.0-quantile > 0); tor_assert(cbt->Xm > 0); - ret = cbt->Xm/pow(1.0-quantile,1.0/cbt->alpha); + /* If either alpha or p are 0, we would divide by zero, yielding an + * infinite (double) result; which would be clamped to INT32_MAX. + * Instead, initialise ret to INT32_MAX, and skip over these + * potentially illegal/trapping divides by zero. + */ + ret = INT32_MAX; + + if (cbt->alpha > 0) { + double p; + p = pow(1.0-quantile,1.0/cbt->alpha); + if (p > 0) { + ret = cbt->Xm/p; + } + } + if (ret > INT32_MAX) { ret = INT32_MAX; } |