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

Fix async prefetch heap use after free #11049

Closed
wants to merge 3 commits into from

Conversation

anand1976
Copy link
Contributor

@anand1976 anand1976 commented Dec 20, 2022

This PR fixes a heap use after free bug in the async prefetch code that happens in the following scenario -

  1. Scan thread starts 2 async reads for Seek, one for the seek block and one for prefetching
  2. Before the first read in 1 completes, another thread reads and loads the block in cache
  3. The first scan thread finds the block in cache, continues and the next block cache miss is for a block that spans the boundary of the 2 prefetch buffers, and the 1st read is complete but the 2nd one is not complete yet
  4. The scan thread will reallocate (i.e free the old buffer and allocate a new one) the 2nd prefetch buffer, and the in-progress prefetch is orphaned
  5. The orphaned prefetch finally completes, resulting in a use after free

Also add a few asserts to surface bugs earlier in the crash tests.

Test plan:
Repro with db_stress and verify the fix

@facebook-github-bot
Copy link
Contributor

@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@@ -327,6 +332,14 @@ Status FilePrefetchBuffer::HandleOverlappingData(
size_t alignment = reader->file()->GetRequiredBufferAlignment();
uint32_t second = curr_ ^ 1;
Copy link
Contributor

@akankshamahajan15 akankshamahajan15 Dec 21, 2022

Choose a reason for hiding this comment

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

I think we should move this statement below after the newly added check just to be safe if buffers get swapped in PollAndUpdateBuffersIfNeeded, although they won't but code will be consistent to always update second after PollAndUpdateBuffersIfNeeded.

Copy link
Contributor

@akankshamahajan15 akankshamahajan15 left a comment

Choose a reason for hiding this comment

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

Added a minor comment. Rest LGTM! Thanks for fixing it.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@anand1976 has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@anand1976 has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@anand1976 merged this pull request in dbf37c2.

anand1976 pushed a commit that referenced this pull request Dec 21, 2022
Summary:
This PR fixes a heap use after free bug in the async prefetch code that happens in the following scenario -
1. Scan thread starts 2 async reads for Seek, one for the seek block and one for prefetching
2. Before the first read in #1 completes, another thread reads and loads the block in cache
3. The first scan thread finds the block in cache, continues and the next block cache miss is for a block that spans the boundary of the 2 prefetch buffers, and the 1st read is complete but the 2nd one is not complete yet
4. The scan thread will reallocate (i.e free the old buffer and allocate a new one) the 2nd prefetch buffer, and the in-progress prefetch is orphaned
5. The orphaned prefetch finally completes, resulting in a use after free

Also add a few asserts to surface bugs earlier in the crash tests.

Pull Request resolved: #11049

Test Plan: Repro with db_stress and verify the fix

Reviewed By: akankshamahajan15

Differential Revision: D42181118

Pulled By: anand1976

fbshipit-source-id: 1ac55d2f64a89ce128c1c574262b8aa7d82eb8cc
@hx235
Copy link
Contributor

hx235 commented Dec 22, 2022

@anand1976 - seems like an irrelevant issue #1 is quoted in summary?

anand1976 pushed a commit to anand1976/rocksdb that referenced this pull request Jan 11, 2023
facebook-github-bot pushed a commit that referenced this pull request Jan 13, 2023
Summary:
Add a unit test in prefetch_test for #11049

Pull Request resolved: #11084

Test Plan: Verify the test fails without #11049 and passes with it

Reviewed By: akankshamahajan15

Differential Revision: D42485828

Pulled By: anand1976

fbshipit-source-id: ae512f2d121745a1f5212645a9b58868976c1f83
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants