You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-dev@quetz.apache.org by "Nicolas Lehuen (JIRA)" <ji...@apache.org> on 2005/09/16 18:27:54 UTC

[jira] Updated: (MODPYTHON-75) Crash and memory leak in python_merge_config due to use of apr_table_overlap

     [ http://issues.apache.org/jira/browse/MODPYTHON-75?page=all ]

Nicolas Lehuen updated MODPYTHON-75:
------------------------------------

    Fix Version:     (was: 3.3.0)

> Crash and memory leak in  python_merge_config due to use of apr_table_overlap
> -----------------------------------------------------------------------------
>
>          Key: MODPYTHON-75
>          URL: http://issues.apache.org/jira/browse/MODPYTHON-75
>      Project: mod_python
>         Type: Bug
>   Components: core
>     Versions: 3.1.4, 3.1.3
>  Environment: all
>     Reporter: Boyan Boyadjiev
>     Assignee: Jim Gallacher
>      Fix For: 3.2.0

>
> Couse:
> Usage of apr_table_overlap() function in the python_merge_config() and the way of handling the pools for resource allocation there. In general using this function in python_merge_config() mismatches the pool designated for global configuration items and the one that has to be used for request local data. By using a global pool for local data two request may collide when accessing this one which leads to the crash.
> The solution which works fine for us is to implement and use a custom_table_overlap function, which does apr_table_overlay and then  apr_table_compress (similar aproach as in mod_perl):
> /*
> code begin
> */
> /**
>  ** modpython_table_overlap
>  **
>  *      Replaces the apr_table_overlap() function using a specific pool
>  *      for the resulting table.
>  */
> static apr_table_t *modpython_table_overlap(apr_pool_t *p,
>                                             apr_table_t *current_table,
>                                             apr_table_t *new_table)
> {
>     apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
>     apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
>     return merge;
> }
> /**
>  ** python_merge_dir_config
>  **
>  */
> static void *python_merge_config(apr_pool_t *p, void *current_conf,
>                                  void *new_conf)
> {
>     py_config *merged_conf =
>         (py_config *) apr_pcalloc(p, sizeof(py_config));
>     py_config *cc = (py_config *) current_conf;
>     py_config *nc = (py_config *) new_conf;
>     apr_hash_index_t *hi;
>     char *key;
>     apr_ssize_t klen;
>     hl_entry *hle;
>     /* we basically allow the local configuration to override global,
>      * by first copying current values and then new values on top
>      */
>     /** create **/
>     merged_conf->hlists = apr_hash_make(p);
>     merged_conf->in_filters = apr_hash_make(p);
>     merged_conf->out_filters = apr_hash_make(p);
>     /** merge directives and options **/
>     merged_conf->directives = modpython_table_overlap(p, cc->directives,
>                                                          nc->directives);
>     merged_conf->options = modpython_table_overlap(p, cc->options,
>                                                       nc->options);
>     /** copy current **/
>     merged_conf->authoritative = cc->authoritative;
>     merged_conf->config_dir = apr_pstrdup(p, cc->config_dir);
>     for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
>         apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
>         apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
>     }
>     for (hi = apr_hash_first(p, cc->in_filters); hi; hi=apr_hash_next(hi)) {
>         apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
>         apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
>     }
>     for (hi = apr_hash_first(p, cc->out_filters); hi; hi=apr_hash_next(hi)) {
>         apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
>         apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
>     }
>     /** copy new **/
>     if (nc->authoritative != merged_conf->authoritative)
>         merged_conf->authoritative = nc->authoritative;
>     if (nc->config_dir)
>         merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
>     for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
>         apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
>         apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
>     }
>     for (hi = apr_hash_first(p, nc->in_filters); hi; hi=apr_hash_next(hi)) {
>         apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
>         apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
>     }
>     for (hi = apr_hash_first(p, nc->out_filters); hi; hi=apr_hash_next(hi)) {
>         apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
>         apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
>     }
>     return (void *) merged_conf;
> }
> /*
> code end
> */

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira