My solution was to use a fork server instead, which works almost equally well. There are not really much downsides with this approach. And this is actually quite simple, and also quite cross-platform (except Windows).
If you're only looking for tcp checkpoint-restore (and not while process) using network namespaces worked, even before the advent of CAP_CHECKPOINT_RESTORE in the Linux kernel (I wish they'd kept checkpoint separate but it's a fight for another day). Works for me on recent kernels. The problem with this the criu/kernel approach is that you need to go through some lengths to pause the low-layer packet stream.
Are there any bypasses to shadow stacks? The only way I can think of is when jmp's are being made to a registry after a pop or after operations that involve stack data. Wouldn't there also be a counter-argument that shadow stacks aren't needed so long as you're using random stack canaries and/or W^X. Why have those not become universal and why would shadow stacks have a more practical improvement?
> Wouldn't there also be a counter-argument that shadow stacks aren't needed so long as you're using random stack canaries and/or W^X. Why have those not become universal and why would shadow stacks have a more practical improvement?
Stack canaries can be bypassed if you can find a read vulnerability to disclose a stack canary or disclose the randomness used for generating the canary, or by finding a write vulnerability that permits rewriting the randomness source used for validating the canary. See https://www.s3.eurecom.fr/docs/ifip18_bierbaumer.pdf
Stack canaries and W^X are quite ubiquitous. The biggest exceptions are JIT'd code, I think, though some JIT engines do leverage one or both.
Shadow stacks in principle are more difficult to defeat--read disclosures alone wouldn't suffice--especially if they're hardware enforced like with Intel CET.
There is also DMTCP (https://github.com/dmtcp/dmtcp/) but this might have other problems for my use case.
My solution was to use a fork server instead, which works almost equally well. There are not really much downsides with this approach. And this is actually quite simple, and also quite cross-platform (except Windows).