-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8331731: ubsan: relocInfo.cpp:155:30: runtime error: applying non-zero offset 18446744073709551614 to null pointer #19424
Conversation
👋 Welcome back mbaesken! A progress list of the required criteria for merging this PR into |
❗ This change is not yet ready to be integrated. |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An idea to fix it is to avoid pointer arithmetic. E.g.
diff --git a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp
index d0f732edac4..b6e1517aefd 100644
--- a/src/hotspot/share/code/relocInfo.cpp
+++ b/src/hotspot/share/code/relocInfo.cpp
@@ -152,7 +152,7 @@ RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
initialize_misc();
assert(((cs->locs_start() != nullptr) && (cs->locs_end() != nullptr)) ||
((cs->locs_start() == nullptr) && (cs->locs_end() == nullptr)), "valid start and end pointer");
- _current = cs->locs_start()-1;
+ _current = (relocInfo*)((uintptr_t)cs->locs_start() - sizeof(relocInfo));
_end = cs->locs_end();
_addr = cs->start();
_code = nullptr; // Not cb->blob();
diff --git a/src/hotspot/share/code/relocInfo.hpp b/src/hotspot/share/code/relocInfo.hpp
index 6d0907d97de..1774c8ac62a 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++;
+ _current = (relocInfo*)((uintptr_t)_current + sizeof(relocInfo));
assert(_current <= _end, "must not overrun relocInfo");
if (_current == _end) {
set_has_current(false);
Doesn't look very nice, but should work.
I agree, it does not look very nice. Not sure what is better, disabling ubsan for the methods or use the code you suggested. |
I prefer @TheRealMDoerr suggestion vs disabling ubsan check for this code. It should be compiled to the same assembler.
|
We could consider using a sentinel value instead of nullptr, but it would require more changes. |
What you think about using some helper templates or macros like this, doing what Martin suggested ?
|
|
Makes sense to use something unsigned. |
I would suggest |
I'm not fully convinced that this is good idea. While reading this patch, it is not clear to me that it is correct to hide the warning that ubsan has found. Maybe it is, but I don't see any explanation here showing why it is OK to subtract or add against null here. This is one reason why I'm reluctant to see these functions getting put into globalDefinitions.hpp. I think that there's a risk that people will start to use these functions without making a full analysis to see if there really is a bug that needs to be solved, if there are some code quality improvements that could be done to get rid of the null pointer, or if it is in fact something that we just want to silence the warning for. If you really want to go ahead and add these functions, I would like to see them get more descriptive names that explain why they are used instead of plain ++ and --. For example: |
We're not hiding a warning. Using pointer addition with |
This seems to be the same as JDK-8300821. (Changeset 01312a0) The miss here seems to be that --- a/src/hotspot/share/asm/codeBuffer.cpp
+++ b/src/hotspot/share/asm/codeBuffer.cpp
@@ -525,7 +525,7 @@ void CodeBuffer::finalize_oop_references(const methodHandle& mh) {
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
// pull code out of each section
CodeSection* cs = code_section(n);
- if (cs->is_empty() || !cs->has_locs()) continue; // skip trivial section
+ if (cs->is_empty() || cs->locs_count() == 0) continue; // skip trivial section
RelocIterator iter(cs);
while (iter.next()) {
if (iter.type() == relocInfo::metadata_type) {
@@ -793,7 +793,7 @@ void CodeBuffer::relocate_code_to(CodeBuffer* dest) const {
for (int n = (int) SECT_FIRST; n < (int)SECT_LIMIT; n++) {
// pull code out of each section
const CodeSection* cs = code_section(n);
- if (cs->is_empty() || !cs->has_locs()) continue; // skip trivial section
+ if (cs->is_empty() || cs->locs_count() == 0) continue; // skip trivial section
CodeSection* dest_cs = dest->code_section(n);
{ // Repair the pc relative information in the code after the move
RelocIterator iter(dest_cs);
@@ -1057,7 +1057,7 @@ void CodeSection::print(const char* name) {
name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity());
tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d",
name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off());
- if (PrintRelocations) {
+ if (PrintRelocations && locs_size != 0) {
RelocIterator iter(this);
iter.print();
} There is also the following which perhaps should assert that there is a relocation at the call pc. As it makes some assumptions about being able to patch its type. (I am not familiar with this code.) jdk/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp Line 434 in 4acafb8
As for the So something would still have to be done about the ubsan. Much of this seems to be about optimising the Unsure if solving this by type casting is just hiding underlying design issues. |
I think you are reading too much into the words I used. Ubsan is warning/complaining/error that the code is problematic.
I fully understand the suggested patch.
This is the crux of my complaint. Is this a good design given that the usage of null isn't apparent on first read? Or was this only something that grew into existence after a while? And would it make more sense for maintainability to not be doing this? I think it is important to think about those questions when trying to handle all these ubsan failures. FWIW, I (and Axel) took a step back and asked why do we think it is necessary to support null pointers here and I think you can see the musing around in Axel's response above. |
Oh, and as it doesn't seem to have been clear from my earlier comments: I don't strongly oppose that you fix it this way you do in the RelocIterator, since I have very little interaction with that code. The comment was more that I would prefer if we take a case-by-case approach when we look at other parts of HotSpot with similar problems and really think what the correct solution would be, and that we don't too quickly start to grab for the |
We have to use pre-increment in I really don't want to add |
This suggestion seems correct because we may allocate relocation buffer in section which does not have relocations codeBuffer.cpp#L169. But this is different issue for different RFE. |
My stance is the same as @stefank that I do not oppose this change to fix the immediate issue. Looking closer at how the
It may be a different RFE, but it is the same issue (unless I am misunderstanding you are referring to). The |
So you want to patch the path which introduces
This seems reasonable. |
I believe using has_locs() is fine in relocate_code_to(). We just need to call it against |
I renamed the templates to sub / add_to_ptr_maybe_null . Maybe other changes could be done in a separate RFE . |
The other changes would render this RFE unnecessary because _current would then never contain a nullptr. |
I guess Matthias only wanted to fix UB in hotspot ASAP and doesn't have the bandwidth to change the design everywhere. Sounds like you guys already have an alternative solution which already works. Maybe you would like to put it into a PR and we continue the discussion there? |
Yes . |
The proposal solves the UB but (IMHO) adds a wart to the code instead of taking a small step back and fixing the root cause of the UB. This then leaves the wart for other maintainers fix with their own bandwidth.
I would prefer if we did the right fix here in this PR.
My previous arguments have been that I don't think it is a good thing, so our opinion here differs. How many places are there that really should be doing add/sub with nullptr? Are most places just like this PR, where using |
Well, you could ask Matthias. It's his PR. However, your new proposal doesn't have any code in common with the existing PR. So, what's the benefit of using this one?
No. They typically come up after fixing other ones. |
@MBaesken can close this PR and re-assign this bug to me if he don't have time to do proposed changes to code. |
I agree with @xmas92, and I propose a slight change to his fix:
|
It does not matter. Few lines above we copied relocation info to new buffer and there is assert in
|
Sounds good to me. |
Thank you, Vladimir! I appreciate it. |
New PR: #19525 |
When running on macOS with ubsan enabled, we see some issues in relocInfo (hpp and cpp); those already occur in the build quite early.
/jdk/src/hotspot/share/code/relocInfo.cpp:155:30: runtime error: applying non-zero offset 18446744073709551614 to null pointer
Similar happens when we add to the _current pointer
_current++;
this gives :
relocInfo.hpp:606:13: runtime error: applying non-zero offset to non-null pointer 0xfffffffffffffffe produced null pointer
Seems the pointer subtraction/addition worked so far, so it might be an option to disable ubsan for those 2 functions.
Progress
Warning
8331731: ubsan: relocInfo.cpp:155:30: runtime error: applying non-zero offset 18446744073709551614 to null pointer
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/19424/head:pull/19424
$ git checkout pull/19424
Update a local copy of the PR:
$ git checkout pull/19424
$ git pull https://git.openjdk.org/jdk.git pull/19424/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 19424
View PR using the GUI difftool:
$ git pr show -t 19424
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/19424.diff
Webrev
Link to Webrev Comment