I don't understand why there is a crumple zone before AND after the stack;
The stack is declared as a global char mystack_storage[...]
.
Assuming that stack grows down, you need the crumple zone at the low end of storage to detect overflow of the alternate stack itself.
Question: what follows the mystack_storage[]
array?
Answer: you don't know.
What if there is another array immediately after, and what if that array is written out of bounds (e.g. with something like other_array[-20] = 'a';
)?
To detect such underflow, you need the crumple zone on the other end as well.
How can the stack ends up aligned if we make so it's unaligned?
The mystack
pointer is intentionally misaligned. If it was used directly as the alternate stack, it would violate stack alignment requirements on many platforms, and would most likely cause a crash.
To prevent this, the library must not be using mystack
directly, but aligning it somewhere else.
The code you pointed to is intended to test that the other code is working properly.
Update:
I still don't understand the offset. Why the mystack pointer would violate stack alignment requirement if used without offset?
Without offset, mystack
's alignment is unknown. It may happen to be aligned on 16-byte, 8-byte, or even 1-byte boundary.
With the offset, it is guaranteed to be misaligned (aligned on 1-byte boundary).
Why it isn't the other way around: by adding the offset it's intentionally misaligned and violate stack alignment requirement.
Yes, the pointer is intentionally misaligned.
The point was: the code which actually uses mystack
(that code is elsewhere, I didn't look for it), is already prepared for dealing with misaligned mystack
, by properly aligning it (let's call that "alignment code"). And the code you pointed to is intended to exercise that other "alignment code".
Now, where is that "alignment code"?
I thought it's somewhere else in the library, but I was wrong. The misaligned mystack
pointer is used directly here.
So who is doing the required alignment then? The kernel does!
From man sigaltstack
:
ss.ss_sp
This field specifies the starting address of the stack. When a signal
handler is invoked on the alternate stack, the kernel automatically
aligns the address given in ss.ss_sp to a suitable address boundary
for the underlying hardware architecture.
So the "other code" that the misalignment of mystack
is intended to exercise is not in the library, it's in the kernel.