Apollon Oikonomopoulos
2016-Nov-13 18:04 UTC
[PATCH] Manually cleanup OpenSSL from dovecot_openssl_common_global_unref()
OpenSSL 1.1 features a cleanup function that is automatically run on shutdown using atexit(3). This function frees all OpenSSL-allocated resources. In dovecot, OpenSSL is loaded indirectly using dlopen(3) against the relevant dovecot crypto module and is finally unloaded using dlclose(3). Until OpenSSL 1.0.1c this worked fine, however OpenSSL 1.0.1c makes sure[1] that the library stays loaded after the initial dlclose() so that the atexit(3) handlers can run on shutdown. This, together with the fact that dovecot uses custom allocation functions for OpenSSL and has already partially free()'d some of OpenSSL's resources in module_free(), leads to a segfault at process shutdown[2]. We fix this by explicitly calling OPENSSL_cleanup() during module unload. This is safe to do, as long as we will never want to subsequently re-initialize OpenSSL. [1] https://github.com/openssl/openssl/commit/4af9f7fe79ff82b90c16969b7e5871435056377b [2] https://buildd.debian.org/status/fetch.php?pkg=dovecot&arch=amd64&ver=1:2.2.26.0-2&stamp=1478873022 Signed-off-by: Apollon Oikonomopoulos <apoikos at debian.org> --- src/lib-ssl-iostream/dovecot-openssl-common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib-ssl-iostream/dovecot-openssl-common.c b/src/lib-ssl-iostream/dovecot-openssl-common.c index 51ea3ad..2bf6307 100644 --- a/src/lib-ssl-iostream/dovecot-openssl-common.c +++ b/src/lib-ssl-iostream/dovecot-openssl-common.c @@ -101,6 +101,9 @@ bool dovecot_openssl_common_global_unref(void) ERR_remove_thread_state(NULL); #endif ERR_free_strings(); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + OPENSSL_cleanup(); +#endif return FALSE; } -- 2.10.1
A. Schulze
2016-Nov-14 23:00 UTC
[PATCH] Manually cleanup OpenSSL from dovecot_openssl_common_global_unref()
Am 13.11.2016 um 19:04 schrieb Apollon Oikonomopoulos:> OpenSSL 1.1 features a cleanup function that is automatically run on shutdown > using atexit(3). This function frees all OpenSSL-allocated resources. > > In dovecot, OpenSSL is loaded indirectly using dlopen(3) against the relevant > dovecot crypto module and is finally unloaded using dlclose(3). Until > OpenSSL 1.0.1c this worked fine, however OpenSSL 1.0.1c makes sure[1] that the > library stays loaded after the initial dlclose() so that the atexit(3) > handlers can run on shutdown. This, together with the fact that dovecot > uses custom allocation functions for OpenSSL and has already partially > free()'d some of OpenSSL's resources in module_free(), leads to a > segfault at process shutdown[2]. > > We fix this by explicitly calling OPENSSL_cleanup() during module unload. This > is safe to do, as long as we will never want to subsequently re-initialize > OpenSSL. > > [1] https://github.com/openssl/openssl/commit/4af9f7fe79ff82b90c16969b7e5871435056377b > [2] https://buildd.debian.org/status/fetch.php?pkg=dovecot&arch=amd64&ver=1:2.2.26.0-2&stamp=1478873022 > > Signed-off-by: Apollon Oikonomopoulos <apoikos at debian.org> > --- > src/lib-ssl-iostream/dovecot-openssl-common.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/src/lib-ssl-iostream/dovecot-openssl-common.c b/src/lib-ssl-iostream/dovecot-openssl-common.c > index 51ea3ad..2bf6307 100644 > --- a/src/lib-ssl-iostream/dovecot-openssl-common.c > +++ b/src/lib-ssl-iostream/dovecot-openssl-common.c > @@ -101,6 +101,9 @@ bool dovecot_openssl_common_global_unref(void) > ERR_remove_thread_state(NULL); > #endif > ERR_free_strings(); > +#if OPENSSL_VERSION_NUMBER >= 0x10100000L > + OPENSSL_cleanup(); > +#endif > return FALSE; > } >I could at least confirm the observation (segfault on build) and the fix solve it as promised. Andreas
Aki Tuomi
2016-Nov-15 11:46 UTC
[PATCH] Manually cleanup OpenSSL from dovecot_openssl_common_global_unref()
On 13.11.2016 20:04, Apollon Oikonomopoulos wrote:> OpenSSL 1.1 features a cleanup function that is automatically run on shutdown > using atexit(3). This function frees all OpenSSL-allocated resources. > > In dovecot, OpenSSL is loaded indirectly using dlopen(3) against the relevant > dovecot crypto module and is finally unloaded using dlclose(3). Until > OpenSSL 1.0.1c this worked fine, however OpenSSL 1.0.1c makes sure[1] that the > library stays loaded after the initial dlclose() so that the atexit(3) > handlers can run on shutdown. This, together with the fact that dovecot > uses custom allocation functions for OpenSSL and has already partially > free()'d some of OpenSSL's resources in module_free(), leads to a > segfault at process shutdown[2]. > > We fix this by explicitly calling OPENSSL_cleanup() during module unload. This > is safe to do, as long as we will never want to subsequently re-initialize > OpenSSL. > > [1] https://github.com/openssl/openssl/commit/4af9f7fe79ff82b90c16969b7e5871435056377b > [2] https://buildd.debian.org/status/fetch.php?pkg=dovecot&arch=amd64&ver=1:2.2.26.0-2&stamp=1478873022 > > Signed-off-by: Apollon Oikonomopoulos <apoikos at debian.org> > --- > src/lib-ssl-iostream/dovecot-openssl-common.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/src/lib-ssl-iostream/dovecot-openssl-common.c b/src/lib-ssl-iostream/dovecot-openssl-common.c > index 51ea3ad..2bf6307 100644 > --- a/src/lib-ssl-iostream/dovecot-openssl-common.c > +++ b/src/lib-ssl-iostream/dovecot-openssl-common.c > @@ -101,6 +101,9 @@ bool dovecot_openssl_common_global_unref(void) > ERR_remove_thread_state(NULL); > #endif > ERR_free_strings(); > +#if OPENSSL_VERSION_NUMBER >= 0x10100000L > + OPENSSL_cleanup(); > +#endif > return FALSE; > } >Hi! Your patch is being reviewed. Aki
Reuben Farrelly
2016-Nov-20 11:59 UTC
[PATCH] Manually cleanup OpenSSL from dovecot_openssl_common_global_unref()
Hi, This patch: On 15/11/2016 10:46 PM, Aki Tuomi wrote:> > > On 13.11.2016 20:04, Apollon Oikonomopoulos wrote: >> OpenSSL 1.1 features a cleanup function that is automatically run on shutdown >> using atexit(3). This function frees all OpenSSL-allocated resources. >> >> In dovecot, OpenSSL is loaded indirectly using dlopen(3) against the relevant >> dovecot crypto module and is finally unloaded using dlclose(3). Until >> OpenSSL 1.0.1c this worked fine, however OpenSSL 1.0.1c makes sure[1] that the >> library stays loaded after the initial dlclose() so that the atexit(3) >> handlers can run on shutdown. This, together with the fact that dovecot >> uses custom allocation functions for OpenSSL and has already partially >> free()'d some of OpenSSL's resources in module_free(), leads to a >> segfault at process shutdown[2]. >> >> We fix this by explicitly calling OPENSSL_cleanup() during module unload. This >> is safe to do, as long as we will never want to subsequently re-initialize >> OpenSSL. >> >> [1] https://github.com/openssl/openssl/commit/4af9f7fe79ff82b90c16969b7e5871435056377b >> [2] https://buildd.debian.org/status/fetch.php?pkg=dovecot&arch=amd64&ver=1:2.2.26.0-2&stamp=1478873022 >> >> Signed-off-by: Apollon Oikonomopoulos <apoikos at debian.org> >> --- >> src/lib-ssl-iostream/dovecot-openssl-common.c | 3 +++ >> 1 file changed, 3 insertions(+) >> >> diff --git a/src/lib-ssl-iostream/dovecot-openssl-common.c b/src/lib-ssl-iostream/dovecot-openssl-common.c >> index 51ea3ad..2bf6307 100644 >> --- a/src/lib-ssl-iostream/dovecot-openssl-common.c >> +++ b/src/lib-ssl-iostream/dovecot-openssl-common.c >> @@ -101,6 +101,9 @@ bool dovecot_openssl_common_global_unref(void) >> ERR_remove_thread_state(NULL); >> #endif >> ERR_free_strings(); >> +#if OPENSSL_VERSION_NUMBER >= 0x10100000L >> + OPENSSL_cleanup(); >> +#endif >> return FALSE; >> } >> > > Hi! > > Your patch is being reviewed. > > Aki... which was committed as c164f8afe58c8d83ef2a48aae629c72408dfea01 in master-2.2, terminally breaks the build with LibreSSL. Obviously this wasn't tested or considered ;) *** Warning: Linking the executable test-http-client against the loadable module *** libssl_iostream_openssl.so is not portable! libtool: link: x86_64-pc-linux-gnu-gcc -std=gnu99 -O0 -g -pipe -march=native -mtune=native -Wall -W -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wchar-subscripts -Wformat=2 -Wbad-function-cast -fno-builtin-strftime -Wstrict-aliasing=2 -Wl,-O1 -o .libs/test-http-client test-http-client.o -Wl,--export-dynamic -Wl,--as-needed ./.libs/libhttp.a ../lib-dns/.libs/libdns.a ../lib-ssl-iostream/.libs/libssl_iostream.a ../lib-master/.libs/libmaster.a ../lib-settings/.libs/libsettings.a ../lib-test/.libs/libtest.a ../lib/.libs/liblib.a -ldl ../lib-ssl-iostream/.libs/libssl_iostream_openssl.so -lssl -lcrypto -Wl,-rpath -Wl,/usr/lib64/dovecot ../lib-ssl-iostream/.libs/libssl_iostream_openssl.so: undefined reference to `OPENSSL_cleanup' collect2: error: ld returned 1 exit status make[3]: *** [Makefile:737: test-http-client] Error 1 make[3]: *** Waiting for unfinished jobs.... libtool: link: x86_64-pc-linux-gnu-gcc -std=gnu99 -O0 -g -pipe -march=native -mtune=native -Wall -W -Wmissing-prototypes -Wmissing-declarations -Wpointer-arith -Wchar-subscripts -Wformat=2 -Wbad-function-cast -fno-builtin-strftime -Wstrict-aliasing=2 -Wl,-O1 -o test-http-client-errors test-http-client-errors.o -Wl,--export-dynamic -Wl,--as-needed ./.libs/libhttp.a ../lib-dns/.libs/libdns.a ../lib-ssl-iostream/.libs/libssl_iostream.a ../lib-master/.libs/libmaster.a ../lib-settings/.libs/libsettings.a ../lib-test/.libs/libtest.a ../lib/.libs/liblib.a -ldl make[3]: Leaving directory '/var/tmp/portage/net-mail/dovecot-2.2.26_p20161120/work/dovecot-2.2.26_p20161120/src/lib-http' make[2]: *** [Makefile:493: all-recursive] Error 1 make[2]: Leaving directory '/var/tmp/portage/net-mail/dovecot-2.2.26_p20161120/work/dovecot-2.2.26_p20161120/src' make[1]: *** [Makefile:618: all-recursive] Error 1 make[1]: Leaving directory '/var/tmp/portage/net-mail/dovecot-2.2.26_p20161120/work/dovecot-2.2.26_p20161120' make: *** [Makefile:462: all] Error 2 * ERROR: net-mail/dovecot-2.2.26_p20161120::reub-Local-Overlay failed (compile phase): * emake failed * I am running LibreSSL-2.5.0, so I guess it may not be a supported function yet. Reuben
Apparently Analagous Threads
- [PATCH] Manually cleanup OpenSSL from dovecot_openssl_common_global_unref()
- [PATCH] Manually cleanup OpenSSL from dovecot_openssl_common_global_unref()
- a bit further along - OpenSSL - Re: trouble compiling Dovecot 2.2.31 on Solaris 10 SPARC - libssl_iostream_openssl.so is not portable!
- 2.2.30.2 fails to compile on centos 7
- 2.2.30.2 fails to compile on centos 7