Skip to content

v0.40.3

@msantos msantos tagged this 29 Jul 12:48
Crash the alcove process immediately on pipe overflow errors:

* alcove processes could become unresponsive while dealing with queued
  events in a signal flood

* write(2) errors could cause a SIGSEGV which was also caught by the
  signal handler

For background, see:

https://github.com/msantos/stdio/commit/ef498b541fbfb9569172dd0f2d7b56104bcab2ac

https://codeberg.org/msantos/stdio/commit/ef498b541fbfb9569172dd0f2d7b56104bcab2ac

To debug the alcove process, SIGPIPE was ignored and the signal handler
was modified to raise SIGSTOP on receipt of a SIGSEGV. Attaching with gdb,
the backtrace showed the SIGSEGV signal was generated when:

* write_to_pid(): write to pipe fails with EAGAIN
* attempt to write alcove_pipe message to stdout returns failure
* process calls abort()
* signal handler is called with SIGSEGV

If SIGABRT has a registered signal handler, abort(3) calls the handler
and, on return, restores the default signal handler and resends the
signal.

From the backtrace, it seems the signal handler is being called
recursively until the stack space is exhausted and SIGSEGV is generated.

Fix by replacing use of abort(3) with _exit(3)/exit(3). The idea behind
using abort(3) was to differentiate unexpected behaviour from the return
of a call.

When the signal pipe buffer is full, crash immediately by calling
_exit(3): normally close(2)'ing the write end of the pipe will cause the
program to call exit(3) when performing a read on the read end of the
signal pipe. Since a large number of signals are buffered in the pipe,
it may take some time for an error to be returned: in the interim,
the signal handler is being called repeatedly.

Alternatives are:

* drop the signals and crash

  * deregister the signal handler in the signal handler
  * wait for the read end of the signal handler to process queued signals
  * exit

* drop the signals and continue

  As above but do not close the file descriptor or exit(): when the fd
  is writable, reset the signal handlers. The signal handlers would need
  to be stored in the process state.
Assets 2