Issue 184428
Summary [clang] Please consider enabling -fstack-clash-protection / probe-stack by default
Labels clang
Assignees
Reporter thejh
    Hi!

Please consider enabling `-fstack-clash-protection` by default for supported targets, so that unbounded recursion on a non-main thread in combination with a large stackframe (containing uninitialized buffers) at the bottom of the recursion does not turn into an exploitable security bug.

For a motivating example, see https://project-zero.issues.chromium.org/issues/465827985 , an Android issue where the combination of the following factors makes it possible to escalate privileges from `shell` context to the more privileged `system_server` context (though my proof of concept only manages to do this at a low success rate):

 - Android compiles code without `-fstack-clash-protection`.
 - Android has an IPC mechanism that supports synchronous calls with synchronous callbacks, and it is possible to infinitely nest such IPC calls to cause unbounded recursion [by design](https://source.android.com/docs/core/architecture/ipc/binder-threading#nested).
 - Non-main thread stacks on Android are placed in the same virtual address region as heap allocations and shared memory mappings.
 - Non-main thread stacks on Android that can run Java code effectively have a 8 KiB or 16 KiB guard region at the bottom, depending on how you count.
 - Another function that can be called over IPC, including from a nested IPC call context, contains a 128 KiB stack buffer, and performs a function call to another non-leaf function before initializing this buffer.

This makes it possible for a saved instruction pointer value to be spilled into, and loaded back from, a shared memory segment located below the guard page.


In my opinion, stack overflows are security issues that can only be mitigated by the compiler, because there is no good way for a programmer to protect against them other than by manually keeping track of available stack memory.

Also, if a programmer wants to guard against exploitable stack overflows in their own recursive code, it is not necessarily enough for them to build their own code with `-fstack-clash-protection`, because the function at the bottom of the stack that moves the stack pointer across the guard page might be part of a library dependency.

My understanding is that other platforms already enable such protections by default; for example, [MSVC documentation](https://learn.microsoft.com/en-us/cpp/build/reference/gs-control-stack-checking-calls?view=msvc-170) says:

> By default, the compiler generates code that initiates a stack probe when a function requires more than one page of stack space.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to