Skip to content
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

Closed

Conversation

parttimenerd
Copy link
Contributor

@parttimenerd parttimenerd commented Dec 1, 2022

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

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Integration blocker

 ⚠️ Too few reviewers with at least role reviewer found (have 0, need at least 1) (failed with the updated jcheck configuration)

Issue

  • JDK-8297967: Make frame::safe_for_sender safer (Enhancement - P4)

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

@bridgekeeper
Copy link

bridgekeeper bot commented Dec 1, 2022

👋 Welcome back parttimenerd! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr Pull request is ready for review label Dec 1, 2022
@openjdk
Copy link

openjdk bot commented Dec 1, 2022

@parttimenerd The following label will be automatically applied to this pull request:

  • hotspot

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.

@mlbridge
Copy link

mlbridge bot commented Dec 1, 2022

Webrevs

src/hotspot/cpu/aarch64/frame_aarch64.cpp Outdated Show resolved Hide resolved
src/hotspot/cpu/x86/frame_x86.cpp Outdated Show resolved Hide resolved
src/hotspot/cpu/aarch64/frame_aarch64.cpp Outdated Show resolved Hide resolved
@parttimenerd
Copy link
Contributor Author

I converted it back to a draft and look into next week with more vigor.

@parttimenerd parttimenerd marked this pull request as draft December 2, 2022 07:09
@openjdk openjdk bot removed the rfr Pull request is ready for review label Dec 2, 2022
@parttimenerd parttimenerd marked this pull request as ready for review December 6, 2022 12:51
@parttimenerd
Copy link
Contributor Author

My new version just uses SafeFetchN in the place where I consistently get segfaults in my fuzzer and it works.

@openjdk openjdk bot added the rfr Pull request is ready for review label Dec 6, 2022
@parttimenerd
Copy link
Contributor Author

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.

@parttimenerd
Copy link
Contributor Author

I added a few more safe fetches, safe_for_sender should now be guarded against any broken fp.

Copy link
Contributor

@TheRealMDoerr TheRealMDoerr left a 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.

@bridgekeeper
Copy link

bridgekeeper bot commented Jan 4, 2023

@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
Copy link
Contributor Author

This is ongoing work.

@parttimenerd parttimenerd marked this pull request as draft January 4, 2023 15:38
@openjdk openjdk bot removed the rfr Pull request is ready for review label Jan 4, 2023
@openjdk
Copy link

openjdk bot commented Feb 17, 2023

@parttimenerd this pull request can not be integrated into master due to one or more merge conflicts. To resolve these merge conflicts and update this pull request you can run the following commands in the local repository for your personal fork:

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

@openjdk openjdk bot added the merge-conflict Pull request has merge conflict with target branch label Feb 17, 2023
@bridgekeeper
Copy link

bridgekeeper bot commented Apr 15, 2023

@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!

@openjdk openjdk bot removed the merge-conflict Pull request has merge conflict with target branch label Apr 24, 2023
@parttimenerd parttimenerd marked this pull request as ready for review April 24, 2023 09:48
@openjdk openjdk bot added the rfr Pull request is ready for review label Apr 24, 2023
@TheRealMDoerr
Copy link
Contributor

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 fp_safe checks for some reason. Using 3 safefetch checks is a bit much, because we shouldn't have gaps within a frame. On the other hand, checking exactly the 3 fields we need sounds like a good idea and your checks should be affordable from performance point of view. I'm ok with it, but I'd like to hear more opinions.

@parttimenerd
Copy link
Contributor Author

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.

@TheRealMDoerr
Copy link
Contributor

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.

@parttimenerd
Copy link
Contributor Author

This happens when the frames frame and stack pointer are randomized (by adding a random number between 0 and 100000) during the fuzzing.

@bridgekeeper
Copy link

bridgekeeper bot commented May 22, 2023

@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!

Copy link
Member

@shipilev shipilev left a 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.

Comment on lines +137 to +139
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
Copy link
Member

@shipilev shipilev Jun 2, 2023

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;
      }

Copy link
Contributor Author

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidental revert: "nullptr" -> "NULL".

Copy link
Contributor Author

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 :)

Comment on lines +259 to +260

if ((address) this->fp()[return_addr_offset] == NULL) return false;
Copy link
Member

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidental revert: "nullptr" -> "NULL".

@parttimenerd
Copy link
Contributor Author

@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).

@shipilev
Copy link
Member

shipilev commented Jun 2, 2023

@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.

@parttimenerd
Copy link
Contributor Author

This might possible. I'll work on it then next week.

@openjdk openjdk bot added the merge-conflict Pull request has merge conflict with target branch label Jun 15, 2023
@bridgekeeper
Copy link

bridgekeeper bot commented Jul 1, 2023

@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!

@bridgekeeper
Copy link

bridgekeeper bot commented Jul 29, 2023

@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 /open pull request command.

@bridgekeeper bridgekeeper bot closed this Jul 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot [email protected] merge-conflict Pull request has merge conflict with target branch rfr Pull request is ready for review
Development

Successfully merging this pull request may close these issues.

6 participants