Since 3.2 and commit
8f70f9c04 ("MEDIUM: mux_fcgi: Make sure we return
the tasklet from fcgi_deferred_shut"), fcgi_deferred_shut() returns its
tasklet to the scheduler. But when the deferred shutdown concerns an
orphaned stream, fcgi_strm_destroy() is called, which frees the stream's
shut_tl tasklet, which is precisely the one being run. The scheduler then
clears TASK_RUNNING in the freed tasklet's state, which is a
use-after-free write (and the connection may even have been released).
This is the same issue as the one fixed in mux-h2 by commit "BUG/MEDIUM:
mux-h2: don't return a freed tasklet from h2_deferred_shut()", where it
was reproduced with -dMuaf. Here it's only based on code analysis. It
requires that the FCGI_ABORT or the end of stream record could not be
sent when the stream was shut because the mux buffer was full, and that
the stream detaches before the deferred shutdown is performed, so it's
rare and only the FCGI server side (trusted) is involved.
The fix simply consists in returning NULL once the stream was destroyed.
It must be backported to 3.2.