Skip to content

fix(profiling): use-after-free with Closure trampolines - #2280

Merged
bwoebi merged 2 commits into
masterfrom
levi/internal-trampoline
Sep 25, 2023
Merged

fix(profiling): use-after-free with Closure trampolines#2280
bwoebi merged 2 commits into
masterfrom
levi/internal-trampoline

Conversation

@morrisonlevi

@morrisonlevi morrisonlevi commented Sep 22, 2023

Copy link
Copy Markdown
Collaborator

Description

A customer reported a crash which lead to the discovery of this use-after-free. Note that this is limited to Closure trampolines, and only when the profiler is enabled. It has been a potential issue for some time, but seems to be more likely to cause a crash since #1998 was merged.

Readiness checklist

  • Changelog has been added to the release document.
  • Tests added for this feature/bug. Yes, but the test only will fail with release asan builds. Currently in CI all ASAN builds are debug builds, which the profiler does not support. We should follow-up in another PR and do release ASAN runs with the profiler.

Reviewer checklist

  • Appropriate labels assigned.
  • Milestone is set.

@morrisonlevi morrisonlevi added cat:app-crash profiling Relates to the Continuous Profiler labels Sep 22, 2023
@morrisonlevi morrisonlevi added this to the 0.92.0 milestone Sep 22, 2023
@morrisonlevi
morrisonlevi requested a review from a team as a code owner September 22, 2023 17:30

Our zend_execute_internal hook inspected the func after the call has been made,
potentially triggering the issue. This test will likely only fail under asan.
It's unclear how the customer also got a crash out of it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It basically crashes if the 18th (ZEND_ACC_CALL_VIA_TRAMPOLINE) bit of the address is not set.
This may be different on different executions, depending on base address (depending on OS), amount of memory allocated before (that's just 256 KB), address randomization etc.

@bwoebi bwoebi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I wouldn't say that it's unclear how it crashed :-D

But the fix looks good and correct to me :-)

@morrisonlevi

Copy link
Copy Markdown
Collaborator Author

I wouldn't say that it's unclear how it crashed :-D

Well sure, use-after-frees are obviously wrong even if they don't lead to crashes ^_^

I just couldn't ever get it to crash myself, hence the notes about it only failing in ASAN. I suppose that's clear enough.

@pr-commenter

pr-commenter Bot commented Sep 22, 2023

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2023-09-22 22:20:31

Comparing candidate commit a3cf362 in PR branch levi/internal-trampoline with baseline commit d8c8736 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 6 metrics, 0 unstable metrics.

Comment thread profiling/src/lib.rs
Comment on lines +1031 to +1037
/// Returns true if the func tied to the execute_data is a trampoline.
/// # Safety
/// This is only safe to execute _before_ executing the trampoline, because the trampoline may
/// free the `execute_data.func` _without_ setting it to NULL:
/// https://heap.space/xref/PHP-8.2/Zend/zend_closures.c?r=af2110e6#60-63
/// So no code can inspect the func after the call has been made, which is why you would call this function: find out before you
/// call the function if indeed you need to skip certain code after it has been executed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍 for those comments 🚀

@bwoebi
bwoebi merged commit 4ff3512 into master Sep 25, 2023
@bwoebi
bwoebi deleted the levi/internal-trampoline branch September 25, 2023 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cat:app-crash profiling Relates to the Continuous Profiler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants