commit 4d0ad34a92dff2be0b23e75ca5373054a5c9334a Author: teor teor2345@gmail.com Date: Mon Sep 29 20:24:40 2014 +1000
Avoid division by zero in circuitstats pareto
In circuit_build_times_calculate_timeout() in circuitstats.c, avoid dividing by zero in the pareto calculations.
If either the alpha or p parameters are 0, we would divide by zero, yielding an infinite result; which would be clamped to INT32_MAX anyway. So rather than dividing by zero, we just skip the offending calculation(s), and use INT32_MAX for the result.
Division by zero traps under clang -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error. --- changes/bug13290-avoid-div-zero-circuitstatus-pareto | 5 +++++ src/or/circuitstats.c | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/changes/bug13290-avoid-div-zero-circuitstatus-pareto b/changes/bug13290-avoid-div-zero-circuitstatus-pareto new file mode 100644 index 0000000..42b121f --- /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 c24259c..5336e40 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; }