Re: svn commit: r1833525 - in /apr/apr/trunk: crypto/apr_crypto.c crypto/apr_crypto_internal.c test/testcrypto.c util-misc/apu_dso.c

2019-08-23 Thread Graham Leggett
On 23 Aug 2019, at 14:34, Eric Covener  wrote:

> I have a question in this area, not necessarily a result of this commit.
> 
> I have been playing with a new crypto provider, in a non-DSO build,
> intended to be used with httpd.
> 
> The provider does have both an initialization and termination API.
> 
> My issue is a result of the "rootp" being used for the driver hashmap
> but "pconf" (in the httpd/mod_session_crypto case) being passed to the
> drivers init() function the first time it's loaded.  This means at
> graceful restart, cleanups registered by the drivers init() function
> will run, but apr_crypto_term will not, and the next call to get the
> driver will not re-run the init().
> 
> Making the lifetimes match either way fixes my test -- either moving
> the "rootp" stuff to DSO-only for apr_crypto_init or by passing
> "rootp" to the DRIVER_LOAD macro for non-DSO init.
> 
> Any opinions?

Pool lifetime issues have been fixed in the apu_dso_init() function, most 
specifically you can now run the init, then clean up the pool, then run init a 
second time, then clean up the pool the second time, and this will work. 
Previously init could only ever be called once, but practically it was being 
called over and over again by every httpd module that touches DSO (sql, etc).

This fix isn’t enough - the same pool lifetime bug exists in apu_dso_load(), 
and each DSO’s init function. The fix that will work is implement the same 
strategy for pool cleanup implemented in apu_dso_init() everywhere else, but 
this means lots of repetition.

I have wanted to implement a generic solution to this, but have not had time to 
figure that out.

Regards,
Graham
—



smime.p7s
Description: S/MIME cryptographic signature


Re: svn commit: r1833525 - in /apr/apr/trunk: crypto/apr_crypto.c crypto/apr_crypto_internal.c test/testcrypto.c util-misc/apu_dso.c

2019-08-23 Thread Eric Covener
I have a question in this area, not necessarily a result of this commit.

I have been playing with a new crypto provider, in a non-DSO build,
intended to be used with httpd.

The provider does have both an initialization and termination API.

My issue is a result of the "rootp" being used for the driver hashmap
but "pconf" (in the httpd/mod_session_crypto case) being passed to the
drivers init() function the first time it's loaded.  This means at
graceful restart, cleanups registered by the drivers init() function
will run, but apr_crypto_term will not, and the next call to get the
driver will not re-run the init().

Making the lifetimes match either way fixes my test -- either moving
the "rootp" stuff to DSO-only for apr_crypto_init or by passing
"rootp" to the DRIVER_LOAD macro for non-DSO init.

Any opinions?

