Personally, I have no system for reallocating a stack. I provide each application with 64 KB of stack space, and when it overflows, it just page-faults and so the faulting application is terminated by the kernel. If you want though, you'd reallocate the stack by allocating memory, copying the current stack content to the end of the allocated memory, and setting the task's ESP to the end of that memory.
For example, consider a sample 64 KB stack from 0x00000 to 0x10000 has overflowed, and you want to resize it to 128 KB. You'd allocate memory, using malloc or whatever, let's assume malloc returns 128 KB at 0x10000 to 0x30000. You'd copy the content of the memory range 0x00000-0x10000 to the memory range of 0x10000-0x30000. And then you need to set the task's ESP, which would be the same offset into the stack, but using the new stack as a base.
I don't guarantee this to work though, as for example, consider the following routine.
Code:
routine:
push ebp
mov ebp, esp
add ebp, 8
push ebx
push ecx
push edx
; read parameters using i386 ABI from the stack
mov eax, [ebp] ; first parameter
mov ebx, [ebp+4] ; second parameter
; do some useful function here
Let's assume the stack overflows at the PUSH EBX instruction. The kernel transparently allocates a new stack and the application is not aware of it. It then pushes ECX and EDX and then tries to read function parameters from the stack using EBP, which in turn points to the old stack, which may or may not be valid. Thus, this as well may page fault and is an issue for you to figure out on your own.