Page MenuHomeFreeBSD

Simplify signal handling code in libthr by removing use of SYS_sigreturn
AcceptedPublic

Authored by dg612_cam.ac.uk on Sun, Apr 21, 4:46 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Apr 28, 10:44 PM
Unknown Object (File)
Sat, Apr 27, 6:07 PM
Unknown Object (File)
Fri, Apr 26, 3:51 PM
Unknown Object (File)
Fri, Apr 26, 3:51 PM
Unknown Object (File)
Fri, Apr 26, 10:32 AM
Subscribers

Details

Reviewers
jhb
brooks
kib
Summary

The use of SYS_sigreturn is unnecessary here.

If handle_signal is called when a signal is delivered, it can just return normally back to sigcode which will call sigreturn anyway.

In case handle_signal is called by check_deferred_signal, using setcontext is better than SYS_sigreturn because that is the correct system call to pair with the earlier getcontext.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

I think this is correct (and had discussed this with Dapeng previously), but probably best to see what @kib thinks.

Can you upload the full context for the diff?

I tend to think that the removal of sigreturn() from handle_signal on the sync signal delivery path is fine. But I do not like the use of setcontext() for deferred delivery. Yes, sigreturn() vs. setcontext() should have not semantic difference when context is correct. But for incorrect sigreturn's we do provide different error handling, including generation of the signals with right si_info (removing this changes the ABI subtly), and verbose printouts. Also I like the idea that signal handling ends up with sigreturn() (twice).

I am curious why do you think that this change makes the code cleaner.

Updated diff to use sigreturn instead of setcontext during deferred signal handling.

Please upload patches with full context.

lib/libthr/thread/thr_sig.c
400

syscall(SYS_sigreturn) was used there not frivolously. Potentially the sigreturn symbol needs to be resolved there, and this might deadlock if rtld bind_lock is already owned. Look at _thr_rtld_init() how it is done (and I am not sure that it worth the trouble to issue this syscall on libthr startup).

In D44893#1026733, @kib wrote:

I am curious why do you think that this change makes the code cleaner.

I think the change makes the control flow easier to follow, as it is more well-bracketed than the current implementation. For sync signals, control returns naturally to where the signal is initiated i.e., the sigcode. For deferred signals, putting the getcontext/sigreturn pair in the same function highlights that non-standard control flow is happening.

Use syscall(SYS_sigreturn) instead of sigreturn.

lib/libthr/thread/thr_sig.c
400

syscall(SYS_sigreturn) was used there not frivolously. Potentially the sigreturn symbol needs to be resolved there, and this might deadlock if rtld bind_lock is already owned. Look at _thr_rtld_init() how it is done (and I am not sure that it worth the trouble to issue this syscall on libthr startup).

@jhb, @brooks, and I have been discussing about removing uses of syscall(2) in the base system because it complicates security mechanisms that intercept and audit system calls (e.g. compartmentalisation on CheriBSD). It seems that, at least in libthr, syscall(2) is only used to pre-resolve symbols that cannot be called with the effect of a no-op.

One workaround I see is to define a function pointer in libthr pointing to these syscalls so that they are force-resolved when libthr is loaded.

This revision is now accepted and ready to land.Wed, May 1, 2:58 PM