exiwhat: Ensure the SIGUSR1 signal handler is safe.
authorTony Finch <dot@dotat.at>
Tue, 7 Jun 2011 15:48:44 +0000 (16:48 +0100)
committerTony Finch <dot@dotat.at>
Tue, 7 Jun 2011 19:03:58 +0000 (20:03 +0100)
commit921b12ca0c361b9c543368edf057712afa02ca14
treed0b0f60f1b784793f9574dafb687fe2f0c46768a
parent0ca0cf52fa9c635984937a3cc813d38fcdacd7ab
exiwhat: Ensure the SIGUSR1 signal handler is safe.

exiwhat sends a SIGUSR1 to all exim processes to make them write
their status to the process log. This is all done in the signal
handler, but the logging code makes a number of calls that are not
signal safe. These can all cause crashes or recursive locking in
libc.

Firstly, obtaining and formatting the timestamp is not safe.
Doing so is unnecessary since exiwhat strips off the timestamp.
This change removes timestamps from the process log.

Secondly, exim closes all the logs after writing the process
log. Closing syslog is not signal safe, and isn't necessary.
We now only close the process log after writing to it.

Thirdly, exim may calculate the process_log_path inside the signal
handler which involves some possibly-unsafe string handling code.
This change calculates the path when reading the configuration.

Fourthly, when exim creates the process log file it might have to
call the unsafe directory_create() though this is unlikely in
practice. After this change exim only calls log_create() in a
subprocess which is safe - it sometimes needs to do so anyway, if
it is running as root and needs to drop privileges.

The new code has no process log handling in log.c which eliminates
some awkward special cases. It uses very simple code to write to
the file in the signal handler, so it is obviously safe by inspection.
doc/doc-txt/ChangeLog
src/src/exim.c
src/src/exiwhat.src
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/log.c
src/src/macros.h
src/src/readconf.c