Signal handling: what you can't do.

Werner Koch wk at gnupg.org
Mon Aug 30 18:20:22 CEST 1999


Hi Geoff,

First, many thanks for your review.  I still have some questions:

Geoff Keating <geoffk at ozemail.com.au> writes:

> static RETSIGTYPE
> got_fatal_signal( int sig )
> {
>     if( caught_fatal_sig )
>         raise( sig );
>     caught_fatal_sig = 1;
> 
>     fprintf( stderr, "\n%s: %s caught ... exiting\n",
>               log_get_name(), signal_name(sig) );
>     secmem_term();
>     exit( 8 );
> }
> 
> now, this is not good.  There are three issues here, but most flow
> from the same important rule:
> 
> In a signal handler, under Linux (and most other unixes), you cannot:
> 
> 1. Assume that the values in non-volatile variables are stored in the same
>    order as implied by the code (or in fact, that they are ever stored
>    at all);

But caught_fatal_sig is declared volatile; so where is the problem
here?

> 2. Call non-reentrant procedures.

I know that using printf is not good style but the only problem I can
see, is that the output is garbled or you get an SEGV.

I tried to use write(2) directly here but for some reasons
(portability?) I gave up on this.  I assume that the correct solution
would be to register an atexit function which displays such a message
if a fatal signal occured.

> Also for instance, in secmem_init, there is this code:
> 
>     else {
>         pool_is_mmapped = 1;
>         pool_okay = 1;
>     }
> 
> there is absolutely no guarantee that `pool_is_mmapped' is physically
> set to 1 before `pool_ok', or that `pool_ok' is set to 1 after the

Okay. I make pool_okay volatile.

> Finally, a minor nit:  in signal_name(), there is this:
> 
>   #if SYS_SIGLIST_DECLARED
>     return sys_siglist[signum];
>   #else
>     static char buf[20];
>     sprintf(buf, "signal %d", signum );
>     return buf;
>   #endif
> 
> it should check that `signum' is less than NSIG, or better yet it
> should use strsignal() which does the check for you and will still

Which is not available on BSD systems

> Again on my system this won't happen because NSIG is greater than the
> signal number of all the signals for which signal_name is actually
> called; but it's not robust code.

Okay, add a bounds check.


-- 
Werner Koch at guug.de           www.gnupg.org           keyid 621CC013



More information about the Gnupg-devel mailing list