ElBlo
Disabling Signal altstack
#include <signal.h>
int sigaltstack(const stack_t *restrict ss, stack_t *restrict oss);
The sigaltstack
function allows you to set an alternate stack for signal
handlers. A typical use case is to set an alternate stack for the SIGSEGV
handler, so it can be executed even if your stack is in a bad state.
EPERM
is returned if you try to change the altstack while it is active. The
OS doesn’t keep track of whether you are executing a signal handler or not, so
the alternate stack is active if your current stack is within the bounds that
you set when you installed it.
This has the implication that if you set your altstack base to 0
and size to
UINT64_MAX
, you will set an altstack that can’t be changed or disabled for
the duration of the program: the alternate stack is always active.
Here’s an example:
#include <limits.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
stack_t altstack = {
.ss_sp = NULL,
.ss_flags = 0,
.ss_size = UINT64_MAX,
};
if (sigaltstack(&altstack, NULL)) {
perror("enabling sigaltstack");
exit(EXIT_FAILURE);
}
fprintf(stderr, "[#] Attempting to change the altstack\n");
altstack = {
.ss_sp = NULL,
.ss_flags = SS_DISABLE,
.ss_size = 0,
};
if (sigaltstack(&altstack, NULL)) {
perror("disabling sigaltstack");
exit(EXIT_FAILURE);
}
return 0;
}
mvanotti@penguin:~$ CXXFLAGS="-Wall -Wextra -pedantic -std=c++20" make test
g++ -Wall -Wextra -pedantic -std=c++20 test.cc -o test
mvanotti@penguin:~$ ./test
[#] Attempting to change the altstack
disabling sigaltstack: Operation not permitted