Uploaded image for project: 'mod_python'
  1. mod_python
  2. MODPYTHON-75

Crash and memory leak in python_merge_config due to use of apr_table_overlap

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.1.3, 3.1.4
    • 3.2.7
    • core
    • None
    • all

    Description

      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
      */

      Attachments

        Activity

          People

            jgallacher James Paul Gallacher
            bb Boyan Boyadjiev
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: