Page MenuHomeFreeBSD

sigfastblock: do not skip cursig/postsig loop in ast()
ClosedPublic

Authored by kib on Mon, Jan 11, 1:39 AM.

Details

Summary

Even if sigfastblock block is non-zero, non-blockable signals must be checked on ast and delivered now. This also affects debugger ability to attach, because issignal() also calls ptracestop() is there is pending stop for debugee.

Instead of checking for sigfastblock, and either setting PENDING flag for usermode or doing signal delivery loop, always do loop after checking, and then check and set PENDING bit. issignal() already does the right thing for fast-blocked case, allowing only STOPs and SIGKILL to happen.

Diff Detail

Repository
R10 FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

kib requested review of this revision.Mon, Jan 11, 1:39 AM
kib created this revision.
sys/kern/subr_trap.c
328 ↗(On Diff #82050)

Is this condition still sufficient? Isn't it possible that the loop above delivered all pending signals already?

kib marked an inline comment as done.Mon, Jan 11, 5:26 PM
kib added inline comments.
sys/kern/subr_trap.c
328 ↗(On Diff #82050)

You are right and I fixed it, I believe. But note that it is only possible in case all signals were SIGKILL and SIGSTOP, which is obviously reduced just to SIGSTOP. So it rarely results in spurious usermode PEND bit set, which is in fact innocent.

kib marked an inline comment as done.

Check for TDP_SIGFASTPENDING in sigfastblock_setpend() to avoid setting spurious usermode PEND bit (it can still race legitimately if signals were rescheduled).

Collapse two calls to sigfastblock_setpend() into one in ast(), which is enough.

This revision is now accepted and ready to land.Tue, Jan 12, 12:58 AM