@@ -90,14 +90,6 @@ impl Supervisor {
9090 // Unwinding might be messed up due to partly protected memory, so let's abort if something
9191 // breaks inside here.
9292 let res = std:: panic:: abort_unwind ( || {
93- // SAFETY: We do not access machine memory past this point until the
94- // supervisor is ready to allow it.
95- // FIXME: this is sketchy, as technically the memory is still in the Rust Abstract Machine,
96- // and the compiler would be allowed to reorder accesses below this block...
97- unsafe {
98- Self :: protect_pages ( alloc. pages ( ) , mman:: ProtFlags :: PROT_NONE ) . unwrap ( ) ;
99- }
100-
10193 // Send over the info.
10294 // NB: if we do not wait to receive a blank confirmation response, it is
10395 // possible that the supervisor is alerted of the SIGSTOP *before* it has
@@ -110,16 +102,14 @@ impl Supervisor {
110102 // count.
111103 signal:: raise ( signal:: SIGSTOP ) . unwrap ( ) ;
112104
113- let res = f ( ) ;
105+ // SAFETY: We have coordinated with the supervisor to ensure that this memory will keep
106+ // working as normal, just with extra tracing. So even if the compiler moves memory
107+ // accesses down to after the `mprotect`, they won't actually segfault.
108+ unsafe {
109+ Self :: protect_pages ( alloc. pages ( ) , mman:: ProtFlags :: PROT_NONE ) . unwrap ( ) ;
110+ }
114111
115- // We can't use IPC channels here to signal that FFI mode has ended,
116- // since they might allocate memory which could get us stuck in a SIGTRAP
117- // with no easy way out! While this could be worked around, it is much
118- // simpler and more robust to simply use the signals which are left for
119- // arbitrary usage. Since this will block until we are continued by the
120- // supervisor, we can assume past this point that everything is back to
121- // normal.
122- signal:: raise ( signal:: SIGUSR1 ) . unwrap ( ) ;
112+ let res = f ( ) ;
123113
124114 // SAFETY: We set memory back to normal, so this is safe.
125115 unsafe {
@@ -130,6 +120,12 @@ impl Supervisor {
130120 . unwrap ( ) ;
131121 }
132122
123+ // Signal the supervisor that we are done. Will block until the supervisor continues us.
124+ // This will also shut down the segfault handler, so it's important that all memory is
125+ // reset back to normal above. There must not be a window in time where accessing the
126+ // pages we protected above actually causes the program to abort.
127+ signal:: raise ( signal:: SIGUSR1 ) . unwrap ( ) ;
128+
133129 res
134130 } ) ;
135131
0 commit comments