Make sure registration is done before sigsetjmp
Summary: registration is a local non-volatile variable, and currently it is changed between sigsetjmp and the potential siglongjmp invokation. According to the docs, this makes its value undefined.
@@ -133,11 +133,6 @@ sig_safe_exec (void (*op)(void*), void* data)
__atomic_store_n(&handler_data.tid, as_safe_gettid(), __ATOMIC_SEQ_CST);
__atomic_store_n(&handler_data.check_sigill, 1, __ATOMIC_SEQ_CST);
- if (sigsetjmp(handler_data.jump_buffer, 1)) {
- errno = EFAULT;
- goto out;
- }
-
sigset_t sigset;
if (sigemptyset(&sigset) ||
sigaddset(&sigset, SIGILL))
@@ -150,6 +145,13 @@ sig_safe_exec (void (*op)(void*), void* data)
goto out;
}
+ // Must be after `registration` is valid. If we ever longjmp to the buffer
+ // below, we will need the actual value in order to sigmux_unregister it.
+ if (sigsetjmp(handler_data.jump_buffer, 1)) {
+ errno = EFAULT;
+ goto out;
+ }
+
__atomic_store_n(&handler_data.active, 1, __ATOMIC_SEQ_CST);
op(data);
__atomic_store_n(&handler_data.active, 0, __ATOMIC_SEQ_CST);
