RFR: 8352112: [ubsan] hotspot/share/code/relocInfo.cpp:130:37: runtime error: applying non-zero offset 18446744073709551614 to null pointer [v2]
Boris Ulasevich
bulasevich at openjdk.org
Thu Mar 20 10:49:09 UTC 2025
On Wed, 19 Mar 2025 17:18:50 GMT, Vladimir Kozlov <kvn at openjdk.org> wrote:
>> src/hotspot/share/code/codeBlob.cpp line 156:
>>
>>> 154: } else {
>>> 155: // We need unique and valid not null address
>>> 156: _mutable_data = blob_end();
>>
>> It makes me a little nervous pointing this value to real data. When RelocIterator computes `_current = nm->relocation_begin() - 1`, it should never read or write from that address, but how can we guarantee that? Any non-null address that is guarateed unmapped would do, or a special protetected page like `bad_page` here: https://github.com/openjdk/jdk/blob/8e530633a9d99d7ce585cafd5573cb89212feee7/src/hotspot/share/runtime/safepointMechanism.cpp#L66. If using protected memory seems like overkill, then I suggest using a static. Something like this:
>>
>> static union {
>> relocInfo _dummy[1];
>> } _empty[2];
>> [...]
>> _mutable_data = _empty+1;
>>
>> However, I think this is not the first time we have run into this issue with RelocIterator. Maybe it's time that we rewrote it to avoid this situation?
>
> How about this?:
>
> +++ b/src/hotspot/share/code/relocInfo.cpp
> @@ -117,6 +117,8 @@ void relocInfo::change_reloc_info_for_address(RelocIterator *itr, address pc, re
> // Implementation of RelocIterator
>
> +static relocInfo dummy_reloc[2];
> +
> void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
> initialize_misc();
>
> @@ -127,8 +129,14 @@ void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
> guarantee(nm != nullptr, "must be able to deduce nmethod from other arguments");
>
> _code = nm;
> - _current = nm->relocation_begin() - 1;
> - _end = nm->relocation_end();
> + // Check for no relocations case and use dummy data to avoid referencing wrong data.
> + if (nm->relocation_size() == 0) {
> + _current = dummy_reloc;
> + _end = dummy_reloc + 1;
> + } else {
> + _current = nm->relocation_begin() - 1;
> + _end = nm->relocation_end();
> + }
> _addr = nm->content_begin();
>
> // Initialize code sections.
>
>
> I filed RFE: [JDK-8352426](https://bugs.openjdk.org/browse/JDK-8352426)
We can just add nullptr checks before pointer arithmetic in relocInfo:
diff --git a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp
index 7aae32759dd..c694f21e5ca 100644
--- a/src/hotspot/share/code/relocInfo.cpp
+++ b/src/hotspot/share/code/relocInfo.cpp
@@ -127,7 +127,8 @@ void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
guarantee(nm != nullptr, "must be able to deduce nmethod from other arguments");
_code = nm;
- _current = nm->relocation_begin() - 1;
+ _current = nm->relocation_begin();
+ if (_current != nullptr) { _current--; }
_end = nm->relocation_end();
_addr = nm->content_begin();
diff --git a/src/hotspot/share/code/relocInfo.hpp b/src/hotspot/share/code/relocInfo.hpp
index 25cca49e50b..b440e713493 100644
--- a/src/hotspot/share/code/relocInfo.hpp
+++ b/src/hotspot/share/code/relocInfo.hpp
@@ -603,7 +603,7 @@ class RelocIterator : public StackObj {
// get next reloc info, return !eos
bool next() {
- _current++;
+ if (_current != nullptr) { _current++; }
assert(_current <= _end, "must not overrun relocInfo");
if (_current == _end) {
set_has_current(false);
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/24102#discussion_r2005301702
More information about the hotspot-compiler-dev
mailing list