Hi Daniel, On Thursday, 21.03.2019 at 10:29, m...@daniel-mendler.de wrote: > I have one unrelated question - the Solo5 API exposes the heap as one > continuous block of memory, where the stack is at the top. Is there some way > to ensure that the growing stack does not overwrite the heap, by using some > red zone pages?
Not at the moment. > I can manually limit stack growth by limiting recursion etc, > but I would prefer to have physically enforced guarantees. Would it make > sense to change the API in such a way that stack and heap are kept fully > separate? For example at compile time a fixed stack size is specified and > the stack is kept at a different location from the heap. The Solo5 API > should then pass heap_start, heap_size, stack_start, stack_size to the > application. This is a good idea and I've already thought about it several times. In general, it should be possible to implement in a way that is portable, with fallback to using a single memory region under the hood for targets where it's either not possible, not worth the implementation complexity or just not done yet. On such targets you'd not get a red zone, but your application would still run. However, there are two things to consider: 1) How is the default stack size determined / who gets to choose it and when? At the moment things are nice and simple, e.g. for 'hvt' you just run with "solo5-hvt --mem=XYZ ..." which gives you an easy way to say how much *maximum* resource you want to commit. *Requiring* users to specify a separate stack size up front at run time seems like exposing an unnecessary detail, not to mention that a lot of people will not know what a reasonable value is. 2) I can imagine that the IncludeOS people on this list will immediately pipe up with "Ha! Now we want multiple stacks, *dynamically allocated at run time*, each in its own region" which opens up its own can of worms entirely. An option I thought of which addresses the second point is extending the Solo5 API to provide a single virtual-memory manipulation call, specifically the equivalent of munmap(). The call would be bounds-checked against the heap region, so attempting to touch anything else will just fail. This would make guard page setup the responsibility of the libOS (ocaml-freestanding in the Mirage case) and allow for "carving up" your memory region as you see fit. The main issue I have with that is that for 'spt' (the seccomp-based unikernel-as-user-process target on master) it opens up (some) access to the host munmap() system call. Now, there have been local privilege escalation bugs on Linux involving "only" munmap() and clone(). Granted, we don't allow clone() but who's to say there won't be one involving "only" munmap() and poll() :-/ So, it's unclear what the way forward is here... all ideas welcome. Martin