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 native stack checking on Android/Bionic #1538

Closed
wants to merge 1 commit into from

Conversation

tmikov
Copy link
Contributor

@tmikov tmikov commented Oct 14, 2024

Summary:
Related to: #1535

It turns out that on Android/Bionic pthread_attr_getstack() includes
the stack guard pages in the returned size. Whether that is a bug or not
is debatable, but it differs in behavior from Linux/glibc. Plus,
returning a stack range that is not actually not all accessible is less
than useful.

In practice it worked with our approach because the default stack guard
size is 4KB on Android, while our "native gap" is 64KB. Our gap is
larger than the stack guard size, so we would still correctly detect and
catch stack overflow.

However, if the stack guard size is 64KB (or larger), we would not
detect the overflow and crash. It is possible to manually set a larger
guard size, plus security-oriented OS-es like GrapheneOS do it by
default.

The fix is to subtract the guard size from the available stack size when
running on Bionic.

Added tests checking the behavior in the main thread, in a default
thread and in a thread with a 64KB guard. Two separate tests are
performed under these circumstances:

  • Unbounded recursion checking for native stack overflow
  • Manually reading the available stack range to ensure it is all
    accessible.

Differential Revision: D64308925

Summary:
Related to: facebook#1535

It turns out that on Android/Bionic `pthread_attr_getstack()` includes
the stack guard pages in the returned size. Whether that is a bug or not
is debatable, but it differs in behavior from Linux/glibc. Plus,
returning a stack range that is not actually not all accessible is less
than useful.

In practice it worked with our approach because the default stack guard
size is 4KB on Android, while our "native gap" is 64KB. Our gap is
larger than the stack guard size, so we would still correctly detect and
catch stack overflow.

However, if the stack guard size is 64KB (or larger), we would not
detect the overflow and crash. It is possible to manually set a larger
guard size, plus security-oriented OS-es like GrapheneOS do it by
default.

The fix is to subtract the guard size from the available stack size when
running on Bionic.

Added tests checking the behavior in the main thread, in a default
thread and in a thread with a 64KB guard. Two separate tests are
performed under these circumstances:
- Unbounded recursion checking for native stack overflow
- Manually reading the available stack range to ensure it is all
accessible.

Differential Revision: D64308925
@facebook-github-bot facebook-github-bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label Oct 14, 2024
@facebook-github-bot
Copy link
Contributor

This pull request was exported from Phabricator. Differential Revision: D64308925

@facebook-github-bot
Copy link
Contributor

This pull request has been merged in a5b2bbc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed Do not delete this pull request or issue due to inactivity. fb-exported Merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants