Issue: Implement SYS_rt_sigtimedwait to support synchronous signal handling (sigwaitinfo/sigtimedwait)
1. Summary
In Linux guest applications running under elfuse, utilizing synchronous signal handling functions such as sigwait(), sigwaitinfo(), or sigtimedwait() results in failures or runtime crashes. This occurs because the underlying system call SYS_rt_sigtimedwait (syscall 179) is unimplemented and returns -ENOSYS.
2. Why it is Needed
In modern multi-threaded Linux applications, handling signals asynchronously via signal handlers (using sigaction) is often discouraged due to safety concerns (reentrancy limits in signal-handler contexts). Instead, the standard Linux design pattern is to block signals in all threads via pthread_sigmask, spawn a dedicated signal-management thread, and wait for signals synchronously using:
sigwait(const sigset_t *set, int *sig)
sigwaitinfo(const sigset_t *set, siginfo_t *info)
sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
In standard Linux C libraries (both glibc and musl), all three of these APIs wrapper the rt_sigtimedwait system call. If SYS_rt_sigtimedwait is missing and returns ENOSYS:
- Applications attempting to handle daemon reload signals (e.g.
SIGHUP), termination signals (e.g. SIGTERM, SIGINT), or worker synchronization signals synchronously fail to initialize their signal helper loops.
- POSIX-compliant multi-threaded software cannot coordinate signals correctly.
3. Implementation Overview
The system call can be emulated in elfuse by registering SYS_rt_sigtimedwait in dispatch.tbl and implementing the lookup logic in the signal subsystem:
- Signature:
int64_t signal_rt_sigtimedwait(guest_t *g, uint64_t set_gva, uint64_t info_gva, uint64_t timeout_gva, uint64_t sigsetsize)
- Behavior:
- Read the target signal set (
set_gva) and validate parameters (such as sigsetsize == 8).
- Check if any signals in the requested set are currently pending.
- If a signal is pending, consume it, populate the
siginfo_t struct at info_gva (if provided), and return the signal number.
- If no signal is pending:
- If a timeout (
timeout_gva) is provided, return -EAGAIN (or sleep for the specified duration and check again).
- If no timeout is specified, block the guest thread (e.g., in a sleep loop) until a signal is delivered.
Issue: Implement
SYS_rt_sigtimedwaitto support synchronous signal handling (sigwaitinfo/sigtimedwait)1. Summary
In Linux guest applications running under
elfuse, utilizing synchronous signal handling functions such assigwait(),sigwaitinfo(), orsigtimedwait()results in failures or runtime crashes. This occurs because the underlying system callSYS_rt_sigtimedwait(syscall 179) is unimplemented and returns-ENOSYS.2. Why it is Needed
In modern multi-threaded Linux applications, handling signals asynchronously via signal handlers (using
sigaction) is often discouraged due to safety concerns (reentrancy limits in signal-handler contexts). Instead, the standard Linux design pattern is to block signals in all threads viapthread_sigmask, spawn a dedicated signal-management thread, and wait for signals synchronously using:sigwait(const sigset_t *set, int *sig)sigwaitinfo(const sigset_t *set, siginfo_t *info)sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)In standard Linux C libraries (both
glibcandmusl), all three of these APIs wrapper thert_sigtimedwaitsystem call. IfSYS_rt_sigtimedwaitis missing and returnsENOSYS:SIGHUP), termination signals (e.g.SIGTERM,SIGINT), or worker synchronization signals synchronously fail to initialize their signal helper loops.3. Implementation Overview
The system call can be emulated in
elfuseby registeringSYS_rt_sigtimedwaitindispatch.tbland implementing the lookup logic in the signal subsystem:set_gva) and validate parameters (such assigsetsize == 8).siginfo_tstruct atinfo_gva(if provided), and return the signal number.timeout_gva) is provided, return-EAGAIN(or sleep for the specified duration and check again).