----- On Apr 30, 2020, at 12:36 PM, Florian Weimer fwei...@redhat.com wrote:
> * Mathieu Desnoyers: > [...] > >>>> + if (__rseq_abi.cpu_id == RSEQ_CPU_ID_REGISTRATION_FAILED) >>>> + return; >>>> + ret = INTERNAL_SYSCALL_CALL (rseq, &__rseq_abi, sizeof (struct rseq), >>>> + 0, RSEQ_SIG); >>>> + if (INTERNAL_SYSCALL_ERROR_P (ret) && >>>> + INTERNAL_SYSCALL_ERRNO (ret) != EBUSY) >>>> + __rseq_abi.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; >>> >>> Sorry, I forgot: Please add a comment that the EBUSY error is ignored >>> because registration may have already happened in a legacy library. >> >> Considering that we now disable signals across thread creation, and that >> glibc's initialization happens before other libraries' constructors >> (as far as I remember even before LD_PRELOADed library constructors), >> in which scenario can we expect to have EBUSY here ? > > That's a good point. > >> Not setting __rseq_abi.cpu_id to RSEQ_CPU_ID_REGISTRATION_FAILED in case >> of EBUSY is more a way to handle "unforeseen" scenarios where somehow the >> registration would already be done. But I cannot find an "expected" >> scenario which would lead to this now. >> >> So if EBUSY really is unexpected, how should we treat that ? I don't think >> setting REGISTRATION_FAILED would be appropriate, because then it would >> break assumption of the prior successful registration that have already >> been done by this thread. > > You could call __libc_fatal with an error message. ENOSYS is definitely > an expected error code here, and EPERM (and perhaps EACCES) can happen > with seccomp filters. If we go this way, I'd also recommend to treat any situation where __rseq_abi.cpu_id is already initialized as a fatal error. Does the code below seem OK to you ? static inline void rseq_register_current_thread (void) { int ret; if (__rseq_abi.cpu_id != RSEQ_CPU_ID_UNINITIALIZED) __libc_fatal ("rseq already initialized for this thread\n"); ret = INTERNAL_SYSCALL_CALL (rseq, &__rseq_abi, sizeof (struct rseq), 0, RSEQ_SIG); if (INTERNAL_SYSCALL_ERROR_P (ret)) { if (INTERNAL_SYSCALL_ERRNO (ret) == EBUSY) __libc_fatal ("rseq already registered for this thread\n"); __rseq_abi.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED; } } Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com