On Thu, Jun 14, 2018 at 12:34 PM  wrote:
>
> Author: ylavic
> Date: Thu Jun 14 16:34:49 2018
> New Revision: 1833525
>
> URL: http://svn.apache.org/viewvc?rev=1833525=rev
> Log:
> apr_crypto: follow up to r1833359: fix some root pool scopes (possible leaks).
>
> Keep the root pool scope for things that need it only (global lists of drivers
> or libs), but otherwise use the passed in pool (default/global PRNG, errors).
>
> This allows the caller to control the scope of initialization functions, and
> for instance be able to re-initialize when apr_crypto is unloaded/reloaded 
> from
> a DSO attached to the passed-in pool (e.g. mod_ssl in httpd).
>
>
> Modified:
> apr/apr/trunk/crypto/apr_crypto.c
> apr/apr/trunk/crypto/apr_crypto_internal.c
> apr/apr/trunk/test/testcrypto.c
> apr/apr/trunk/util-misc/apu_dso.c
>
> Modified: apr/apr/trunk/crypto/apr_crypto.c
> URL: 
> http://svn.apache.org/viewvc/apr/apr/trunk/crypto/apr_crypto.c?rev=1833525=1833524=1833525=diff
> ==
> --- apr/apr/trunk/crypto/apr_crypto.c (original)
> +++ apr/apr/trunk/crypto/apr_crypto.c Thu Jun 14 16:34:49 2018
> @@ -37,8 +37,6 @@ static apr_hash_t *drivers = NULL;
>
>  #define ERROR_SIZE 1024
>
> -#define CLEANUP_CAST (apr_status_t (*)(void*))
> -
>  APR_TYPEDEF_STRUCT(apr_crypto_t,
>  apr_pool_t *pool;
>  apr_crypto_driver_t *provider;
> @@ -87,26 +85,29 @@ static apr_status_t apr_crypto_term(void
>  APR_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool)
>  {
>  apr_status_t rv;
> -apr_pool_t *parent;
> +apr_pool_t *rootp;
>  int flags = 0;
>
>  if (drivers != NULL) {
>  return APR_SUCCESS;
>  }
>
> -/* Top level pool scope, need process-scope lifetime */
> -for (parent = apr_pool_parent_get(pool);
> - parent && parent != pool;
> - parent = apr_pool_parent_get(pool))
> -pool = parent;
> +/* Top level pool scope, for drivers' process-scope lifetime */
> +rootp = pool;
> +for (;;) {
> +apr_pool_t *p = apr_pool_parent_get(rootp);
> +if (!p || p == rootp) {
> +break;
> +}
> +rootp = p;
> +}
>  #if APR_HAVE_MODULAR_DSO
>  /* deprecate in 2.0 - permit implicit initialization */
> -apu_dso_init(pool);
> +apu_dso_init(rootp);
>  #endif
> -drivers = apr_hash_make(pool);
> -
> -apr_pool_cleanup_register(pool, NULL, apr_crypto_term,
> -apr_pool_cleanup_null);
> +drivers = apr_hash_make(rootp);
> +apr_pool_cleanup_register(rootp, NULL, apr_crypto_term,
> +  apr_pool_cleanup_null);
>
>  /* apr_crypto_prng_init() may already have been called with
>   * non-default parameters, so ignore APR_EREINIT.
> @@ -203,6 +204,7 @@ APR_DECLARE(apr_status_t) apr_crypto_get
>  char symname[34];
>  apr_dso_handle_t *dso;
>  apr_dso_handle_sym_t symbol;
> +apr_pool_t *rootp;
>  #endif
>  apr_status_t rv;
>
> @@ -227,7 +229,7 @@ APR_DECLARE(apr_status_t) apr_crypto_get
>  #if APR_HAVE_MODULAR_DSO
>  /* The driver DSO must have exactly the same lifetime as the
>   * drivers hash table; ignore the passed-in pool */
> -pool = apr_hash_pool_get(drivers);
> +rootp = apr_hash_pool_get(drivers);
>
>  #if defined(NETWARE)
>  apr_snprintf(modname, sizeof(modname), "crypto%s.nlm", name);
> @@ -239,21 +241,19 @@ APR_DECLARE(apr_status_t) apr_crypto_get
>  "apr_crypto_%s-" APR_STRINGIFY(APR_MAJOR_VERSION) ".so", name);
>  #endif
>  apr_snprintf(symname, sizeof(symname), "apr_crypto_%s_driver", name);
> -rv = apu_dso_load(, , modname, symname, pool);
> +rv = apu_dso_load(, , modname, symname, rootp);
>  if (rv == APR_SUCCESS || rv == APR_EINIT) { /* previously loaded?!? */
>  apr_crypto_driver_t *d = symbol;
>  rv = APR_SUCCESS;
>  if (d->init) {
> -rv = d->init(pool, params, result);
> +rv = d->init(rootp, params, result);
>  if (rv == APR_EREINIT) {
>  rv = APR_SUCCESS;
>  }
>  }
>  if (rv ==