I’m aware that the kernel stack is very limited - Are there any guidelines for when I should expand the stack? Can you give me some examples of real use cases?
I guess that in most cases it’s pretty hard to know when you should expand the stack… well, I guess that the guideline is something like: In paths that you think the stack space can be large, call IoGetRemainingStackSize() to check the bytes left and call KeExpandKernelStackAndCalloutEx if necessary… The question is: In which cases do you think this check is necessary?
Also, when I do expand the stack, can I reference memory from the previous stack segment or is it not guaranteed to be valid?
We usually only use this if we are calling outside our own driver. That’s really the only case where you have no idea or control over how much stack will be used. For example, in Windows the file systems use this API before calling down to the lower layers of the storage branch.
The previous stack segment will remain valid for the duration of this call.
Yeah but you tell me every time you call ZwOpenProcess you do it through KeExpandStackCallout? ZwOpenProcess invokes callbacks of other drivers that may use stack space…
If you were in an IOCTL handler for a control device and called ZwOpenProcess I’d be surprised if it overflowed the stack. It could happen, but it’s mitigated by a) the stack is fairly fresh when you’re called and b) the fact that the Ps callbacks are call out and not call through. Compare this to the I/O subsystem and the number of stack frames you can end up with before getting to the end of the line. From the storage branch of a test VM right now:
If you were going to call ZwOpenProcess from within a filter here you might need the expand call because you have no idea how much stack is left.
Usually you find out where you need this API by getting a crash (hopefully in testing but maybe at a customer site). In recent memory we’ve needed it around FltCreateFile calls (they can cause I/O) and a USB filter that sometimes generated I/O as a result of I/O.