Discard ignored signals on New Technology (#592)

This commit is contained in:
Gavin Hayes 2022-09-05 12:17:56 -04:00 committed by GitHub
parent 4b4ea046c4
commit 7de2f229a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 1 deletions

View file

@ -31,6 +31,7 @@ bool __sig_handle(bool, int, int, ucontext_t *) hidden;
int __sig_add(int, int) hidden;
int __sig_mask(int, const sigset_t *, sigset_t *) hidden;
int __sig_raise(int, int) hidden;
void __sig_check_ignore(const int, const unsigned) hidden;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -246,7 +246,7 @@ textwindows int __sig_add(int sig, int si_code) {
}
/**
* Enqueues generic signal for delivery on New Technology.
* Checks for unblocked signals and delivers them on New Technology.
*
* @param restartable is for functions like read() but not poll()
* @return true if EINTR should be returned by caller
@ -264,3 +264,38 @@ textwindows bool __sig_check(bool restartable) {
}
return delivered;
}
/**
* Determines if a signal should be ignored and if so discards existing
* instances of said signal on New Technology.
*
* Even blocked signals are discarded.
*
* @param sig the signal number to remove
* @threadsafe
*/
textwindows void __sig_check_ignore(const int sig, const unsigned rva) {
struct Signal *cur, *prev, *next;
if (rva != (unsigned)(intptr_t)SIG_IGN &&
(rva != (unsigned)(intptr_t)SIG_DFL || __sig_isfatal(sig))) {
return;
}
if (__sig.queue) {
__sig_lock();
for (prev = 0, cur = __sig.queue; cur; cur = next) {
next = cur->next;
if (sig == cur->sig) {
if (cur == __sig.queue) {
__sig.queue = cur->next;
} else if (prev) {
prev->next = cur->next;
}
__sig_handle(false, cur->sig, cur->si_code, 0);
__sig_free(cur);
} else {
prev = cur;
}
}
__sig_unlock();
}
}

View file

@ -258,6 +258,7 @@ static int __sigaction(int sig, const struct sigaction *act,
if (act) {
__sighandrvas[sig] = rva;
__sighandflags[sig] = act->sa_flags;
__sig_check_ignore(sig, rva);
}
}
return rc;

View file

@ -156,3 +156,22 @@ noubsan void ubsanTrumpsSystemsEngineering(void) {
TEST(sigaction, sigFpe_handlerCanEditProcessStateAndRecoverExecution) {
ubsanTrumpsSystemsEngineering();
}
static unsigned OnSignalCnt = 0;
void OnSignal(int sig, siginfo_t *si, void *ctx) {
OnSignalCnt++;
}
TEST(sigaction, ignoringSignalDiscardsSignal) {
struct sigaction sa = {.sa_sigaction = OnSignal, .sa_flags = SA_SIGINFO};
ASSERT_EQ(0, sigaction(SIGUSR1, &sa, NULL));
sigset_t blocked;
sigemptyset(&blocked);
sigaddset(&blocked, SIGUSR1);
ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &blocked, NULL));
ASSERT_EQ(0, raise(SIGUSR1));
ASSERT_NE(SIG_ERR, signal(SIGUSR1, SIG_IGN));
ASSERT_EQ(0, sigaction(SIGUSR1, &sa, NULL));
ASSERT_EQ(0, sigprocmask(SIG_UNBLOCK, &blocked, NULL));
EXPECT_EQ(0, OnSignalCnt);
}