Commit 592af02f authored by Jeff Trawick's avatar Jeff Trawick
Browse files

merge this fix from trunk:


  Prevent hangs of child processes when writing to piped loggers at
  the time of graceful restart.  

PR:           26467
Reviewed by:  jorton, pquerna


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.0.x@202161 13f79535-47bb-0310-9956-ffa450edef68
parent 4fe4d550
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
Changes with Apache 2.0.55
  *) Prevent hangs of child processes when writing to piped loggers at
     the time of graceful restart.  PR 26467.  [Jeff Trawick]
  *) SECURITY: CAN-2005-1268 (cve.mitre.org)
     mod_ssl: Fix off-by-one overflow whilst printing CRL information
     at "LogLevel debug" which could be triggered if configured 
+14 −0
Original line number Diff line number Diff line
@@ -116,6 +116,20 @@ AP_DECLARE(apr_status_t) ap_replace_stderr_log(apr_pool_t *p,
int ap_open_logs(apr_pool_t *pconf, apr_pool_t *plog, 
                 apr_pool_t *ptemp, server_rec *s_main);

#ifdef CORE_PRIVATE

/**
 * Perform special processing for piped loggers in MPM child
 * processes.
 * @param p Not used
 * @param s Not used
 * @tip ap_logs_child_init is not for use by modules; it is an
 * internal core function
 */
void ap_logs_child_init(apr_pool_t *p, server_rec *s);

#endif /* CORE_PRIVATE */

/* 
 * The three primary logging functions, ap_log_error, ap_log_rerror, and 
 * ap_log_perror use a printf style format string to build the log message.  
+1 −0
Original line number Diff line number Diff line
@@ -4491,6 +4491,7 @@ static void register_hooks(apr_pool_t *p)
    ap_hook_translate_name(ap_core_translate,NULL,NULL,APR_HOOK_REALLY_LAST);
    ap_hook_map_to_storage(core_map_to_storage,NULL,NULL,APR_HOOK_REALLY_LAST);
    ap_hook_open_logs(ap_open_logs,NULL,NULL,APR_HOOK_REALLY_FIRST);
    ap_hook_child_init(ap_logs_child_init,NULL,NULL,APR_HOOK_MIDDLE);
    ap_hook_handler(default_handler,NULL,NULL,APR_HOOK_REALLY_LAST);
    /* FIXME: I suspect we can eliminate the need for these do_nothings - Ben */
    ap_hook_type_checker(do_nothing,NULL,NULL,APR_HOOK_REALLY_LAST);
+45 −0
Original line number Diff line number Diff line
@@ -145,6 +145,45 @@ static const TRANS priorities[] = {

static apr_file_t *stderr_log = NULL;

/* track pipe handles to close in child process */
typedef struct read_handle_t {
    struct read_handle_t *next;
    apr_file_t *handle;
} read_handle_t;

static read_handle_t *read_handles;

/* clear_handle_list() is called when plog is cleared; at that
 * point we need to forget about our old list of pipe read
 * handles
 */
static apr_status_t clear_handle_list(void *v)
{
    read_handles = NULL;
    return APR_SUCCESS;
}

/* remember to close this handle in the child process */
static void close_handle_in_child(apr_pool_t *p, apr_file_t *f)
{
    read_handle_t *new_handle;

    new_handle = apr_pcalloc(p, sizeof(read_handle_t));
    new_handle->next = read_handles;
    new_handle->handle = f;
    read_handles = new_handle;
}

void ap_logs_child_init(apr_pool_t *p, server_rec *s)
{
    read_handle_t *cur = read_handles;

    while (cur) {
        apr_file_close(cur->handle);
        cur = cur->next;
    }
}

AP_DECLARE(void) ap_open_stderr_log(apr_pool_t *p)
{
    apr_file_open_stderr(&stderr_log, p);
@@ -220,6 +259,9 @@ static int log_child(apr_pool_t *p, const char *progname,
        if (rc == APR_SUCCESS) {
            apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT);
            (*fpin) = procnew->in;
            /* read handle to pipe not kept open, so no need to call
             * close_handle_in_child()
             */
        }
    }

@@ -296,6 +338,8 @@ int ap_open_logs(apr_pool_t *pconf, apr_pool_t *p /* plog */,
    int replace_stderr;
    apr_file_t *errfile = NULL;

    apr_pool_cleanup_register(p, NULL, clear_handle_list,
                              apr_pool_cleanup_null);
    if (open_error_log(s_main, p) != OK) {
        return DONE;
    }
@@ -756,6 +800,7 @@ static int piped_log_spawn(piped_log *pl)
            ap_piped_log_write_fd(pl) = procnew->in;
            apr_proc_other_child_register(procnew, piped_log_maintenance, pl,
                                          ap_piped_log_write_fd(pl), pl->p);
            close_handle_in_child(pl->p, ap_piped_log_read_fd(pl));
        }
        else {
            char buf[120];