Page MenuHomeFreeBSD

linux(4): save the epoll_pwait signal mask in td_oldsigmask
Needs ReviewPublic

Authored by nick_spun.io on Fri, Sep 25, 4:38 AM.

Details

Reviewers
adrian
kevans
Summary

linux_epoll_wait_ts() set TDP_OLDMASK but kept the caller's mask in a
local and restored it by hand. The TDA_SIGSUSPEND AST then replaced
it with whatever td_oldsigmask held: a stale mask from an earlier
sigsuspend, ppoll or pselect, or on a thread that had never called
them, an empty one that unblocked every signal. The hand restore
also overwrote the kevent error, so an interrupted wait returned 0
instead of EINTR.

Save the mask in td_oldsigmask and let the AST restore it, as
kern_poll_kfds() does.

A program that calls sigsuspend() in a signal handler, as Bun does to
suspend threads for garbage collection, was left with that signal
blocked after its next epoll_pwait2() and deadlocked.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 77300
Build 74183: arc lint + arc unit