RFR: 8281213: Unsafe uses of long and size_t in MemReporterBase::diff_in_current_scale

David Holmes dholmes at openjdk.org
Tue Dec 6 03:10:58 UTC 2022


On Mon, 5 Dec 2022 13:54:57 GMT, Afshin Zafari <duke at openjdk.org> wrote:

> ### Description
> MemReporterBase::diff_in_current_scale is defined as follows:
> 
>   inline long diff_in_current_scale(size_t s1, size_t s2) const {
>     long amount = (long)(s1 - s2);
>     long scale = (long)_scale;
>     amount = (amount > 0) ? (amount + scale / 2) : (amount - scale / 2);
>     return amount / scale;
>   }
> 
> Long and size_t can have different sizes: 4 bytes and 8 bytes (LLP64). The result of 's1 - s2' might not fit into long. It might not fit into int64_t. For example: s1 is SIZE_MAX and s2 is SIZE_MAX-MAX_INT64-1.
> 
> Size_t should be used instead of long. Assertions must be added to check:
> s1 >= s2 and (amount - scale/2) >= 0 and (amount + scale/2) <= SIZE_MAX.
> 
> ### Patch
> `long` is replaced by `size_t`. Comparison to 0 is implemented accordingly since size_t is always >= 0.
> Since s1 can be less than s2 in some invocations of this method, no assert is written for `(s1 >= s2)` case.
> 
> ### Test
> local: runtime/NMT/Jcmd*
> mach5: tier1

Changes requested by dholmes (Reviewer).

src/hotspot/share/services/memReporter.hpp line 76:

> 74:     size_t amount = s1 - s2;
> 75:     if (s1 >= s2) {
> 76:       assert((amount + _scale / 2) <= SIZE_MAX, "difference is gretaer than the upper limit.");

That assertion can never fail - any size_t arithmetic expression must be <= SIZE_MAX. You need to detect overflow/wrap-around a different way.

Typo: gretaer

-------------

PR: https://git.openjdk.org/jdk/pull/11514


More information about the hotspot-runtime-dev mailing list