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

adds x86 stack pointer handling for external calls #955

Merged
merged 2 commits into from
Jun 16, 2019

Conversation

gitoleg
Copy link
Contributor

@gitoleg gitoleg commented Jun 14, 2019

For x86 and x86_64 ABI it is the responsibility of the callee to pop the return address from the stack pointer and increase the stack pointer. Since the code of external functions is not present in the binary, every time an external function is called, the stack grows without being corrected. In case if the base pointer is not used (e.g., in optimized code, or if the no-frame-pointer option was specified) this will also lead to the stack corruption as all variables will shift. This corruption results in an incorrect interpretation of a program and in case of taint analysis will introduce aliasing between neighboring stack variables.

The solution is to appropriately increase the stack pointer every time we return from a call from the Lisp Machine back to the Primus Machine. This will correctly handle three cases:

  1. an internal ABI comformant function is overridden by a lisp function
  2. an external function is overridden by a lisp function
  3. an external function which is not linked/overridden

In the latter will work correctly, because all external functions that are not linked explicitly, are implicitly linked to a special function __primus_linker_unresolved_call, which in turn is overridden by the primus:handle-unresolved-names function, therefore an unlinked external function will still end up with a Lisp machine call. The same is true, if a function is overridden without using the Lisp Machine, directly from the Linker.

Obviously, this patch relies on the presence of the Lisp machine and if the Lisp Machine is not loaded, the stack pointer will not be corrected.

This patch will also misbehave, if a local static function that is not ABI comformant is overridden by a Lisp stub. In that case it is the responsibility of the Lisp stub to properly correct the stack pointer.

A better solution is still being sought, but so far this is the best option we have.
Resolves #879

gitoleg added 2 commits June 14, 2019 11:50
So far the stack pointer register wasn't properly handled by
primus in case of external calls.

The reason is in the asymmetry of the function calling in x86 ABI:
the caller side allocates the stack slot for the returning address
and callee sise is responsible for clearing it. But in case of
external calls, dependless if a lisp stub exists or call remains
unresolved, there wasn't any stack restoring. As a result
stack pointer didn't point to a proper place.

This PR solve this problem by incrementing stack pointer
after lisp call returns. It works for unresolved calls as well.
@ivg ivg self-requested a review June 14, 2019 17:10
@gitoleg gitoleg merged commit f595843 into BinaryAnalysisPlatform:master Jun 16, 2019
@gitoleg gitoleg deleted the correct-x86-sp branch May 13, 2020 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ESP handling for external calls
2 participants