Changes

2,406 bytes added ,  12:41, 18 April 2022
no edit summary
Line 136: Line 136:     
==== Dump ====
 
==== Dump ====
 +
We need to determine where the <code>struct rseq</code> is and dump its address length and signature.
 +
To achieve that we use special ptrace handle <code>PTRACE_GET_RSEQ_CONFIGURATION</code> (refer to the <code>dump_thread_rseq</code> function).
    +
We have to fix up IP to the abort handler.
    
==== Restore ====
 
==== Restore ====
 +
We need to take data about the <code>struct rseq</code> from the image (see images/rseq.proto) and register it from the parasite context using the <code>rseq</code> syscall (take a look on <code>restore_rseq</code> in criu/pie/restorer.c)
    +
No additional actions here. The process will be restored and will continue execution from the abort handler (not within the rseq CS!).
    
=== inside CS: <code>flags</code> is <code>RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL</code> ===
 
=== inside CS: <code>flags</code> is <code>RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL</code> ===
   −
Rare case, but we support it too.
+
Rare case, but we support it too. If the rseq CS has <code>RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL</code> flag it means that its technically
 +
non-abortable. So, from the first glance, it seems like we can just not do anything special: save rseq structure address, not fix up IP.
 +
This is incorrect.
 +
 
 +
The kernel will clean up <code>(struct rseq).rseq_cs</code> pointer once we jump into the parasite on the dump:
 +
<pre>
 +
static int rseq_ip_fixup(struct pt_regs *regs)
 +
{
 +
...
 +
 
 +
/*
 +
* Handle potentially not being within a critical section.
 +
* If not nested over a rseq critical section, restart is useless.
 +
* Clear the rseq_cs pointer and return.
 +
*/
 +
if (!in_rseq_cs(ip, &rseq_cs))
 +
return clear_rseq_cs(t);
 +
</pre>
 +
 
 +
and after the restore process will continue the rseq CS execution from the same place (it's okay) but from the kernel point of view,
 +
the process will continue this execution as not being within the rseq CS (that's bad!). Because the kernel determines execution context from the <code>(struct rseq).rseq_cs</code> field.
    
==== Dump ====
 
==== Dump ====
 +
We need to determine where the <code>struct rseq</code> is and dump its address length and signature.
 +
To achieve that we use special ptrace handle <code>PTRACE_GET_RSEQ_CONFIGURATION</code> (refer to the <code>dump_thread_rseq</code> function).
    +
We save IP as it was (not doing fixup), but we have to save <code>(struct rseq).rseq_cs</code> field into the CRIU image.
    
==== Restore ====
 
==== Restore ====
 +
We need to take data about the <code>struct rseq</code> from the image (see images/rseq.proto) and register it from the parasite context using the <code>rseq</code> syscall (take a look on <code>restore_rseq</code> in criu/pie/restorer.c)
    +
We need to restore <code>(struct rseq).rseq_cs</code> memory externaly using ptrace <code>POKEAREA</code> (see <code>restore_rseq_cs</code>).
    
== TODO ==
 
== TODO ==