Thank you Brendan and willedwards for your answers
You can harden your exploit mitigation further by W^X, even for JITed code
It's funny you mentioned W^X in the context of JIT compiling as I was just thinking about that today. I'm trying to figure out how to maintain the security W^X offers while still allowing JIT compiling; my understanding is that the application writes the code to data pages(W) and then asks the OS to change the pages to code pages (X). If the OS always honors this request, then W^X is essentially non-existent (surely an attacker doesn't care if they have to first ask the OS for permission before executing their malicious code if the OS will always grant it).
So the only thing I can figure is that the OS will not always grant permission to change page permissions. Which begs the question, how does the OS differentiate between legitimate requests to change page permissions and malicious requests?
The best I can come up with is that at install time an admin can grant* programs like JIT compilers authority to request changing pages from writable to executable; programs that do not have this permission will be treated as if they're generating a GPF if they try calling this function.
Is there a better approach?
*(I've considered a few such privileges which will be determined at install time).
I think that RWX for JITs is not just technical, its also historic. Back when the JITting started, it wasn't seen as much of a problem. Now, there are lots of sunk effort in making those JITs work the way they do, and there's not much appetite for rewriting them. Also, on the technical side, theres not a lot of options if you want any semblance of portability. Its hard to support new processor or OS features that require major reorganisation when you expect the same binaries to run on older machines.
I believe the modern iOS stopped embedding the WebView browser in apps and started running the browser in a separate process and using UI composition to give the user experience of a seamless browser in order to be able to enable stronger mitigations like W^X in normal iOS apps, even though they can't enable them in webkit processes. Something like that.
Take this to Pwn2Own and make your millions
All in all, the attackers keep winning, but we must never ever give up! The only truly secure code seems to be the code that is never run