Created
June 19, 2021 13:49
-
-
Save azat/2ee360fd4f2828d363b0926431afacc6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Test case for alternative stack overflow in TLS | |
#include <cstdio> | |
#include <cstring> | |
#include <cstdlib> | |
#include <csignal> | |
#include <cassert> | |
#include <string> | |
#include <algorithm> | |
#include <thread> | |
static_assert(MINSIGSTKSZ == 2048); | |
alignas(4096) static thread_local char alt_stack[2048]; | |
static thread_local char data_char[512]; | |
static thread_local int data_int; | |
void handler(int sig, siginfo_t *, void *) | |
{ | |
signal(sig, SIG_DFL); | |
/// This will overflow alt_stack, and overwrite other variables in TLS | |
char local_data_char[4096]; | |
memset(local_data_char, 'B', sizeof(local_data_char)); | |
assert(data_int == 1); | |
assert(std::find_if_not(data_char, data_char+sizeof(data_char), [](char a) { return a == 'A'; }) == data_char+sizeof(data_char)); | |
_Exit(0); | |
} | |
int main() | |
{ | |
std::thread thread([]() { | |
stack_t altstack{}; | |
altstack.ss_sp = alt_stack; | |
altstack.ss_size = sizeof(alt_stack); | |
if (sigaltstack(&altstack, NULL)) | |
perror("sigaltstack"); | |
struct sigaction sa{}; | |
sa.sa_sigaction = handler; | |
sa.sa_flags = SA_SIGINFO | SA_ONSTACK; | |
if (sigaddset(&sa.sa_mask, SIGSEGV)) | |
perror("sigaddset"); | |
if (sigaction(SIGSEGV, &sa, NULL)) | |
perror("sigaction"); | |
if (sigaction(SIGSEGV, NULL, &sa)) | |
perror("sigaction"); | |
assert(sa.sa_flags & SA_ONSTACK); | |
data_int = 1; | |
memset(data_char, 'A', sizeof(data_char)); | |
*(volatile char *)NULL = 0; | |
}); | |
thread.join(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment