summaryrefslogtreecommitdiff
path: root/src/common/util.c
diff options
context:
space:
mode:
authorGeorge Kadianakis <desnacked@riseup.net>2015-01-15 14:36:24 +0000
committerGeorge Kadianakis <desnacked@riseup.net>2015-01-15 14:43:58 +0000
commit45bc5a07434376c0d801a547b38893d85a515b49 (patch)
tree3569b85366fbfabc6db75a3df054990e13a5ea59 /src/common/util.c
parent3668a4126e0c2502a77c2ba5d7885add489a964a (diff)
downloadtor-45bc5a07434376c0d801a547b38893d85a515b49.tar.gz
tor-45bc5a07434376c0d801a547b38893d85a515b49.zip
Restrict sample values of the Laplace distribution to int64_t.
This helps avoid undefined behavior from casting big double values to int64_t. Fixes #14090.
Diffstat (limited to 'src/common/util.c')
-rw-r--r--src/common/util.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/common/util.c b/src/common/util.c
index f7baab0791..be866a5fe6 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -527,15 +527,25 @@ round_int64_to_next_multiple_of(int64_t number, int64_t divisor)
/** Transform a random value <b>p</b> from the uniform distribution in
* [0.0, 1.0[ into a Laplace distributed value with location parameter
- * <b>mu</b> and scale parameter <b>b</b> in [-Inf, Inf[. */
-double
+ * <b>mu</b> and scale parameter <b>b</b>. Truncate the final result
+ * to be an integer in [INT64_MIN, INT64_MAX]. */
+int64_t
sample_laplace_distribution(double mu, double b, double p)
{
+ double result;
+
tor_assert(p >= 0.0 && p < 1.0);
/* This is the "inverse cumulative distribution function" from:
* http://en.wikipedia.org/wiki/Laplace_distribution */
- return mu - b * (p > 0.5 ? 1.0 : -1.0)
- * tor_mathlog(1.0 - 2.0 * fabs(p - 0.5));
+ result = mu - b * (p > 0.5 ? 1.0 : -1.0)
+ * tor_mathlog(1.0 - 2.0 * fabs(p - 0.5));
+
+ if (result >= INT64_MAX)
+ return INT64_MAX;
+ else if (result <= INT64_MIN)
+ return INT64_MIN;
+ else
+ return (int64_t) result;
}
/** Add random noise between INT64_MIN and INT64_MAX coming from a
@@ -546,10 +556,10 @@ int64_t
add_laplace_noise(int64_t signal, double random, double delta_f,
double epsilon)
{
- /* cast to int64_t intended */
int64_t noise = sample_laplace_distribution(
0.0, /* just add noise, no further signal */
delta_f / epsilon, random);
+
if (noise > 0 && INT64_MAX - noise < signal)
return INT64_MAX;
else if (noise < 0 && INT64_MIN - noise > signal)