-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
8297967: Make frame::safe_for_sender safer #11461
Conversation
👋 Welcome back parttimenerd! A progress list of the required criteria for merging this PR into |
@parttimenerd The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
I converted it back to a draft and look into next week with more vigor. |
a890300
to
f776255
Compare
My new version just uses |
The issue might happen when ASGCT (and my ASGST for which I wrote a fuzzer) are called with modified sp and fp, which async-profiler might do. |
I added a few more safe fetches, safe_for_sender should now be guarded against any broken fp. |
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.
Quite a few SafeFetch checks! But it's only used for profiling purposes, so checking a bit more sounds ok to me. Let's hear what other people think.
Please update the description and the JBS issue according to your new version and describe how broken values may reach this function.
@parttimenerd This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
This is ongoing work. |
@parttimenerd this pull request can not be integrated into git checkout parttimenerd_8297967
git fetch https://git.openjdk.org/jdk master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push |
@parttimenerd This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
971553f
to
98afe54
Compare
I'm still trying to understand the underlying problem. I guess that FP points into a read protected (or uncommitted) part of the stack which isn't caught by the |
The issue happens reproducibly while fuzzing profiling APIs. The change would remove a large class of errors that I found during testing. The issues can happen in theory too, due to e.g. a modified frame passed in by the profiler. |
Can you dump the broken frame when one of your safefetch checks fail or create a hs_err file? That might shed more light into the problem. |
This happens when the frames frame and stack pointer are randomized (by adding a random number between 0 and 100000) during the fuzzing. |
@parttimenerd This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
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.
Some drive-by comments here.
if (SafeFetchN(this->fp() + return_addr_offset, 0) == 0 || | ||
SafeFetchN(this->fp() + interpreter_frame_sender_sp_offset, 0) == 0 || | ||
SafeFetchN(this->fp() + link_offset, 0) == 0 |
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.
So these three are sender_sp
, sender_unextended_sp
and saved_fp
a few lines below, right? So we can just SafeFetch-check those vars after we got them? This also highlights we want to check that those pointers are safe to fetch from.
I.e.:
// for interpreted frames, the value below is the sender "raw" sp,
// which can be different from the sender unextended sp (the sp seen
// by the sender) because of current frame local variables
sender_sp = (intptr_t*) addr_at(sender_sp_offset);
sender_unextended_sp = (intptr_t*) this->fp()[interpreter_frame_sender_sp_offset];
saved_fp = (intptr_t*) this->fp()[link_offset];
saved_fp = (intptr_t*) this->fp()[link_offset];
if ((SafeFetchN(sender_sp, 0) == 0) ||
(SafeFetchN(sender_unextended_sp) == 0) ||
(SafeFetchN(saved_fp, 0) == 0)) {
return false;
}
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.
you're right, that looks much better
@@ -210,8 +216,7 @@ bool frame::safe_for_sender(JavaThread *thread) { | |||
|
|||
// Will the pc we fetch be non-zero (which we'll find at the oldest frame) | |||
|
|||
if ((address) this->fp()[return_addr_offset] == nullptr) return false; | |||
|
|||
if ((address) this->fp()[return_addr_offset] == NULL) return false; |
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.
Accidental revert: "nullptr" -> "NULL".
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.
I started the PR before the whole move, thanks for noticing this :)
|
||
if ((address) this->fp()[return_addr_offset] == NULL) return false; |
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.
Excess newline. Accidental revert: "nullptr" -> "NULL".
@@ -256,7 +262,7 @@ bool frame::safe_for_sender(JavaThread *thread) { | |||
|
|||
// Will the pc we fetch be non-zero (which we'll find at the oldest frame) | |||
|
|||
if ( (address) this->fp()[return_addr_offset] == nullptr) return false; | |||
if ((address) this->fp()[return_addr_offset] == NULL) return false; |
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.
Accidental revert: "nullptr" -> "NULL".
@shipilev do you think that bringing this PR is worthwhile? It only hardens the API when it is slightly misused (being passed in broken ucontexts). |
In my mind, if this have a non-zero probability of happening during the normal non-fuzzing execution, then we should be on the safe side and check. A profiler that crashes the app is never a good thing. I got here through the bug report here -- so it might be a signal that problems like these happen IRL. |
This might possible. I'll work on it then next week. |
@parttimenerd This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
@parttimenerd This pull request has been inactive for more than 8 weeks and will now be automatically closed. If you would like to continue working on this pull request in the future, feel free to reopen it! This can be done using the |
Makes
frame::safe_for_sender
safer by checking that the location of the return address, sender stack pointer, and link address is accessible. This makes the method safer in the case of broken frames.Progress
Integration blocker
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/11461/head:pull/11461
$ git checkout pull/11461
Update a local copy of the PR:
$ git checkout pull/11461
$ git pull https://git.openjdk.org/jdk.git pull/11461/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 11461
View PR using the GUI difftool:
$ git pr show -t 11461
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/11461.diff
Webrev
Link to Webrev Comment