DynamoRIO / DynamoRIO/dynamorio

ASSERT: cross-module tail call from native_exec module ends up interpreting back_from_native

Open
#1,077 1 comment 0 reactions 0 assignees View on GitHub
Migrated Priority-Medium
Dominant language
C
Stars
3.2k
Forks
629
Avg merge
2d 15h
Merged PRs (30d)
31

Description

_From [rnk@google.com](https://code.google.com/u/rnk@google.com/) on February 14, 2013 13:17:24_

I see when using -native_exec_retakeover (not committed yet) on clang -cc1 in a std::vector<> dtor. We have this code:

0x1d25430 <_ZNSt6vectorISt4pairIPFvPvES1_ESaIS4_EED1Ev>: mov (%rdi),%rdi
0x1d25433 <_ZNSt6vectorISt4pairIPFvPvES1_ESaIS4_EED1Ev+3>: test %rdi,%rdi
0x1d25436 <_ZNSt6vectorISt4pairIPFvPvES1_ESaIS4_EED1Ev+6>: je 0x1d2543d <_ZNSt6vectorISt4pairIPFvPvES1_ESaIS4_EED1Ev+13>
0x1d25438 <_ZNSt6vectorISt4pairIPFvPvES1_ESaIS4_EED1Ev+8>: jmpq 0x6333c0 <_ZdlPv@plt>

The important thing is:
jmpq 0x6333c0

That does a tail call to operator delete. It hits our GOT interceptor, so we interpret it. We interpret the return, which tries to dispatch on back_from_native.

There are a couple of solutions:
- dispatch should know about back_from_native. This will also make it generally safe to over-interpret native modules, but might have a perf hit for apps that don't use native_exec.
- The PLT stub could check the TOS for back_from_native, and pre-emptively replace it with native_retval. This adds overhead to every PLT call.

I'm going to implement checking in dispatch and measure the performance impact. If it is negligible, then IMO it's the best.

We already have some special cases enumerated in is_stopping_point(). Maybe I can keep the number of compares down with a call to is_in_dynamo_dll(), which only does two compares.

_Original issue: http://code.google.com/p/dynamorio/issues/detail?id=1077_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.