On Thu, May 02, 2019 at 03:34:22PM +0100, Robert Allen1 wrote:
> Hi,
>
> I spent some time digging into the FD leak and I've pinpointed it: it's an
> interaction between HAProxy re-exec and a change to keep the random
> devices open by default in OpenSSL 1.1.1 -- specifically
> https://github.com/openssl/openssl/commit/c7504aeb640a88949dfe3146f7e0f275f517464c
>
> Since a lot of different RAND_* family functions cause initialisation,
> that explains why hacking out ssl_initialize_random didn't work for us;
> some other part of reloading just ended up opening the random devices and
> then leaking the handles on the next exec().
>
> Anyway, from experimentation, we can close the leak with a patch like (but
> obviously better abstracted than) this one against 1.9.6:
>
> diff --git a/src/haproxy.c b/src/haproxy.c
> index 1cb10391..d3482f46 100644
> --- a/src/haproxy.c
> +++ b/src/haproxy.c
> @@ -737,6 +737,10 @@ void mworker_reload()
> ptdf->fct();
> if (fdtab)
> deinit_pollers();
> + /* Close OpenSSL random devices, if open */
> + /* Note: If not already initialised, this may cause OpenSSL
> rand_lib initialisation... */
> + void RAND_keep_random_devices_open(int keep);
> + RAND_keep_random_devices_open(0);
> /* restore the initial FD limits */
> limit.rlim_cur = rlim_fd_cur_at_boot;
>
> From reading in the OpenSSL code, I assume that the use of O_RDONLY
> without O_CLOEXEC or a fcntl is intentional so that it doesn't have to
> re-open the devices on fork().
>
> So it looks like the best place to solve this is around there ^^, although
> it needs to be wrapped up in ssl_sock.c with appropriate version guards on
> the OpenSSL version.
>
> Any thoughts on the above and how to proceed?
>
> Rob
>
Hi Robert,
I think that the right thing to do, we should probably just call
RAND_keep_random_devices_open(0); in the mworker_reload function.
You just need to check the SSL macros for the build and the minimum openssl
version (1.1.1), so probably something like this:
#if defined(USE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10101000L)
RAND_keep_random_devices_open(0);
#endif
I don't think we need anything in ssl_sock.c though.
Regards,
--
William Lallemand