Joe Orton wrote: > On Sat, May 24, 2014 at 10:32:35AM +0200, Kaspar Brand wrote: >> On 19.05.2014 10:15, Plüm, Rüdiger, Vodafone Group wrote: >>> Maybe stupid idea, but can't we do that once and hand it out over >>> and over again? >> >> Not a stupid idea at all - I think it's actually the most sensible >> solution to this problem. This is what OpenSSL does with the >> DH parameters provided by the callback in >> s3_srvr.c:ssl3_send_server_key_exchange(): > > This may be a stupid question: if we are doing this once per process > lifetime would it not be better to do it at init time, and store the > results somewhere other than a static variable? > > We have a potential race here between threads doing the param > generation, right? > > + static DH *dh = NULL; \ > + DH *dh_tmp; \ > ... > + dh = dh_tmp; \ > > though it would not matter who wins the race *if* we could rely on > pointer assignment being atomic - which is a fairly dubious assumption,
That was my assumption. If we cannot assume that the pointer assignment is atomic, then we have a race problem. Would the following patch address your concern? Index: modules/ssl/ssl_engine_kernel.c =================================================================== --- modules/ssl/ssl_engine_kernel.c (revision 1597665) +++ modules/ssl/ssl_engine_kernel.c (working copy) @@ -31,6 +31,7 @@ #include "ssl_private.h" #include "mod_ssl.h" #include "util_md5.h" +#include "apr_atomic.h" static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); #ifdef HAVE_TLSEXT @@ -1320,6 +1321,10 @@ * contrast to the keys itself) and code safe as the returned structure * is duplicated by OpenSSL anyway. Hence no modification happens * to our copy. + * + * Use apr_atomic_xchgptr to assign the result to dh as we might have + * multiple threads calling us in parallel and pointer assignment might + * not be atomic. */ #define make_get_dh(rfc,size,gen) \ static DH *get_dh##size(void) \ @@ -1339,7 +1344,7 @@ DH_free(dh_tmp); \ return NULL; \ } \ - dh = dh_tmp; \ + apr_atomic_xchgptr((volatile void **)&dh, dh_tmp); \ return dh; \ } > and at least deserves a comment. If a potential race is possible here > it might be better to do it once at startup to save CPU time anyway? I am not that worried about CPU because I guess we fairly quickly get dh set to a valid value and afterwards stuff is fast, but for sure this would be another option. Regards Rüdiger