<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/65312>65312</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libfuzzer] FuzzedDataProvider consumeFloatingPointInRange can return potentially invalid results.
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
br-lewis
</td>
</tr>
</table>
<pre>
I've noticed that in certain circumstances `consumeFloatingPointInRange` can return a float or double that's greater than the given `max` value. This can be both infinity or a finite value that's greater than max. I'm submitting a bug rather than a fix because I'm not sure if you would consider this an issue.
# Steps to reproduce
1. Add these tests to `compiler-rt/lib/fuzzer/tests/FuzzedDataProviderUnittest.cpp`
```
TEST(FuzzedDataProvider, ConsumeFloatingPointInRangeInfinityResult) {
const uint8_t fuzz_data[] = {
0xff, // true for call to ConsumeBool
0xff, 0xff, 0xff, 0xff, // max int for call to ConsumeIntegral
};
FuzzedDataProvider DataProvider(fuzz_data, sizeof(fuzz_data));
float min = -130363940359280487072189884884913750016.000000;
float max = 340282346638528859811704183484516925440.000000;
float result = DataProvider.ConsumeFloatingPointInRange<float>(min, max);
ASSERT_FLOAT_EQ(result, max);
ASSERT_EQ(result, max);
}
TEST(FuzzedDataProvider, ConsumeFloatingPointInRangeFiniteResult) {
const uint8_t fuzz_data[] = {
0xff, // true for call to ConsumeBool
0xff, 0xff, 0xff, 0xff, // max int for call to ConsumeIntegral
};
FuzzedDataProvider DataProvider(fuzz_data, sizeof(fuzz_data));
float min = -317596856862626935824257237918882463744.00000000000000000;
float max = 22690334736495996280219465965285408768.00000000000000000;
float result = DataProvider.ConsumeFloatingPointInRange<float>(min, max);
ASSERT_FLOAT_EQ(max, result);
ASSERT_EQ(max, result);
}
```
2. Build and run the tests
# Why this might not be a bug
Both of these tests pass the `ASSERT_FLOAT_EQ` check which the rest of the unit tests use when dealing with floats and that assert will call `gtest`'s [`AlmostEquals`](https://github.com/google/googletest/blob/main/googletest/include/gtest/internal/gtest-internal.h#L330-L343) function which considers both of these cases as correct.
```
// Returns true if and only if this number is at most kMaxUlps ULP's away
// from rhs. In particular, this function:
//
// - returns false if either number is (or both are) NAN.
// - treats really large numbers as almost equal to infinity.
// - thinks +0.0 and -0.0 are 0 DLP's apart.
```
So would you consider it valid for `consumeFloatingPointInRange` to return numbers greater than `max`, including infinity in very cases of a very large `max`?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzcV1mPpLAR_jXul1IjY3OYh36Yq6WRNpvNzqzyuDJQ3Thr7I5t5thfH9nAHDtHpChSpKBWA6b8UfW5XPUhvVdHg7gj5TkpLzdyCoN1u9ZtNd4rv2lt_7i7Jqy-QzA2qA57CIMMoAx06IKMZ-W6afRBmg49kIp21vhpxL22Mihz_GaVCdfmuzRHJBWFThpwGCZnQMIhGoF10Nup1ZjACas9HB3KgC4OGAgDwlHdoYnwo3yIMHdST5jB7aB8gmwRWhsGUOagjAqPEVRCusbZ-APwUT5kEGMcwU_tqEJ0GiS00xGcDMNqF8EeoMVOTh6XCcYG8JNDUAd4tBPc20n3EAlQfZqnPEgDyvsJM0IvCT1b_hmHm4AnD8GCw5Oz_dTh_CzP4KyPPKNHCOhDMkrEjiel0W1dIGyvVUvY_jD9_o2OsH0yJGy_jwP9pQzym7N30Y0fRoX4NOtOJ1LRxYGKLr90e3t1c0uYeDuZsAu4-HhBrxe2v6OfdCCsAVKfz5CQeAgwKRPEzwDR05-9DHLONSD88qVxPOjD4RBf-PYgbE_YHoKbEA7WQSe1jqwsrp1bqxegFeOj84I0ygdQJrwHdm0CHp1cAYHUl4Svfr5lCF7TJZ7jZBfg1W-0h9ejTfytgOtL5o0wKpN42eac8oo3BeVlwwQtRE1rlotGiEKIosl5XVKaVxlNx7N7K458SDi8oEwwXlQVFyUTomxEnte0yAUvRFHmVcPKoqB_wrwGc2ltE97LULNP0oLwizSX8CvCxKhM5CJu3LeRn93cXH2__bn_8tez259XfyNMuCWX3syA1fhzs7heL97wn6b2PpWO_-PEfpnXq7P_7fR-k9g8r8umEmUlKlaxquGlYAUra8brJhdCsKLidVEsGfni-DDHGasaynlR86poyqapmKAsb4qqbKqSibKgoq7EJ4D_22xPdhewZvNH2f6h2XO2v67oLIPzSekepOnBTXMTnZvEH33o78Pj3KlGdRxC6mktzg3wpel57K728KovnaT3CZhU9M_QYqsfsPsF94PqhmTl0IcFAiajwoIS--n9gAZ6lDo233sVhnk5fHI_SQ7pPboA90rrObFJRY8RIIYcu3rcfhU906P14eqfk9Q-PikvCRNDCCdP-Nm8R44qDFObdXaMN9YeNT5dJEC2b7WN3XWUcTFfP1Km01OfZjyNBHRG6nVouw5kA2H8C-d0-4UXPBaRw2S6oKxZSFmVgp-1yxO7nfToQXrorHPYhezdJX6qHt-TnPJzFVGHxJk1-jFep5U109iig6hGAkR-4Ndf5MMPffLw48u3xJ68l49rYZhRD86O4AafAVwbOEkXVDdpmepmQl2DicS-cugP9wC2i-LzcJDaJx9RJWn17BlhwrqZB-kwkvX17Gv2DlSI6s2DQ6n1I2jpjrjAJMpkSgDAmAGx-K2C8F2oQZlf8dXnNKOJtm26cAgULldmYujvr8D8f2MX4Rcl4JP4UyHKTtWnSvzvZXHSgUkVr7G8UqlPwjeyP6dg3ClPalcZuEP3uGSOPYCc72d6nmfz_abf8b7hjdzgLq8a3kRFUG2GXYUMOy7loaBFyfK8a5qa866WBWLFK9yoHaOM04aWeU7zosqoLLDuRVOUQvactaSgOEqlM63vxsy64yYp311V8pxttGxR-_SpwZjB-1kWE8bil4fbxTnbdjp6UlCtfPDPKEEFnb5RtGoXwVtevterPuH45XfHyQY0QaX8UWZepbmy-mwzOb37pF5Ep5bT9uTsP7BLJSCGEuV3CvVfAQAA__91ySA4">