]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
kr_random_coin: do not crash on invalid values
authorPetr Špaček <petr.spacek@nic.cz>
Mon, 10 Dec 2018 17:43:00 +0000 (18:43 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 11 Dec 2018 11:19:44 +0000 (12:19 +0100)
lib/utils.h

index fb59236b62e2dfc0cbbb40b287e5ff5c88117121..0ec283b0c8266ae8ba2f733aca9b288eb6b2e6a2 100644 (file)
@@ -189,7 +189,7 @@ KR_EXPORT
 void kr_rnd_buffered(void *data, unsigned int size);
 
 /** Return a few random bytes. */
-static inline uint64_t kr_rand_bytes(int size)
+static inline uint64_t kr_rand_bytes(unsigned int size)
 {
        uint64_t result;
        if (size <= 0 || size > sizeof(result)) {
@@ -204,25 +204,27 @@ static inline uint64_t kr_rand_bytes(int size)
         * (Tested via reading assembly from usual gcc -O2 setup.)
         * Alternatively we could waste more rnd bytes, but that seemed worse. */
        result = 0;
-       for (int i = 0; i < size; ++ i) {
+       for (unsigned int i = 0; i < size; ++ i) {
                result |= ((size_t)data[i]) << (i * 8);
        }
        return result;
 }
 
 /** Throw a pseudo-random coin, succeeding approximately with probability nomin/denomin.
- * - low precision, only one byte of randomness
- * - the most extreme bias is 1:255
+ * - low precision, only one byte of randomness (or none with extreme parameters)
  * - tip: use !kr_rand_coin() to get the complementary probability
  */
-static inline bool kr_rand_coin(int nomin, int denomin)
+static inline bool kr_rand_coin(unsigned int nomin, unsigned int denomin)
 {
-       if (nomin < 0 || denomin <= 0 || nomin > denomin) {
-               kr_log_error("kr_rand_coin(): EINVAL\n");
-               abort();
-       }
+       /* This function might be called with non-constant values
+        * so we try to handle odd corner cases instead of crash. */
+       if (nomin >= denomin)
+               return true;
+       else if (nomin <= 0)
+               return false;
+
        /* threshold = how many parts from 256 are a success */
-       int threshold = (nomin * 256 + /*rounding*/ denomin / 2) / denomin;
+       unsigned int threshold = (nomin * 256 + /*rounding*/ denomin / 2) / denomin;
        if (threshold == 0) threshold = 1;
        if (threshold == 256) threshold = 255;
        return (kr_rand_bytes(1) < threshold);