Commit 3db43ac3 authored by Nick Kew's avatar Nick Kew
Browse files

mod_cgid: backport fix for segfault on (older) Solaris.

r729579, r731963, r731965
PR 39332


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@732067 13f79535-47bb-0310-9956-ffa450edef68
parent 02e7d023
Loading
Loading
Loading
Loading
+3 −0
Changes for CHANGES: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.2.12

  *) mod_cgid: fix segfault problem on solaris.
     PR 39332 [Masaoki Kobayashi <masaoki techfirm.co.jp>, Jeff Trawick]

  *) mod_ldap: Avoid a segfault when result->rc is checked in uldap_connection_init
     when result is NULL. This could happen if LDAP initialization failed.
     PR 45994.  [Dan Poirier <poirier pobox.com>]
+0 −8
Changes for STATUS: 0 added lines, 8 removed lines.
Original line number Diff line number Diff line
@@ -110,14 +110,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK:
    http://svn.apache.org/viewvc?view=rev&revision=730274
    +1: niq, rpluem

  * mod_cgid: fix for segfault problem on solaris
    PR 39332
    http://svn.apache.org/viewvc?view=rev&revision=729579
    +1: niq, rpluem
    +1 with r731963 + r731965: trawick
       (http://svn.apache.org/viewvc?view=rev&revision=731963,
        http://svn.apache.org/viewvc?view=rev&revision=731965)

  * util_script (CGI): return 504 (Gateway timeout) rather than 500
    when a script times out before returning status line/headers.
    PR 42190
+43 −16
Changes for modules/generators/mod_cgid.c: 43 added lines, 16 removed lines.
Original line number Diff line number Diff line
@@ -344,6 +344,33 @@ static apr_status_t sock_write(int fd, const void *buf, size_t buf_size)
    return APR_SUCCESS;
}

static apr_status_t sock_writev(int fd, request_rec *r, int count, ...)
{
    va_list ap;
    int rc;
    struct iovec *vec;
    int i;
    int total_bytes = 0;

    vec = (struct iovec *)apr_palloc(r->pool, count * sizeof(struct iovec));
    va_start(ap, count);
    for(i = 0; i < count; i++) {
        vec[i].iov_base = va_arg(ap, caddr_t);
        vec[i].iov_len  = va_arg(ap, apr_size_t);
        total_bytes += vec[i].iov_len;
    }
    va_end(ap);

    do {
        rc = writev(fd, vec, count);
    } while (rc < 0 && errno == EINTR);
    if (rc < 0) {
        return errno;
    }

    return APR_SUCCESS;
}

static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env,
                            cgid_req_t *req)
{
@@ -472,31 +499,31 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env,
    req.loglevel = r->server->loglevel;

    /* Write the request header */
    if ((stat = sock_write(fd, &req, sizeof(req))) != APR_SUCCESS) {
        return stat;
    if (req.args_len) {
        stat = sock_writev(fd, r, 5,
                           &req, sizeof(req),
                           r->filename, req.filename_len,
                           argv0, req.argv0_len,
                           r->uri, req.uri_len,
                           r->args, req.args_len);
    } else {
        stat = sock_writev(fd, r, 4,
                           &req, sizeof(req),
                           r->filename, req.filename_len,
                           argv0, req.argv0_len,
                           r->uri, req.uri_len);
    }

    /* Write filename, argv0, uri, and args */
    if ((stat = sock_write(fd, r->filename, req.filename_len)) != APR_SUCCESS ||
        (stat = sock_write(fd, argv0, req.argv0_len)) != APR_SUCCESS ||
        (stat = sock_write(fd, r->uri, req.uri_len)) != APR_SUCCESS) {
        return stat;
    }
    if (req.args_len) {
        if ((stat = sock_write(fd, r->args, req.args_len)) != APR_SUCCESS) {
    if (stat != APR_SUCCESS) {
        return stat;
    }
    }

    /* write the environment variables */
    for (i = 0; i < req.env_count; i++) {
        apr_size_t curlen = strlen(env[i]);

        if ((stat = sock_write(fd, &curlen, sizeof(curlen))) != APR_SUCCESS) {
            return stat;
        }

        if ((stat = sock_write(fd, env[i], curlen)) != APR_SUCCESS) {
        if ((stat = sock_writev(fd, r, 2, &curlen, sizeof(curlen),
                                env[i], curlen)) != APR_SUCCESS) {
            return stat;
        }
    }