[Swan] SIGINT and xauth.c

D. Hugh Redelmeier hugh at mimosa.com
Mon Oct 7 17:40:35 EEST 2013


| From: D. Hugh Redelmeier <hugh at mimosa.com>

| | From: D. Hugh Redelmeier <hugh at mimosa.com>
| 
| | xauth.c has intricate sigal handling code.  I would like to understand its 
| | intent.
| | 
| | Where do these SIGINTs come from?
| 
| Nevermind.
| 
| I think they come when delete_state wants to terminate andy xauth thread 
| that is associated with the state being deleted.

(Remember that I'm ignorant about pthreads.)

According to signal(7):

        The signal disposition is a per-process attribute: in a
	multithreaded application, the disposition of a particular
	signal is the same for all threads.

As the code is now, we really want a per-thread setting for SIGINT
handling.

Also:

	A process-directed signal may be delivered to any one of the
	threads that does not currently have the signal blocked.  If
	more than one of the threads has the signal unblocked, then
	the kernel chooses an arbitrary thread to which to deliver the
	signal.

(state_deletion_xauth_cleanup's own SIGINT throwing is conveniently
targetted to a particular thread by using pthread_kill.)

What's the problem?  If there is an xauth thread (and hence a signal
disposition set for it), SIGINTs generated by something other than
state_deletion_xauth_cleanup will be mis-handled.  In particular, if
a sysadmin kills Pluto, the signal will be delivered to any one of the
threads that doesn't have it blocked.  This would be the main thread
or any of the xauth threads, or any other thread (eg. crypto threads).

First question: what should happen with SIGINTs.  It is unfortunate
that this has to be a global question when what we really want is a
private and effective way to send an interrupt between consenting
threads.

Currently the rest of Pluto doesn't care about SIGINTs.  So they will
terminate it.  I think that termination is such that the process (i.e.
all threads) will die, not just the thread that gets the signal.

If an exogenous SIGINT were delivered to an xauth thread, that thread
would act as if state_deletion_xauth_cleanup had signalled it, and
that is probably wrong.

If a SIGINT were delivered to another thread, but there was an xauth
thread running, the xauth signal handler would catch the signal.  As
it is currently written, that signal handler calls lsw_abort if it
doesn't find the thread in xauth.c's thread table.

If a SIGINT happened while no xauth thread was running, there would be
no signal handler and the result would be as expected: Pluto as a
whole would be terminated).  Is this correct?

This seems like a mess.  Luckily, the rest of Pluto doesn't explicitly
deal with or care about SIGINT.

Is there a way to interrupt a targetted thread that doesn't involve
hijacking a global resource like the SIGINT handler?  It sure would
help if signal dispositions were per thread.

Alternatively, is there a fool-proof (including race-proof) way that
the signal handler can tell a SIGINT generated by
state_deletion_xauth_cleanup from one that is not?  Maybe some global
flag needs to be set by state_deletion_xauth_cleanup (sounds slightly
racy).


More information about the Swan mailing list