]> git.ipfire.org Git - thirdparty/haproxy.git/commit
BUG/MEDIUM: poller: use fd_delete() to release the poller pipes
authorWilly Tarreau <w@1wt.eu>
Wed, 10 Aug 2022 15:08:17 +0000 (17:08 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 10 Aug 2022 15:25:23 +0000 (17:25 +0200)
commite6ca435c04a344e2a48b11a64b4faf16c9a3b024
treeb7866e89af5290ef9c263d0e0b978e667c82b760
parent54bc78693d8153f10ec4268bfad8779b08740bc2
BUG/MEDIUM: poller: use fd_delete() to release the poller pipes

The poller pipes needed to communicate between multiple threads are
allocated in init_pollers_per_thread() and released in
deinit_pollers_per_thread(). The former adds them via fd_insert()
so that they are known, but the former only closes them using a
regular close().

This asymmetry represents a problem, because we have in the fdtab[]
an entry for something that may disappear when one thread leaves, and
since these FD numbers are very low, there is a very high likelihood
that they are immediately reassigned to another thread trying to
connect() to a server or just sending a health check. In this case,
the other thread is going to fd_insert() the fd and the recently
added consistency checks will notive that ->owner is not NULL and
will crash. We just need to use fd_delete() here to match fd_insert().

Note that this test was added in 2.7-dev2 by commit 36d9097cf
("MINOR: fd: Add BUG_ON checks on fd_insert()") which was backported
to 2.4 as a safety measure (since it allowed to catch particularly
serious issues). The patch in itself isn't wrong, it just revealed
a long-dormant bug (been there since 1.9-dev1, 4 years ago). As such
the current patch needs to be backported wherever the commit above
is backported.

Many thanks to Christian Ruppert for providing detailed traces in
github issue #1807 and Cedric Paillet for bringing his complementary
analysis that helped to understand the required conditions for this
issue to happen (fast health checks @100ms + randomly long connections
~7s + fast reloads every second + hard-stop-after 5s were necessary
on the dev's machine to trigger it from time to time).
src/fd.c